Kubernetes 1.29: sidecar containers в beta, обновляем staging и убираем костыли
Kubernetes 1.29 переводит sidecar containers в beta. Обновляем staging-кластер и рефакторим деплойменты - убираем хак с initContainers, проверяем stateful workloads.
Kubernetes 1.29 выпущен с sidecar containers в beta и улучшениями для stateful workloads, декабрь 2023
В июле мы обновили тестовый кластер до 1.28 и включили SidecarContainers=true в alpha-режиме. Тогда же написали: если в 1.29 это двинется в beta - разговор о prod становится предметным. Kubernetes 1.29 вышел, feature gate перешёл в beta и включён по умолчанию. Разговор стал предметным.
Обновляем staging. Смотрим, что изменилось. Рефакторим несколько деплойментов, которые долго терпели неудобный initContainer-хак.
Что поменялось с alpha на beta
В 1.28 SidecarContainers был alpha gate - выключен по умолчанию, включался явным флагом на API-сервере и kubelet. Стабильность - «может поменяться без предупреждения». В 1.29 gate переходит в beta: включён по умолчанию, ожидается стабилизация API до GA, ломающие изменения крайне маловероятны.
Для нас это значит одно: можно без лишних движений тестировать на staging и планировать перенос в production. В alpha мы бы не стали этого делать для управляемых кластеров - слишком непредсказуемый жизненный цикл.
Само поведение не изменилось: restartPolicy: Always внутри initContainers делает контейнер нативным sidecar - запускается до основных, завершается после них, перезапускается независимо. Разница только в том, что теперь это работает без ручного включения gate.
Обновление staging-кластера
Начали со стандартного drain/upgrade по узлам. Никаких сюрпризов - changelog 1.29 по-настоящему большой (KEP-ов набралось прилично), но с точки зрения оператора кластера апгрейд прошёл ровно. Из заметного при обновлении: убедились, что никто из нас не полагался на поведение, которое в 1.29 changed или deprecated.
Отдельно проверили: после обновления узлов kubelet поднял SidecarContainers=true автоматически, без нашего вмешательства. Это именно то, что описано в документации для beta gate. Приятно, когда работает как написано.
Рефакторинг: убираем initContainer-хак
На staging у нас было три деплоймента с логирующими агентами Fluent Bit в виде «вечного» initContainer - тот самый хак, который не давал контейнеру выйти через кастомный entrypoint. Плюс один Job с агентом, который иногда терял последние строки лога при завершении.
Новый манифест выглядит так:
initContainers:
- name: log-agent
image: fluent/fluent-bit:2.1
restartPolicy: Always
volumeMounts:
- name: varlog
mountPath: /var/log
- name: fluent-bit-config
mountPath: /fluent-bit/etc/
containers:
- name: app
image: myapp:1.4
Старый вариант предполагал обёртку вокруг Fluent Bit, которая просто не выходила из процесса. Это работало, но kubectl describe pod показывал initContainer в состоянии Running вместо Completed - что сбивало с толку при диагностике и ломало некоторые операторские скрипты, которые ждали завершения всех initContainer перед тем, как считать под готовым «чисто».
После переезда на нативный sidecar: kubectl describe стал читаться нормально. Агент числится в отдельной секции, статусы понятны без дополнительной расшифровки.
Деплойменты - три штуки переехали за день. Накладок не было. Fluent Bit стартует гарантированно до основного контейнера, и мы видим это по порядку записей в логах самого агента: инициализация Fluent Bit стоит раньше первой строки приложения. Раньше это было «обычно так, но не гарантировано» - теперь это контракт.
Job с агентом - здесь интереснее. Job считает данные и пишет итоговый отчёт в stdout перед выходом. Fluent Bit должен успеть эти строки забрать. С нативным sidecar Kubernetes держит Job живым до тех пор, пока агент не завершится штатно после получения SIGTERM. Несколько прогонов - итоговые строки приходят полные. До рефакторинга мы периодически видели обрывы на последних секундах работы.
Что ещё интересного в 1.29
Kubernetes 1.29 принёс несколько вещей для stateful workloads, которые нам ещё предстоит внимательно изучить.
VolumeAttributesClass - новый объект для описания характеристик тома (iops, throughput) независимо от StorageClass. Пока alpha, но концептуально это попытка стандартизировать то, что каждый cloud-провайдер сейчас делает по-своему через аннотации. Смотрим.
ReadWriteOncePod для PVC - вошло в stable ещё в 1.28, но в 1.29 обновлены admission webhooks, которые корректно обрабатывают edge cases. Для баз данных с одним writer-ом это полезная гарантия, которую стоит добавить в шаблоны.
Нативные sidecar для StatefulSet - технически та же механика, что и для Deployment, но со StatefulSet есть нюансы в порядке rolling update. Пока не проверяли на staging, но это следующий пункт.
Что дальше
Staging обновлён, три деплоймента рефакторены, Job работает корректно. Следующий шаг - решать про production-кластеры. Beta дала нам достаточно уверенности, чтобы планировать перенос: ломающих изменений до GA ждать не приходится, поведение стабильно.
Пока ориентируемся на перевод продакшн-деплойментов в несколько волн - сначала те, где логирующий агент был особенно неудобным в диагностике. Там хак с «вечным» initContainer создавал больше всего путаницы при работе с pod-ами в нештатных ситуациях.
Главный итог staging-сессии: нативные sidecar containers - это не революция, а исправление давнего архитектурного долга в самом Kubernetes. KEP-753 висел с 2019 года, и то, что его наконец добили до beta, чувствуется как облегчение, а не как «новая фича».