Що таке 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’ів