Питання 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’ів