Основные сущности Kubernetes

Обновлено и опубликовано Опубликовано:

Используемые термины: Kubernetes.

В этой статье рассмотрим основные объекты Kubernetes и разберём, как их создают через kubectl. Для самых важных приведём короткие примеры команд.

Рабочие нагрузки

Pod — минимальная единица развертывания в Kubernetes: один или несколько контейнеров на одном node с общей сетью и томами.

Создадим Pod из образа nginx:

kubectl run nginx --image=nginx

Проверим, что Pod запущен:

kubectl get pods

* если Pod завис в статусе Pending или CrashLoopBackOff — смотрим логи: kubectl logs <POD>.

Deployment — декларативное управление репликами Pod'ов, отвечает за rolling update.

Создадим Deployment с тремя репликами:

kubectl create deployment nginx --image=nginx --replicas=3

Обновим образ и запустим rolling update:

kubectl set image deployment/nginx nginx=nginx:1.27

ReplicaSet — держит нужное число копий Pod, обычно управляется через Deployment, а не напрямую.

Посмотрим ReplicaSet, который создал Deployment:

kubectl get replicaset

* вручную ReplicaSet создавать почти никогда не нужно — этим занимается Deployment.

StatefulSet — для stateful-приложений: стабильные имена Pod'ов и отдельный PVC на каждую реплику.

Создадим StatefulSet из манифеста:

kubectl apply -f statefulset.yaml

Главная особенность StatefulSet — блок volumeClaimTemplates, который создаёт свой PVC для каждой реплики:

volumeClaimTemplates:
  - metadata:
     name: data
    spec:
      accessModes: ["ReadWriteOnce"]
      resources:
        requests:
          storage: 5Gi

* Pod'ы получают имена по порядку — postgres-0, postgres-1, postgres-2 — и при пересоздании возвращаются к своему же тому.

DaemonSet — запускает по одному Pod на каждом (или на выбранных) node — например, для сбора логов или метрик.

Создадим DaemonSet из манифеста:

kubectl apply -f daemonset.yaml

Посмотрим системные DaemonSet, которые уже работают в кластере:

kubectl -n kube-system get daemonset

Job / CronJob — разовые и периодические задачи, которые должны выполниться и завершиться, а не работать постоянно.

Запустим разовую задачу:

kubectl create job backup --image=busybox -- echo "done"

Создадим такую же задачу, но по расписанию:

kubectl create cronjob backup --image=busybox --schedule="0 3 * * *" -- echo "done"

Сеть и доступ

Service — стабильный VIP/DNS-адрес к набору Pod'ов. IP-адрес Pod'а меняется при каждом пересоздании, а Service решает эту проблему — даёт постоянную точку входа независимо от того, что происходит с Pod'ами. Бывает трёх типов: ClusterIP, NodePort, LoadBalancer.

Опубликуем Deployment nginx через Service:

kubectl expose deployment nginx --port=80 --type=ClusterIP

Проверим, что Service появился:

kubectl get svc

Ingress — маршрутизирует HTTP(S)-трафик снаружи кластера к нужному Service по домену или пути.

Создадим Ingress из манифеста:

kubectl apply -f ingress.yaml

* сам по себе Ingress ничего не делает — это только правила маршрутизации. Чтобы они заработали, в кластере должен быть установлен Ingress Controller (например, NGINX Ingress Controller), который эти правила читает и обслуживает трафик.

Endpoint / EndpointSlice — фактические IP-адреса Pod'ов, которые стоят за Service. Kubernetes обновляет их автоматически.

Посмотрим, какие адреса попали в Service:

kubectl get endpointslices

NetworkPolicy — определяет, кто с кем может общаться внутри кластера, фактически firewall на уровне Pod'ов.

Применим NetworkPolicy из манифеста:

kubectl apply -f networkpolicy.yaml

* по умолчанию весь трафик между Pod'ами разрешён — NetworkPolicy нужна, только если требуется его ограничить.

Конфигурации и секреты

ConfigMap — хранит несекретные настройки: переменные окружения, конфигурационные файлы.

Создадим ConfigMap из пары значений:

kubectl create configmap app-config --from-literal=LOG_LEVEL=info

Secret — хранит чувствительные данные: пароли, TLS-сертификаты, токены.

Создадим Secret с паролем:

kubectl create secret generic db-pass --from-literal=password=P@ssw0rd

* Secret по умолчанию хранится в base64, а не в зашифрованном виде — для полноценного шифрования нужен внешний механизм, например Sealed Secrets.

Хранилище

PersistentVolume (PV) — кусок хранилища в кластере: сетевой диск, локальный том или облачный volume.

Посмотрим список доступных PV:

kubectl get pv

PersistentVolumeClaim (PVC) — запрос приложения на том нужного размера и класса.

Создадим PVC из манифеста:

kubectl apply -f pvc.yaml

StorageClass — класс и политика динамического выделения томов, определяет, какой драйвер хранилища использовать.

Посмотрим StorageClass, доступные в кластере:

kubectl get storageclass

Организация и права

Namespace — логическое разделение ресурсов внутри одного кластера.

Создадим Namespace для проекта:

kubectl create namespace myapp

ServiceAccount — идентичность, от имени которой Pod обращается к API Kubernetes.

Создадим ServiceAccount:

kubectl create serviceaccount app-sa

Role / ClusterRole + RoleBinding / ClusterRoleBinding — RBAC: набор прав (Role) и их привязка к пользователю или ServiceAccount (RoleBinding).

Создадим Role с правом читать Pod'ы:

kubectl create role pod-reader --verb=get,list --resource=pods

Привяжем Role к ServiceAccount:

kubectl create rolebinding pod-reader-binding --role=pod-reader --serviceaccount=myapp:app-sa

Узлы и планирование

Node — рабочая машина кластера, на которой запускаются Pod'ы.

Посмотрим список node в кластере:

kubectl get nodes

Label / Selector / Annotation — метки для отбора объектов и метаданные, которые ни на что не влияют напрямую.

Добавим Label на node:

kubectl label node node1 disktype=ssd

Добавим Annotation на Pod:

kubectl annotate pod nginx owner=devops-team

* разница простая: по Label можно отбирать объекты через Selector, а Annotation — это просто метаданные для людей и инструментов, на отбор объектов она не влияет.

Affinity / Taint / Toleration — определяют, на какие node может (или не может) попасть Pod.

Пометим node как выделенный, недоступный для обычных Pod'ов:

kubectl taint nodes node1 dedicated=gpu:NoSchedule

* чтобы Pod всё же попал на такой node, у него в манифесте должна быть соответствующая Toleration.

Прочее частое

HorizontalPodAutoscaler (HPA) — автоматически меняет число реплик Deployment в зависимости от нагрузки.

Создадим HPA для Deployment nginx:

kubectl autoscale deployment nginx --min=2 --max=10 --cpu-percent=80

ResourceQuota / LimitRange — ограничивают, сколько ресурсов может суммарно потребить Namespace и сколько — один Pod.

Применим ResourceQuota из манифеста:

kubectl apply -f resourcequota.yaml

CustomResourceDefinition (CRD) — добавляет в Kubernetes собственный тип объекта, обычно вместе с оператором, который им управляет.

Посмотрим, какие CRD уже установлены в кластере:

kubectl get crd

PodDisruptionBudget (PDB) — ограничивает, сколько Pod'ов Deployment или StatefulSet может одновременно оказаться недоступно при плановых операциях — обновлении node, автоскейлинге кластера.

Создадим PDB, который не даёт остановить больше одного Pod'а разом:

kubectl create poddisruptionbudget nginx-pdb --selector=app=nginx --min-available=2

# DevOps # Контейнеризация # Серверы
Дмитрий Моск — частный мастер
Был ли полезен этот ответ?

Да            Нет

Дмитрий Моск
— IT-специалист.
Настройка серверов, услуги DevOps.

Нужна бесплатная консультация?

Вопросы и ответы

Какие основные ресурсы Kubernetes стоит помнить

Топ ошибок, с которыми можно столкнуться в Kubernetes

Темная и светлая стороны вайб-кодинга. Стоит ли пользоваться.

Таблица сравнения методологий программирования Waterfall и Agile

Принцип организации централизованной адресной книги для почтового сервера

Обзор восьмой версии Linux CentOS

Распространенные способы устранения проблем с компьютером

Другие вопросы

Все статьи

Задать свой ворос можно в данной форме:






Реклама