Pod, Deployment и Service в Kubernetes: объяснение на примерах
Основы3 минРедакция Innovialabs
Коротко
Pod — запущенный контейнер, Deployment следит, чтобы нужное число подов всегда работало и обновлялось без простоя, а Service даёт им постоянный адрес. Связываются они через метки (labels) и селекторы.
Короткий ответ
Чтобы запустить приложение в Kubernetes, обычно нужны три объекта:
- Pod — минимальная единица запуска: один или несколько контейнеров с общей сетью.
- Deployment — описывает, сколько подов нужно и из какого образа, и поддерживает это состояние.
- Service — стабильный адрес и балансировщик для группы подов.
Связь между ними держится на метках (labels): Deployment создаёт поды с меткой app: web, а Service направляет трафик на все поды с этой меткой.
Pod: где живёт контейнер
Pod — обёртка вокруг контейнера. Контейнеры одного пода разделяют IP-адрес и могут общаться через localhost. Чаще всего в поде один контейнер.
apiVersion: v1
kind: Pod
metadata:
name: web
labels:
app: web
spec:
containers:
- name: web
image: nginx:1.27
ports:
- containerPort: 80
Ключевое свойство: поды временные. Если под упал или нода отказала, этот под не восстановится сам, а у нового будет другой IP. Поэтому поды почти никогда не создают вручную — этим занимается Deployment.
Deployment: сколько копий и какой версии
Deployment говорит: «держи три пода по такому шаблону». Если под исчезнет, Deployment создаст замену. Если изменить образ, он постепенно заменит старые поды новыми.
apiVersion: apps/v1
kind: Deployment
metadata:
name: web
spec:
replicas: 3
selector:
matchLabels:
app: web
template:
metadata:
labels:
app: web
spec:
containers:
- name: web
image: nginx:1.27
ports:
- containerPort: 80
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
memory: 256Mi
Что здесь важно:
replicas— желаемое число подов.selector.matchLabelsдолжен совпадать сtemplate.metadata.labels, иначе Deployment не примет конфигурацию.template— шаблон пода, по сути тот же Pod из примера выше.resourcesпомогает планировщику размещать поды и защищает ноду от перегрузки.
Под капотом Deployment создаёт ReplicaSet, который непосредственно следит за числом подов. Напрямую с ReplicaSet работать обычно не нужно.
Service: постоянный адрес
IP подов меняются, поэтому обращаться к ним напрямую нельзя. Service получает постоянное имя и IP внутри кластера и распределяет запросы между подходящими подами.
apiVersion: v1
kind: Service
metadata:
name: web
spec:
selector:
app: web
ports:
- port: 80
targetPort: 80
type: ClusterIP
Теперь другие поды в том же namespace обращаются к приложению по адресу http://web.
Основные типы Service:
| Тип | Доступ | Когда использовать |
|---|---|---|
| ClusterIP | только внутри кластера | связь между сервисами, тип по умолчанию |
| NodePort | порт на каждой ноде | тесты, простые установки |
| LoadBalancer | внешний балансировщик облака | публичный доступ в облаке |
Для HTTP-сайтов с доменами обычно добавляют Ingress — он маршрутизирует запросы по домену и пути к нужным Service.
Как всё работает вместе
- Вы применяете файлы:
kubectl apply -f deployment.yaml -f service.yaml. - Deployment создаёт ReplicaSet, тот — три пода с меткой
app: web. - Scheduler распределяет поды по нодам.
- Service находит поды по селектору
app: webи начинает слать им трафик. - Под упал — Deployment создаёт новый, Service автоматически включает его в балансировку.
Полезные команды для проверки:
kubectl get pods -l app=web
kubectl describe deployment web
kubectl get endpoints web
kubectl rollout status deployment/web
Частые ошибки
- Метки не совпадают. Селектор Service не находит поды —
kubectl get endpointsпокажет пустой список. - Перепутаны
portиtargetPort.port— порт Service,targetPort— порт контейнера. - Поды без Deployment. Ручной под не переживёт сбой ноды.
- Нет readiness probe. Service может отправить трафик в под, который ещё не готов принимать запросы.
- Тег
latest. Сложно понять, какая версия запущена, и откатиться.
Подробнее — в документации Kubernetes.