Основные сущности 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