Зачем в Kubernetes запускать несколько контейнеров в одном Pod?

«Зачем в Kubernetes запускать несколько контейнеров в одном Pod?» — вопрос из категории Kubernetes, который задают на 23% собеседований Devops Инженер. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Pod — это атомарная единица планирования в Kubernetes, которая может содержать один или несколько тесно связанных контейнеров, разделяющих общие ресурсы. Это нужно для сценариев тесного взаимодействия.

Основные паттерны и причины:

  1. Sidecar-паттерн: Вспомогательный контейнер расширяет или усиливает основной.
    • Пример: Контейнер nginx (веб-сервер) и контейнер fluentd (сбор логов), которые монтируют общий emptyDir-том для access-логов.
  2. Ambassador-паттерн: Контейнер-посредник для сетевого взаимодействия (например, проксирует все исходящие подключения).
  3. Adapter-паттерн: Контейнер, нормализующий или преобразующий выходные данные основного контейнера (например, форматирование метрик).

Что разделяют контейнеры внутри Pod:

  • Network Namespace: Один IP-адрес, localhost, порты. Контейнеры общаются друг с другом по localhost.
  • Storage Volumes: Общие тома для обмена данными.
  • IPC Namespace: Возможность использовать межпроцессное взаимодействие (например, POSIX-очереди).

Пример манифеста (Sidecar для логирования):

apiVersion: v1
kind: Pod
metadata:
  name: web-with-logger
spec:
  containers:
  - name: web-app
    image: my-app:latest
    volumeMounts:
    - name: shared-logs
      mountPath: /var/log/app
  - name: log-shipper # Sidecar-контейнер
    image: grafana/loki-logging-driver:latest
    volumeMounts:
    - name: shared-logs
      mountPath: /tail
    command: ['sh', '-c', 'tail -f /tail/app.log | send-to-loki']
  volumes:
  - name: shared-logs
    emptyDir: {}

Важно: Контейнеры в Pod запускаются и удаляются вместе. Сбой одного контейнера (с exit code >0) приводит к перезапуску всего Pod по политике restartPolicy.