← Kubernetes: основы
6 мин · просто · Урок 5 из 11

Pod глубже: command, args, restartPolicy

Как переопределить запуск контейнера и что кластер делает после его завершения.

command и args

У каждого образа есть программа, которую он запускает по умолчанию (ENTRYPOINT и CMD из Dockerfile). Поля command и args в контейнере переопределяют это поведение.

command заменяет программу по умолчанию. args задаёт ей аргументы.

spec:
  containers:
    - name: app
      image: busybox:1.36
      command: ["sh", "-c"]
      args: ["echo hi; sleep 3600"]

Здесь контейнер запустит sh -c "echo hi; sleep 3600": напечатает hi и проспит час.

Команду можно положить целиком в command, если так удобнее:

command: ["sh", "-c", "echo hi; sleep 3600"]

Соответствие с Docker: command в Pod - это ENTRYPOINT контейнера, args - это CMD. Если задать только args, она передаётся в ENTRYPOINT образа.

Поле в PodЧто переопределяетЧто задаёт
commandENTRYPOINTсаму программу
argsCMDаргументы программы

Зачем переопределять команду

Базовый образ часто умеет больше одного сценария. Одним и тем же busybox можно поднять веб-сервер, запустить разовую обработку или просто держать контейнер живым для отладки. command/args выбирают, что именно делать, без пересборки образа.

Отсюда и типовой приём с sleep: без него контейнер завершился бы сразу после echo, и Pod ушёл бы из Running.

restartPolicy

restartPolicy - поле в spec, которое говорит, что делать после завершения контейнера. У него три значения.

restartPolicyВыход с кодом 0Выход с ошибкой
Alwaysперезапуститьперезапустить
OnFailureоставить как естьперезапустить
Neverоставить как естьоставить как есть
spec:
  restartPolicy: OnFailure
  containers:
    - name: app
      image: busybox:1.36
      command: ["sh", "-c", "exit 1"]

Контейнер с sleep 3600 завершится через час. При restartPolicy: Always его запустит заново kubelet. kubelet - агент Kubernetes на Node, который запускает и перезапускает контейнеры. Node - машина кластера, где работают Pod.

Из-за этого веб-сервис с Always не уходит в простой от одного падения: контейнер рухнул, kubelet поднял его заново, Pod снова отвечает на запросы.

Выбор политики зависит от задачи. Долгоживущему сервису нужен Always. Разовой задаче, которая должна отработать и не повторяться без ошибки, подходит OnFailure или Never (такие задачи обычно оформляют как Job, это отдельный урок).

Как это видно в кластере

Колонка RESTARTS в kubectl get pod показывает, сколько раз контейнер перезапускался. Если число растёт без остановки - контейнер падает, а политика его поднимает по кругу. Это частый симптом: CrashLoopBackOff. Разбору таких сбоев посвящены отдельные уроки дальше в курсе.

Домашка

Теорию закрепляет задание на своём кластере: 2 шага с проверкой. Кластер поднимается по треку Kubernetes локально, задания лежат в репозитории k8s-practice.

./run.sh start k8s-pod-deep     # развернуть стартовое состояние
./run.sh verify k8s-pod-deep    # проверить текущий шаг

Коротко

Прошли материал до конца? Отметьте урок пройденным.