Что такое 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/

Эта команда:

  1. Считывает kustomization.yaml в overlays/dev.

  2. Загружает базовые ресурсы, на которые он ссылается.

  3. Применяет патчи и преобразования.

  4. Разворачивает итоговый 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

Этот файл:

  1. Добавляет префикс dev- к именам ресурсов.

  2. Устанавливает пространство имен dev.

  3. Обновляет тег образа для my-app.

  4. Генерирует 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 для развертывания обеих стадий сайта.

kustomize-power-of-customization

Содержимое файлов

Структура проекта показана ниже:

bavseerdsnkflspeeauiatrprmslyaolvetesgdoisosiidkudkycpmnneuceumeaidgpstpse.czeltiltnyeaxooooota.t.ymnym.myihmimiylaotezezamnmnanaml.lttttly-i-iapopomananlt.t.cyhyha.a.mymylalammll

Основные ресурсы описаны в директории 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>&copy; 2025 Papa Corp.</p>
    </footer>
</html>

Demo actions

Требования: Демонстрация проводится на ОС Ubuntu, однако, вы можете любую другую. Также Kubernetes кластер развёрнут при помощи microk8s.

  1. Установка Kustomize CLI

  2. После установки kustomize перейдите в корневую папку проекта и выполните команду:

kustomize build base/

В результате вы увидите финальную базовую конфигурированную структуру желаемой инфраструктуры. Ресурсы не будут созданы, потому что эта команда работает как dry-run, и просто создает объединенную и настроенную схему в формате YAML для дальнейшей реализации.

Выполните также:

kustomize build overlays/staging
kustomize build overlays/production

Сравните полученные результаты с базовой конфигурацией. Вы увидите, что в оверлеях staging и production добавлены патчи, которые изменяют ресурсы, такие как количество реплик, лимиты ресурсов и теги образов.

  1. теперь, в соответствии с легендой, нам нужно развернуть базовые ресурсы. Выполните следующие команды:

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. Также вы можете проверить, что веб-страница доступна по указанным выше адресам.

  1. Измените содержимое веб-страницы, чтобы проверить, что все работает правильно. Для этого вам нужно изменить файл 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. Удачи!