Вопрос 9 · Раздел 14

Что такое Pod в Kubernetes?

K8s не работает с контейнерами напрямую, потому что ему нужно место для «помощников» (sidecar, init-контейнеры) и общей конфигурации (сеть, тома). Pod -- это обёртка, которая гр...

Версии по языкам: English Russian Ukrainian

Junior уровень

Простое объяснение

Pod (Под) — это минимальная единица запуска в Kubernetes. Pod оборачивает один или несколько контейнеров и предоставляет им общие ресурсы: IP-адрес, хранилище, настройки.

K8s не работает с контейнерами напрямую, потому что ему нужно место для «помощников» (sidecar, init-контейнеры) и общей конфигурации (сеть, тома). Pod – это обёртка, которая группирует один или несколько контейнеров.

Простая аналогия

Pod — это как комната в общежитии:

  • В комнате может жить один человек (один контейнер) — самый частый случай
  • Иногда в комнате живут два человека (два контейнера) — если они тесно связаны
  • Все в комнате делят общую ванную и кухню (общие ресурсы)
  • У комнаты один адрес (один IP на весь Pod)

Ключевые особенности

  1. Один IP на все контейнеры — контейнеры в Pod общаются через localhost
  2. Общие тома — контейнеры могут читать/писать одни и те же файлы
  3. Вместе живут, вместе умирают — 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 не работает напрямую с контейнерами?

  1. Группировка связанных процессов: Некоторые процессы должны быть colocated (на одном Node),共享 network stack, иметь общий lifecycle.

  2. Единица атомарности:
    • Scheduler размещает Pod целиком на один Node
    • Все контейнеры Pod стартуют/умирают вместе
    • Невозможно разделить контейнеры Pod между Node
  3. Изоляция и共享: 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’ов