Kustomize - сила кастомизации
Что такое Kustomize?
Kustomize — это инструмент управления конфигурацией, встроенный в kubectl, который позволяет настраивать YAML-манифесты Kubernetes без изменения исходных файлов. Он позволяет пользователям определить общий набор базовых ресурсов и затем накладывать специфичные для окружения настройки (называемые оверлеями). Это делает его идеальным для управления несколькими средами развертывания, такими как разработка, тестирование и продакшн. Вместо использования шаблонов или переменных Kustomize применяет преобразования непосредственно к YAML-файлам, совместимым с Kubernetes.
Примеры использования включают настройку тегов образов, изменение количества реплик, добавление configMap/секретов и изменение имен ресурсов или пространств имен для различных окружений. Kustomize помогает внедрять лучшие практики GitOps, сохраняя YAML декларативным и DRY (Don’t Repeat Yourself). Он поддерживает модульный дизайн, позволяя командам эффективно переиспользовать и компоновать манифесты. Поскольку он интегрирован напрямую с kubectl, его можно использовать без установки дополнительных инструментов. В целом, Kustomize подходит для команд, стремящихся управлять конфигурациями Kubernetes чисто и масштабируемо.
Как это работает
В основе Kustomize лежит инструмент на базе Go, который обрабатывает манифесты Kubernetes, считывая файл kustomization.yaml, где определяется, как собирать и изменять набор YAML-ресурсов. Конфигурация делится на базы и оверлеи. База содержит необработанные, многократно используемые манифесты Kubernetes, а оверлей применяет специфичные для окружения настройки (например, количество реплик, метки или теги образов) поверх базы. Kustomize загружает эти ресурсы в память, а затем применяет серию трансформеров для внесения запрошенных изменений.
Эти трансформеры могут добавлять префиксы к именам, внедрять пространства имен, изменять образы контейнеров или модифицировать метки и аннотации. Патчи могут применяться с использованием стратегического слияния или JSON 6902, в зависимости от требуемой точности. Kustomize также поддерживает генераторы для динамического создания ConfigMap и Secrets. После завершения всех преобразований итоговый набор YAML-манифестов выводится для использования с kubectl или CI/CD-пайплайнами. Такая архитектура обеспечивает четкое разделение между общей конфигурацией и изменениями, специфичными для окружения, что делает развертывания более безопасными и удобными для сопровождения.
kubectl apply -k
kubectl apply -k — это встроенный способ использовать Kustomize напрямую с Kubernetes. Он указывает kubectl применить настроенный набор ресурсов, определенных в каталоге, содержащем файл kustomization.yaml.
Чтобы развернуть оверлей dev в вашем кластере, выполните:
kubectl apply -k overlays/dev/
Эта команда:
Считывает kustomization.yaml в overlays/dev.
Загружает базовые ресурсы, на которые он ссылается.
Применяет патчи и преобразования.
Разворачивает итоговый YAML в кластере Kubernetes.
Автономный CLI Kustomize
Существует также автономный CLI-инструмент, который предоставляет более продвинутые функции и версии, независимые от Kubernetes. Это полезно, если вы хотите использовать Kustomize в CI/CD-пайплайнах, скриптах или вам нужны функции, которые еще недоступны в вашей версии kubectl.
Вы можете установить автономный CLI, скачав его с официальных релизов Kustomize на GitHub:
KUSTOMIZE_VERSION='vX.Y.Z' # Релизы здесь https://github.com/kubernetes-sigs/kustomize/releases
curl -LO https://github.com/kubernetes-sigs/kustomize/releases/download/kustomize/$KUSTOMIZE_VERSION/kustomize_$KUSTOMIZE_VERSION_linux_amd64.tar.gz
tar -zxvf kustomize_$KUSTOMIZE_VERSION_linux_amd64.tar.gz
sudo mv kustomize /usr/local/bin/
Или
snap install kustomize
Для пользователей macOS он также доступен через Homebrew:
brew install kustomize
После установки вы можете выполнить:
kustomize build ./overlays/dev
Для полной документации и примеров использования посетите официальную документацию Kustomize.
Декларативный подход
Kustomize следует декларативной модели конфигурации, что означает, что вы описываете каким должно быть желаемое состояние ваших ресурсов Kubernetes, а не как их создавать процедурно. Это делается через файл kustomization.yaml, который служит точкой входа для определения того, как компоновать и преобразовывать ваши манифесты.
resources:
- deployment.yaml
- service.yaml
namePrefix: dev-
namespace: dev
images:
- name: my-app
newTag: v2.0.1
configMapGenerator:
- name: app-config
literals:
- ENV=development
- LOG_LEVEL=debug
Этот файл:
Добавляет префикс
dev-к именам ресурсов.Устанавливает пространство имен
dev.Обновляет тег образа для
my-app.Генерирует ConfigMap из литеральных значений.
Подробнее о ссылке на файл Kustomization.
Этот декларативный подход упрощает контроль версий вашей конфигурации, повторное использование компонентов в разных окружениях и интеграцию с GitOps-процессами.
Демонстрация
Легенда:
Пропущенные аспекты: мы избегаем всех видов автоматизации и внешнего доступа к основным сервисам.
Вы — инженер DevOps в компании Papa Corp., отвечающий за одностраничный корпоративный сайт.
Сайт размещен в локальном кластере Kubernetes и имеет две среды: staging (предпродакшн) и production. Каждая среда принадлежит отдельному пространству имен.
После коммита новая версия сайта должна быть сначала применена в среде staging. Если всё в порядке, она будет внедрена в production.
Ваш сайт статический и очень простой, он основан на nginx (nginx:alpine). Ресурсы доступны через NodePort кластера (30088/TCP для staging, 30080/TCP для production).
Нагрузка на staging минимальна, поэтому вы можете выделить всего 64 МБ оперативной памяти и 0.1 CPU. Для среды production вы выделяете 128 МБ оперативной памяти и 0.25 CPU на три реплики (этот параметр можно изменить вручную).
Вы выбираете декларативный подход, поэтому решаете использовать Kustomization для развертывания обеих стадий сайта.

Содержимое файлов
Структура проекта показана ниже:
Основные ресурсы описаны в директории base, файлы кастомизации в папке overlays.
base содержит следущие файлы:
deployment.yaml: базовое описание nginx сервера.
apiVersion: apps/v1
kind: Deployment
metadata:
name: demo-webapp # Will be suffixed by the nameSuffix from the overlay/<stage>/kustomization.yaml
# namespace: demo-webapp-staging # Will be replaced by the namespace from the overlay/<stage>/kustomization.yaml
labels:
app: webapp # Will be replaced by the label from the base/kustomization.yaml and the overlays/<stage>/kustomization.yaml
spec:
replicas: 1 # Will be replaced by the label the overlays/<stage>/kustomization.yaml
selector:
matchLabels:
app: webapp # Will be replaced by the label from the base/kustomization.yaml and the overlays/<stage>/kustomization.yaml
template:
metadata:
labels:
app: webapp # Will be replaced by the label from the base/kustomization.yaml and the overlays/<stage>/kustomization.yaml
spec:
containers:
- name: nginx
image: nginx:alpine
resources:
requests:
memory: "128Mi" # Will be replaced by the label the overlays/<stage>/deployment-patch.yaml
cpu: "250m" # Will be replaced by the label the overlays/<stage>/deployment-patch.yaml
limits:
memory: "128Mi" # Will be replaced by the label the overlays/<stage>/deployment-patch.yaml
cpu: "250m" # Will be replaced by the label the overlays/<stage>/deployment-patch.yaml
ports:
- containerPort: 80
volumeMounts:
- name: web-content
mountPath: /usr/share/nginx/html
volumes:
- name: web-content
configMap:
name: web-content
service.yaml: описание сервиса nginx.
apiVersion: v1
kind: Service
metadata:
name: demo-webapp # Will be suffixed by the nameSuffix from the overlay/<stage>/kustomization.yaml
# namespace: demo-webapp-staging # Will be replaced by the namespace from the overlay/<stage>/kustomization.yaml
labels:
app: webapp # Will be replaced by the label from the overlay/<stage>/kustomization.yaml
spec:
selector:
app: webapp # Will be replaced by the label from the overlay/<stage>/kustomization.yaml
type: NodePort
ports:
- port: 80
targetPort: 80
# nodePort: 30088 # Will be replaced by the label from the overlay/<stage>/kustomization.yaml
namespace.yaml: описание пространства имён.
apiVersion: v1
kind: Namespace
metadata:
name: demo-webapp # Will be replaced by the namespace from the overlay/<stage>/kustomization.yaml
kustomization.yaml: Описание конфигураций и изменений присущих обоим средам.
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- deployment.yaml
- service.yaml
- namespace.yaml
configMapGenerator:
- name: web-content
files:
- files/index.html
labels:
- includeSelectors: true
includeTemplates: true
pairs:
app: demo-webapp
Папка overlays содержит две поддиректории: staging и production, в каждой из которых находится файл kustomization.yaml, описывающий типовые изменения.
staging/deployment-patch.yaml**: патчи и изменения в деплоймент nginx сервера, для пред-продакшен среды.
apiVersion: apps/v1
kind: Deployment
metadata:
name: demo-webapp
spec:
template:
spec:
containers:
- name: nginx
resources:
requests:
memory: "64Mi"
cpu: "125m"
limits:
memory: "64Mi"
cpu: "125m"
staging/kustomization.yaml**: конфигурации и изменения для пред-продакшен среды.
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- ../../base
patches:
- target:
kind: Deployment
name: demo-webapp
path: deployment-patch.yaml
- target:
kind: Service
name: demo-webapp
patch: |-
- op: replace
path: /spec/ports/0/nodePort
value: 30088
nameSuffix: -staging
namespace: demo-webapp-staging
labels:
- includeSelectors: true
includeTemplates: true
pairs:
app: demo-webapp-staging
environment: staging
production/deployment-patch.yaml**: патчи и изменения в деплоймент nginx сервера, для продакшен среды.
apiVersion: apps/v1
kind: Deployment
metadata:
name: demo-webapp
spec:
template:
spec:
containers:
- name: nginx
resources:
requests:
memory: "128Mi"
cpu: "250m"
limits:
memory: "128Mi"
cpu: "250m"
production/kustomization.yaml**: конфигурации и изменения для продакшен среды.
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- ../../base
patches:
- target:
kind: Deployment
name: demo-webapp
path: deployment-patch.yaml
- target:
kind: Service
name: demo-webapp
patch: |-
- op: replace
path: /spec/ports/0/nodePort
value: 30080
nameSuffix: -prod
namespace: demo-webapp-prod
labels:
- includeSelectors: true
includeTemplates: true
pairs:
app: demo-webapp-staging
environment: staging
replicas:
- name: demo-webapp
count: 2
base/files/index.html**: содержимое веб страницы.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Papa Corp.</title>
</head>
<body>
<header>
<h1>Welcome to the Papa Corp. site</h1>
</header>
<main>
<section>
<h2>About</h2>
<p>This is a simple describe of our company.</p>
</section>
<section>
<h2>Features</h2>
<ul>
<li>Responsive design</li>
<li>Custom styles</li>
<li>Easy to customize</li>
</ul>
</section>
</main>
<footer>
<p>© 2025 Papa Corp.</p>
</footer>
</html>
Demo actions
Требования: Демонстрация проводится на ОС Ubuntu, однако, вы можете любую другую. Также Kubernetes кластер развёрнут при помощи microk8s.
Установка
KustomizeCLIПосле установки
kustomizeперейдите в корневую папку проекта и выполните команду:
kustomize build base/
В результате вы увидите финальную базовую конфигурированную структуру желаемой инфраструктуры. Ресурсы не будут созданы, потому что эта команда работает как dry-run, и просто создает объединенную и настроенную схему в формате YAML для дальнейшей реализации.
Выполните также:
kustomize build overlays/staging
kustomize build overlays/production
Сравните полученные результаты с базовой конфигурацией. Вы увидите, что в оверлеях staging и production добавлены патчи, которые изменяют ресурсы, такие как количество реплик, лимиты ресурсов и теги образов.
- теперь, в соответствии с легендой, нам нужно развернуть базовые ресурсы. Выполните следующие команды:
kubectl apply -k overlays/staging # It will deploy the customized resources on stage (aka pre-production) layer
kubectl apply -k overlays/production # It will deploy the customized resources on production environment
Обождите немного, пока Kubernetes создаст все ресурсы. После этого проверьте их:
kubectl get all -n demo-webapp-staging # You should see all deployed resources on beta stage
# Get content of a web page
curl localhost:30088
# Check production environment
kubectl get all -n demo-webapp-production # You should see all deployed resources on prod stage
# Get content of a web page
curl localhost:30080
Используя kubectl get <RESOURCE> -n <NAMESPACE>, проверьте созданные ресурсы. Вы должны увидеть, что все ресурсы были созданы в пространстве имен demo-webapp-staging и demo-webapp-production. Также вы можете проверить, что веб-страница доступна по указанным выше адресам.
- Измените содержимое веб-страницы, чтобы проверить, что все работает правильно. Для этого вам нужно изменить файл index.html в папке base/files. Этот файл будет автоматически загружен в ConfigMap, который затем будет смонтирован в контейнер nginx. После изменения файла вы должны применить изменения в staging и production средах. Для этого выполните следующие команды:
kubectl apply -k overlays/staging
# Wait a bit and get content of a web page
curl localhost:30088
Вы должны увидеть измененное содержимое, сравните его с продакшен версией, как было сказано выше. В соответствии с легендой, вы должны проверить, что все работает правильно в staging среде. Если все в порядке, вы можете применить изменения в production среде. Для этого выполните следующие команды:
kubectl apply -k overlays/production
# Wait a bit and get content of a web page
curl localhost:30080
Готово! Вы успешно развернули и протестировали изменения в staging среде, а затем применили их в production. Пробуйте экспериментировать с различными конфигурациями и изменениями, чтобы увидеть, как Kustomize может помочь вам управлять вашими ресурсами Kubernetes. Удачи!
