Kubernetes v1.33 покращує управління життєвим циклом контейнерів

З виходом Kubernetes v1.33 API життєвого циклу контейнерів отримало кілька вдосконалень, які спрощують, роблять безпечнішими та більш гнучкими процеси м’якого старту та завершення роботи. У цій статті ми детально розглянемо кожну нову можливість – нульові затримки, кастомні сигнали зупинки – а також надамо технічний контекст, рекомендації щодо продуктивності та найкращі практики, рекомендовані учасниками SIG Node.
Нульове значення для дії Sleep
Вперше введена в Kubernetes v1.29, дія Sleep
для хуків життєвого циклу preStop
та postStart
відокремлює м’які паузи від образів контейнерів, усуваючи необхідність вбудовувати бінарний файл sleep
. У фоновому режимі вона безпосередньо викликає time.Sleep()
з Go, яка вже розглядає нульову або від’ємну тривалість як бездіяльність. Проте до v1.32 хук чітко відхиляв нульові значення.
З версією v1.33 функція PodLifecycleSleepActionAllowZero
перейшла в бета-стадію і включена за замовчуванням. Це означає, що тепер ви можете вказати нульову затримку, щоб позначити “без паузи”, не активуючи фічі. З технічної точки зору, зміна полягала в простій перевірці прапорця в менеджері життєвого циклу kubelet, але вона усуває давнє рішення, коли користувачі змушені були вибирати довільні маленькі тривалості, щоб обійти валідацію.
Чому це важливо: у великих кластерах з сотнями оновлень на годину усунення непотрібних затримок як прискорює розгортання, так і зменшує навантаження на API. Як зазначає Janet Kuo з SIG Node, “нуль – це справжній ідентифікатор для тривалості паузи – тепер наша валідація відповідає семантиці Go”.
Сигнали зупинки контейнера
До v1.33 Kubernetes покладався виключно на інструкцію STOPSIGNAL
, закладену в маніфесті образу. Це ускладнювало можливість зміни або налаштування сигналів, таких як SIGUSR1
або SIGHUP
, під час розгортання без перебудови образу.
Нова функція ContainerStopSignals
додає поле stopSignal
до блоку lifecycle
специфікації Pod. При активації kubelet перевірить сигнал на відповідність spec.os.name
(або linux
, або windows
) і передасть його через виклики CRI, якщо середовище виконання це підтримує. На Linux ви можете вибрати з повного діапазону POSIX; на Windows дозволені лише SIGTERM
та SIGKILL
.
Стандартна поведінка
Якщо кастомний stopSignal
не задано, kubelet повертається до STOPSIGNAL
образу. Якщо такого немає, використовується стандартне значення середовища виконання контейнера (SIGTERM
для containerd та CRI-O). Ця багаторівнева система резервування забезпечує зворотну сумісність, одночасно надаючи більше контролю.
Несумісність версій
Оскільки ContainerStopSignals
є альфа-функцією в v1.33, ви повинні вручну активувати її в kube-apiserver
та kubelet
за допомогою --feature-gates=ContainerStopSignals=true
. Одночасно, версії containerd v1.7+ та CRI-O v1.26+ впроваджують підтримку передачі нестандартних сигналів через API CRI. Перевірте CHANGELOG вашого середовища виконання для точних прапорців.
Використання сигналів зупинки контейнера
Нижче наведено приклад маніфесту Pod, який планується на Linux і використовує SIGUSR1
:
apiVersion: v1
kind: Pod
metadata:
name: nginx-custom-stop
spec:
os:
name: linux
containers:
- name: nginx
image: nginx:stable
lifecycle:
stopSignal: SIGUSR1
Пам’ятайте: без вказівки spec.os.name
ви не можете задавати довільні сигнали, а на Windows вузлах ваш вибір обмежується SIGTERM
або SIGKILL
. Якщо поле пропущене, Kubernetes вважає, що ви використовуєте семантику Linux, але відхилить недійсні сигнали під час прийому.
Вплив на продуктивність та спостережуваність
Введення підтримки нульових затримок та сигналів зупинки, керованих API, має наслідки для спостережуваності. Метрики, що надаються kubelet (container_start_latency
, container_stop_latency
), тепер відображатимуть коротші затримки, коли Sleep
=0. Використовуйте правила Prometheus для моніторингу незвично високих затримок, які можуть свідчити про блокування завершення роботи на рівні навантаження.
З боку CRI журнали середовища виконання з --log-level=debug
тепер повідомляють точні SIG*
сигнали, які були надіслані. У виробництві команди повинні інтегрувати ці події в централізоване ведення журналу (ELK, Loki), щоб кожна зміна сигналу корелювала з оповіщеннями про життєвий цикл Pod. Як радить Еміліо Ернандес з проекту containerd, “активація детальних сигналів зупинки зменшує ймовірність помилкових циклів аварій, але вимагає енд-то-енд трасування для відстеження доставки сигналів”.
Найкращі практики для хуків життєвого циклу
- Використовуйте нульові затримки
Sleep
, коли не потрібні реальні затримки, щоб прискорити операції масштабування. - Залиште кастомні сигнали зупинки для додатків, які реалізують обробники м’якого завершення роботи в процесі (наприклад, HTTP-сервери, які реагують на
SIGUSR1
для семантики очищення). - Перевіряйте назви ОС у CI-процесах, щоб уникнути потрапляння недійсних комбінацій
spec.os.name
абоstopSignal
у виробництво. - Моніторте метрики kubelet і журнали CRI після розгортання, щоб переконатися, що нові хуки не затримують перевірки готовності або завершення роботи.
Майбутня дорожня карта та залучення спільноти
Дивлячись у майбутнє, SIG Node обговорює загальну доступність ContainerStopSignals
у v1.34 та розширення хуків життєвого циклу для підтримки кількох сигналів на контейнер. Тимчасові контейнери та хуки для налагодження також заплановані для подальшого вдосконалення. Щоб відстежувати прогрес, слідкуйте за проблемами SIG Node на GitHub або приєднуйтесь до #sig-node у Slack.
Ваша участь вітається! Незалежно від того, чи ви працюєте над Kubelet, вдосконалюєте підтримку сигналів у CRI-O, чи пишете тести для поведінки Windows, для вашої експертизи знайдеться місце. Для отримання додаткової інформації:
- Поштова розсилка: kubernetes-sig-node@googlegroups.com
- Проблеми спільноти: Проблеми SIG Node
- Зв’язатися з автором: GitHub
@sreeram-venkitesh
, Slack@sreeram.venkitesh