Что такое Pod в Kubernetes?
K8s не работает с контейнерами напрямую, потому что ему нужно место для «помощников» (sidecar, init-контейнеры) и общей конфигурации (сеть, тома). Pod -- это обёртка, которая гр...
Junior уровень
Простое объяснение
Pod (Под) — это минимальная единица запуска в Kubernetes. Pod оборачивает один или несколько контейнеров и предоставляет им общие ресурсы: IP-адрес, хранилище, настройки.
K8s не работает с контейнерами напрямую, потому что ему нужно место для «помощников» (sidecar, init-контейнеры) и общей конфигурации (сеть, тома). Pod – это обёртка, которая группирует один или несколько контейнеров.
Простая аналогия
Pod — это как комната в общежитии:
- В комнате может жить один человек (один контейнер) — самый частый случай
- Иногда в комнате живут два человека (два контейнера) — если они тесно связаны
- Все в комнате делят общую ванную и кухню (общие ресурсы)
- У комнаты один адрес (один IP на весь Pod)
Ключевые особенности
- Один IP на все контейнеры — контейнеры в Pod общаются через
localhost - Общие тома — контейнеры могут читать/писать одни и те же файлы
- Вместе живут, вместе умирают — Pod создаётся и удаляется целиком
Самый частый случай: один контейнер на Pod
apiVersion: v1
kind: Pod
metadata:
name: myapp-pod
spec:
containers:
- name: myapp
image: myapp:1.0
ports:
- containerPort: 8080
Почему Pod, а не просто контейнер?
Kubernetes нужно место для дополнительной информации:
- Sidecar-контейнеры (сбор логов, мониторинг)
- Init-контейнеры (подготовка перед запуском основного)
- Общие ресурсы (тома, сеть)
Важно: Pod’ы эфемерны
Pod’ы эфемерны – могут исчезнуть в любой момент. Ваш код не должен хранить состояние в Pod. Используйте PersistentVolume или внешнюю БД для данных.
Что запомнить Junior-разработчику
- Pod — минимальная единица запуска в K8s
- Обычно один контейнер = один Pod
- Контейнеры в Pod делят IP и тома
- Pod’ы эфемерны — могут исчезнуть в любой момент
- В продакшене Pod’ами управляют через Deployment, не напрямую
Когда НЕ использовать multi-container Pod
НЕ используйте multi-container Pod, если: контейнеры можно разделить, они не требуют общего lifecycle, масштабировать их нужно независимо.
Middle уровень
Зачем нужен Pod?
Pod — это абстракция для группы тесно связанных контейнеров, которые должны работать вместе на одном сервере.
Паттерны использования нескольких контейнеров
В большинстве случаев используется правило “один контейнер на Pod”. Но есть паттерны для нескольких контейнеров:
Sidecar – вспомогательный контейнер, работающий рядом с основным (как мотоцикл с коляской).
1. Sidecar (Боковой контейнер)
Вспомогательный контейнер расширяет функции основного:
spec:
containers:
- name: app
image: myapp:1.0
volumeMounts:
- name: logs
mountPath: /var/log/app
- name: log-agent # Sidecar
image: fluentd
volumeMounts:
- name: logs
mountPath: /var/log/app
readOnly: true
volumes:
- name: logs
emptyDir: {}
Примеры: сборщик логов (Fluentd), прокси Service Mesh (Istio sidecar).
2. Adapter
Преобразует вывод основного приложения к стандарту внешней системы:
[App: свой формат данных] → [Adapter: Prometheus формат] → [Внешний мониторинг]
3. Ambassador
Проксирует соединения основного контейнера к внешним сервисам:
[App] → [Ambassador: localhost:3306] → [Удалённая БД: db.example.com:3306]
4. Init Containers
Запускаются и завершаются до старта основных контейнеров:
spec:
initContainers:
- name: wait-for-db
image: busybox
command: ['sh', '-c', 'until nc -z db 5432; do sleep 2; done']
containers:
- name: app
image: myapp:1.0
Жизненный цикл Pod
Pending → Running → (Succeeded | Failed)
↓
Terminated
- Pending: Pod принят, но ещё не запущен (скачивается образ)
- Running: Pod запущен, контейнеры работают
- Succeeded: Все контейнеры завершены успешно
- Failed: Хотя бы один контейнер завершился с ошибкой
Почему нельзя работать с Pod напрямую?
В продакшене Pod’ы создаются не вручную, а через контроллеры:
| Контроллер | Назначение |
|---|---|
| Deployment | Stateless приложения (REST API, веб-сервисы) |
| StatefulSet | Stateful приложения (БД, очереди) |
| DaemonSet | Один Pod на каждом Node (логи, мониторинг) |
| Job/CronJob | Одноразовые задачи |
Эти контроллеры обеспечивают самовосстановление: если Pod упал, контроллер создаст новый.
Сеть Pod’ов
- Каждый Pod получает уникальный IP-адрес
- Все контейнеры в Pod делят один network namespace
- Контейнеры общаются через
localhost - Pod’ы общаются друг с другом напрямую (без NAT)
Что запомнить Middle-разработчику
- Pod — обёртка над группой тесно связанных контейнеров
- 90% случаев: один контейнер = один Pod
- Паттерн Sidecar — база для Service Mesh и логирования
- Init Containers — для подготовки перед запуском
- Pod’ы эфемерны — используйте Deployment для управления
- Контейнеры в Pod делят Network и IPC namespaces
Senior уровень
Pod как атомарная единица планирования
Pod — это фундаментальная абстракция Kubernetes, которая определяет границу атомарности для планирования, масштабирования и отказа.
Архитектурное обоснование Pod
Почему K8s не работает напрямую с контейнерами?
-
Группировка связанных процессов: Некоторые процессы должны быть colocated (на одном Node),共享 network stack, иметь общий lifecycle.
- Единица атомарности:
- Scheduler размещает Pod целиком на один Node
- Все контейнеры Pod стартуют/умирают вместе
- Невозможно разделить контейнеры Pod между Node
- Изоляция и共享: Pod определяет границы изоляции (что разделяется) и共享 (что нет).
Linux Namespaces и Pod
Все контейнеры в Pod делят:
- Network namespace: один IP, один набор портов
- IPC namespace: общая межпроцессная коммуникация
- UTS namespace: одинаковое hostname
Но изолированы:
- PID namespace (по умолчанию, можно изменить)
- User namespace (опционально)
Pod Spec: ключевые секции
apiVersion: v1
kind: Pod
metadata:
name: myapp
labels:
app: myapp
version: v1
spec:
# Планирование
nodeSelector:
disktype: ssd
tolerations:
- key: "dedicated"
operator: "Equal"
value: "gpu"
effect: "NoSchedule"
# Инициализация
initContainers: [...]
# Контейнеры
containers:
- name: app
image: myapp:1.0
resources:
requests:
cpu: "500m"
memory: "256Mi"
limits:
cpu: "1"
memory: "512Mi"
livenessProbe: {...}
readinessProbe: {...}
volumeMounts: [...]
# Тома
volumes: [...]
# Безопасность
securityContext:
runAsNonRoot: true
fsGroup: 2000
# DNS
dnsPolicy: ClusterFirst
hostname: myapp
subdomain: default
Продвинутые паттерны
Sidecar для mTLS (Istio)
containers:
- name: app
image: myapp:1.0
- name: istio-proxy
image: istio/proxyv2:1.20
# Перехватывает весь трафик, обеспечивает mTLS
Init Container для миграций
initContainers:
- name: db-migrate
image: myapp:1.0
command: ['java', '-jar', 'app.jar', '--migrate']
containers:
- name: app
image: myapp:1.0
command: ['java', '-jar', 'app.jar']
Pod жизненный цикл: Deep Dive
Phase transitions:
Pending: Pod accepted, containers not yet running
↓ (image pulled, resources allocated)
Running: At least one container running
↓ (all containers exit successfully)
Succeeded: Terminal state
↓ (any container exits with error)
Failed: Terminal state
Container states:
- Waiting: Container not yet started (pulling image, etc.)
- Running: Container executing
- Terminated: Container exited (with exit code, signal, reason)
Pod Disruption Budget (PDB)
Для защиты от добровольных перемещений (drain, rollout):
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: myapp-pdb
spec:
minAvailable: 2
selector:
matchLabels:
app: myapp
Ephemeral Containers (v1.23+)
Для отладки без перезапуска Pod:
kubectl debug -it myapp-pod --image=busybox --target=app
QoS Classes
Kubernetes назначает QoS класс Pod’у на основе requests/limits:
| Класс | Условия | Приоритет eviction |
|---|---|---|
| Guaranteed | requests == limits для всех контейнеров | Последний |
| Burstable | Хотя бы один request < limit | Средний |
| BestEffort | Нет requests/limits | Первый |
Резюме для Senior
- Pod — обёртка над группой тесно связанных контейнеров.
- Контейнеры в Pod’е разделяют Network и IPC namespaces.
- Паттерн Sidecar — фундамент для Service Mesh, observability, security.
- Pod’ы эфемерны — относятся как к “скоту” (Cattle), не как к “питомцам” (Pets).
- QoS классы определяют приоритет при eviction.
- PDB защищает от добровольных перемещений.
- Init Containers — для инициализации, Sidecar — для расширения функциональности.
🎯 Шпаргалка для интервью
Обязательно знать:
- Pod — минимальная единица запуска в K8s; обёртка над одним или несколькими контейнерами
- 90% случаев: один контейнер = один Pod
- Контейнеры в Pod делят Network namespace (один IP), IPC, volumes
- Pod’ы эфемерны — относятся как Cattle, не Pets; не храните состояние в Pod
- В продакшене Pod’ами управляют через контроллеры (Deployment, StatefulSet, DaemonSet)
- Паттерны: Sidecar (расширение), Init (подготовка), Ambassador (прокси)
- QoS классы (Guaranteed, Burstable, BestEffort) определяют приоритет при eviction
Частые уточняющие вопросы:
- «Почему K8s не работает с контейнерами напрямую?» — Нужно место для sidecar, init-контейнеров, общей конфигурации
- «Что такое Sidecar?» — Вспомогательный контейнер рядом с основным (логирование, service mesh proxy)
- «Что будет если Pod упадёт?» — Контроллер (Deployment) создаст новый; сам Pod не перезапускается
- «Как контейнеры в Pod общаются?» — Через
localhost(общий network namespace)
Красные флаги (НЕ говорить):
- «Создаю Pod’ы напрямую в продакшене» (используйте Deployment/StatefulSet)
- «Pod = один контейнер всегда» (multi-container Pod — стандартный паттерн)
- «Данные в Pod сохраняются после удаления» (Pod’ы эфемерны)
- «Контейнеры в Pod имеют разные IP» (делят один network namespace)
Связанные темы:
- [[Что такое Kubernetes и зачем он нужен]] — архитектура K8s
- [[Что такое Node в Kubernetes]] — где работают Pod’ы
- [[Как организовать rolling update в Kubernetes]] — обновление Pod’ов