Прямой ответ
Kustomize решает задачу вариативности манифестов без шаблонизации. Вместо переменных и условий используется наложение: базовый набор объектов описывается один раз, а отличия окружений задаются патчами и трансформациями. Инструмент встроен в kubectl начиная с версии 1.14 и вызывается флагом -k.
Типовая структура:
deploy/
base/
kustomization.yaml
deployment.yaml
service.yaml
overlays/
staging/
kustomization.yaml
replicas-patch.yaml
production/
kustomization.yaml
resources-patch.yaml
Базовый kustomization.yaml:
resources:
- deployment.yaml
- service.yaml
labels:
- pairs:
app.kubernetes.io/name: api
includeSelectors: true
Overlay для production:
namespace: production
namePrefix: api-
resources:
- ../../base
images:
- name: registry/app
newTag: "2026.10.21-1"
replicas:
- name: app
count: 6
patches:
- path: resources-patch.yaml
Просмотр результата без применения:
kubectl kustomize overlays/production
kubectl apply -k overlays/production
kubectl diff -k overlays/production
Ключевые механизмы:
| Поле | Действие |
|---|---|
namePrefix, nameSuffix |
Добавляет префикс ко всем именам и обновляет ссылки |
namespace |
Проставляет namespace во всех объектах |
images |
Заменяет имя образа и тег |
replicas |
Меняет число реплик по имени Deployment |
patches |
Применяет strategic merge или JSON-патч |
labels |
Добавляет метки с контролем попадания в селекторы |
configMapGenerator |
Создаёт ConfigMap с хэшем в имени |
components |
Подключает переиспользуемые фрагменты |
Отдельного внимания заслуживают генераторы. configMapGenerator создаёт ConfigMap с суффиксом из хэша содержимого и автоматически обновляет ссылки на него в Deployment. Изменение конфига меняет имя ConfigMap, что приводит к пересозданию подов — проблема «конфиг обновлён, но под работает со старым» решается механизмом, а не ручной процедурой.
Практика: организация манифестов
1. Разделяйте base и overlays. Base описывает приложение без привязки к окружению; overlay содержит только отличия. Дублирование полного набора манифестов на каждое окружение приводит к расхождению, которое обнаруживается в момент инцидента.
2. Используйте components для переиспользования. Компонент — фрагмент, который можно подключить в нескольких overlay: мониторинг, доступ к базе, TLS. В отличие от base, компонент не обязан быть самостоятельным набором.
3. Патчи вместо копирования. Strategic merge patch заменяет только указанные поля, поэтому изменение одного параметра не требует переноса всего манифеста.
4. Проверяйте результат до применения. kubectl kustomize выводит итоговые объекты; kubectl diff показывает расхождение с состоянием кластера. Это обязательный шаг в пайплайне — см. статью про пайплайны.
5. Версионируйте теги образов, а не latest. Поле images позволяет подставлять тег из сборки, сохраняя base неизменным.
6. Не смешивайте Kustomize с шаблонизацией в одном слое. Если манифест уже содержит подстановку переменных, результат kustomize становится непредсказуемым для чтения.
Рекомендации:
- Начинайте с base и двух overlay. Усложнение структуры раньше появления реальной необходимости затрудняет чтение.
- Держите секреты вне репозитория.
secretGeneratorподдерживает файлы, но секрет в Git — это секрет в истории; детали — в статье про управление секретами. - Сравнивайте с Helm осознанно. Kustomize управляет конфигурацией существующих манифестов; Helm — пакетный менеджер с шаблонами и хуками жизненного цикла. Для приложения, которое устанавливают другие команды, подходит Helm; для собственного набора окружений — Kustomize. Сравнение — в статье про Helm.
- Фиксируйте структуру в репозитории вместе с манифестами. Изменение overlay должно проходить то же ревью, что и код.
- Помните, что Kustomize не управляет состоянием. Он генерирует объекты, но не отслеживает дрейф и не хранит состояние, в отличие от Terraform — см. IaC-подход.
Практический сценарий: staging и production разошлись на два месяца
Контекст: манифесты для staging и production хранились в двух каталогах копированием. Обновление лимитов ресурсов внесли в staging и забыли про production.
- Обнаружение. После деплоя в production часть подов начала вытесняться: лимиты памяти в production остались старыми, меньше фактического потребления.
- Диагностика. Сравнение манифестов показало 14 отличий, из которых осмысленными были три: число реплик, тег образа и значения ресурсов. Остальные расхождения возникли из-за правок, внесённых только в одну копию.
- Причина. Отсутствие единого источника: каждый каталог жил своей жизнью, и ревью не выявляло пропущенные правки.
- Действия. (а) Создали
baseс общими манифестами; (б) в overlay вынесли только namespace, число реплик, тег образа и патч ресурсов; (в) добавили шагkubectl diff -kв пайплайн перед применением; (г) добавили CI-проверку, чтоkubectl kustomizeвыполняется без ошибок для всех overlay — синтаксическая ошибка в одном overlay больше не блокирует только его; (д) удалили дублирующиеся каталоги. - Результат. Правка ресурсов в base применяется к обоим окружениям; расхождения остались только в трёх осознанных полях, а расхождение по остальным полям стало невозможным по конструкции.
Вывод: копирование манифестов между окружениями создаёт расхождения, которые проявляются в худший момент. Выделение общей базы и явных отличий делает расхождение видимым на этапе ревью.
FAQ
Kustomize и Helm — конкуренты? Частично. Kustomize работает с готовыми манифестами без шаблонизации, Helm предлагает шаблоны, значения и релизы. Их часто сочетают: Helm устанавливает сторонние компоненты, Kustomize управляет собственными.
Нужен ли отдельный бинарник kustomize?
Нет, для большинства задач достаточно kubectl kustomize и kubectl apply -k. Отдельная установка нужна, если требуется версия, опережающая встроенную в kubectl.
Что делать с секретами в Kustomize? Использовать генераторы с внешним источником или плагины, либо хранить зашифрованные значения. Хранение открытых секретов в репозитории недопустимо даже в приватном.
Как откатить изменение, внесённое через Kustomize? Kustomize не хранит состояние, поэтому откат — это применение предыдущей версии overlay из Git. Именно поэтому изменения должны фиксироваться в репозитории.
Источники: Kubernetes docs (manage objects with Kustomize), kubectl docs — ссылки в шапке.