Pod, Deployment, Service: кто за что отвечает
Первый вопрос по Kubernetes почти всегда про иерархию объектов — по ответу видно, писал ли кандидат манифесты сам.
Вопрос: «Объясните разницу между Pod, Deployment и Service. Что произойдёт, если удалить Pod, созданный вручную, и Pod, созданный Deployment?»
Что на самом деле проверяет интервьюер
Проверяют понимание декларативной модели: в Kubernetes вы описываете желаемое состояние, а контроллеры непрерывно приводят к нему реальность. Кандидат, который это понял, легко объяснит и самовосстановление, и масштабирование, и rolling update. Кандидат, который заучил определения, застрянет на уточняющем вопросе про удаление пода.
Развёрнутый ответ: три уровня
Pod — минимальная единица планирования
Pod — это один или несколько контейнеров, которые всегда живут на одной ноде, разделяют сетевой namespace (общий IP, общаются между собой через localhost) и могут делить тома. Pod эфемерен: у него нет постоянного IP, и он не переезжает — он умирает, а вместо него создаётся новый, с новым именем и новым адресом.
Несколько контейнеров в одном поде — это паттерн sidecar: основной контейнер приложения плюс вспомогательный (сборщик логов, прокси сервис-меша, обновлятор конфигурации). Класть в под два независимых приложения — типичная ошибка: они не смогут масштабироваться раздельно.
Deployment — контроллер, который следит за подами
Deployment описывает, сколько реплик пода должно работать и из какого шаблона их создавать. Он не управляет подами напрямую: он создаёт ReplicaSet, а уже тот держит нужное число подов. Эта прослойка и делает возможной выкатку версий — при изменении шаблона Deployment создаёт новый ReplicaSet и постепенно переливает реплики из старого в новый.
apiVersion: apps/v1
kind: Deployment
metadata:
name: api
spec:
replicas: 3
selector:
matchLabels:
app: api # по этой метке Deployment находит свои поды
template:
metadata:
labels:
app: api # метка должна совпадать с селектором
spec:
containers:
- name: api
image: registry.local/api:1.4.2
ports:
- containerPort: 8080
Теперь можно ответить на вторую часть вопроса. Удалили под, созданный вручную (kind: Pod) — он исчез навсегда, восстанавливать его некому. Удалили под Deployment — ReplicaSet через секунду заметит, что реплик стало 2 вместо 3, и создаст новый под. Это и есть самовосстановление: не магия, а контроллер, который в цикле сравнивает желаемое состояние с фактическим.
Service — стабильный адрес для меняющихся подов
Поды приходят и уходят, IP меняются — обращаться к ним напрямую нельзя. Service даёт постоянные имя и виртуальный IP (ClusterIP), а список фактических адресов подов держит в объекте Endpoints/EndpointSlice, отбирая поды по меткам, а не по принадлежности к Deployment.
apiVersion: v1
kind: Service
metadata:
name: api
spec:
selector:
app: api # любые поды с этой меткой попадут под балансировку
ports:
- port: 80 # порт самого Service
targetPort: 8080 # порт контейнера
type: ClusterIP
Внутри кластера сервис доступен по DNS-имени api, а полностью — api.production.svc.cluster.local. Типы сервисов, которые нужно назвать:
| Тип | Что даёт |
| ClusterIP | адрес только внутри кластера (по умолчанию) |
| NodePort | порт из диапазона 30000–32767 на каждой ноде |
| LoadBalancer | внешний балансировщик от облачного провайдера |
| Headless (clusterIP: None) | DNS возвращает IP всех подов; нужен StatefulSet и клиентской балансировке |
Для HTTP наружу обычно используют не LoadBalancer на каждый сервис, а Ingress (или Gateway API): один внешний балансировщик и маршрутизация по домену и пути, плюс терминация TLS.
Чем отличаются другие контроллеры
- StatefulSet — для приложений с состоянием: стабильные имена подов (
db-0,db-1), персональный том у каждой реплики, строгий порядок запуска и остановки. - DaemonSet — ровно по одному поду на каждой ноде: агенты логов, мониторинга, CNI.
- Job / CronJob — разовые и периодические задачи, где под должен завершиться, а не работать вечно.
Типичные ошибки кандидатов
- Говорят «Deployment создаёт поды», не упоминая ReplicaSet — и потом не могут объяснить механику rolling update.
- Считают, что Service связан с Deployment. Связь идёт только по меткам, поэтому опечатка в labels даёт сервис без единого endpoint — классический баг «503 при живых подах».
- Путают
portиtargetPort. - Кладут в один Pod фронтенд и бэкенд «чтобы было проще».
- Выставляют наружу десяток LoadBalancer вместо одного Ingress — дорого и неудобно.
Как ответить кратко (20–30 секунд)
«Pod — минимальная единица планирования, один или несколько контейнеров с общими сетью и томами; он эфемерен и своего постоянного IP не имеет. Deployment — контроллер, который через ReplicaSet поддерживает заданное число реплик и умеет катить новые версии: удалённый под он пересоздаст, а созданный вручную под восстанавливать некому. Service даёт стабильный DNS-адрес и балансирует трафик между подами, отбирая их по меткам — поэтому несовпадение labels и selector даёт сервис без endpoints. Наружу HTTP выставляю через Ingress, а не через LoadBalancer на каждый сервис.»