Чем отличается 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.