Чем отличается pod от контейнера?
Коротко в один абзац
Контейнер — это изолированный процесс/группа процессов, упакованный с файловой системой и настройками рантайма (Docker/CRI). Pod — это логическая оболочка в Kubernetes, в которой запускаются один или несколько контейнеров, и которая предоставляет общей группе контейнеров сеть (один IP), общие тома, namespace’ы и жизненный цикл, управляемый Kubernetes (планировщик, контроллеры, etcd).
Технические отличия (ключевые моменты)
-
Единица оркестрации: контейнер — единица рантайма; pod — единица оркестрации в k8s. Планировщик назначает pod на ноду, не отдельный контейнер.
-
Сетевой неймспейс: все контейнеры в одном pod’е делят один сетевой namespace и один IP — они видят друг друга по localhost. Контейнеры вне pod’а общаются по сети.
-
Тома и хранилище: pod может монтировать один или несколько томов (PVC, emptyDir), которые доступны всем контейнерам внутри pod.
-
Жизненный цикл и управление: pod — эфемерный (могут быть пересозданы контроллерами). Контейнеры внутри pod’а создаются/удаляются вместе с pod. Контроллеры (Deployment, StatefulSet) управляют количеством pod’ов.
-
Ресурсы и планирование: kube-scheduler учитывает requests (и limits) всех контейнеров в pod при решении, где разместить pod. cgroups и ограничения применяются на уровне отдельного контейнера исполнителем контейнерного рантайма.
-
Health / probes: liveness/readiness/startup probes назначаются per-container, но решение о маршрутизации трафика к pod принимается исходя из readiness контейнеров.
-
Безопасность: есть под-уровневые и контейнер-уровневые securityContext; serviceAccount привязан к pod.
Практические последствия
-
В pod’е два контейнера не могут слушать один и тот же порт на localhost; конфликт портов — причина ошибки.
-
Sidecar-паттерн (логирование, proxy) — контейнеры в одном pod удобно делят сеть и тома.
-
Pod — не место для долгоживущего ручного управления: в production поды создают контроллеры; если вручную удалить pod, контроллер его пересоздаст.
-
Для stateful-приложений обычно используют StatefulSet + PVC; для stateless — Deployment/ReplicaSet.
-
При сбое ноды все pod’ы на ней теряются → scheduler создаст новые pod’ы на других нодах (если ресурсы доступны).
Примеры (микро)
Docker (один контейнер):
docker run --name web -p 8080:80 nginx:latest
Kubernetes (pod с двумя контейнерами, основной + sidecar, общий volume):
apiVersion: v1
kind: Pod
metadata:
name: app-with-sidecar
spec:
containers:
\- name: app
image: myapp:1.0
ports: \[{ containerPort: 8080 }\]
\- name: sidecar-logger
image: fluentd:latest
volumeMounts:
\- name: shared-logs
mountPath: /var/log/app
volumes:
\- name: shared-logs
emptyDir: {}
В этом pod’е контейнер app пишет логи в /var/log/app, sidecar их читает по localhost и тому же пути.
Лучшие практики
-
Держите один основной контейнер в pod; добавляйте sidecar’ы только если действительно нужен совместный сетевой/файловый контекст.
-
Всегда задавайте resources.requests и limits.
-
Используйте readiness probe, чтобы трафик шёл только к готовым контейнерам.
-
Не полагайтесь на уникальность pod для хранения важного состояния — используйте PVC/managed services.