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 | Что переопределяет | Что задаёт |
|---|---|---|
command | ENTRYPOINT | саму программу |
args | CMD | аргументы программы |
Зачем переопределять команду
Базовый образ часто умеет больше одного сценария. Одним и тем же busybox можно
поднять веб-сервер, запустить разовую обработку или просто держать контейнер
живым для отладки. command/args выбирают, что именно делать, без пересборки
образа.
Отсюда и типовой приём с sleep: без него контейнер завершился бы сразу после
echo, и Pod ушёл бы из Running.
restartPolicy
restartPolicy - поле в spec, которое говорит, что делать после завершения
контейнера. У него три значения.
Always- перезапускать всегда, даже после выхода с кодом 0. Значение по умолчанию.OnFailure- перезапускать только при ненулевом коде выхода.Never- не перезапускать.
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 # проверить текущий шаг
Коротко
commandпереопределяет ENTRYPOINT образа,args- CMD.- Только
argsбезcommandпередаётся в ENTRYPOINT образа. - Долгоживущий процесс вроде
sleep 3600нужен, чтобы контейнер не завершился сразу и Pod остался в Running. restartPolicy:Always(по умолчанию),OnFailure,Never.- Растущая колонка RESTARTS означает цикл падений, дальше обычно
CrashLoopBackOff.
Прошли материал до конца? Отметьте урок пройденным.
Прогресс сохранён в этом браузере
Почистишь историю или откроешь с телефона, и отметки пропадут. Оставь почту, они переедут в аккаунт. Пароль придумывать не нужно.
Готово. теперь в аккаунте: прогресс виден с любого устройства. Мой прогресс