Перейти до вмісту

Модуль 2.3: Kustomize

Hands-On Lab Available
K8s Cluster intermediate 30 min
Launch Lab ↗

Opens in Killercoda in a new tab

Складність: [MEDIUM] — кастомізація Kubernetes без шаблонів

Час на виконання: 40–50 хвилин

Передумови: Модуль 2.1 (Деплойменти), базове розуміння YAML


Що ви зможете робити

Розділ «Що ви зможете робити»

Після завершення цього модуля ви зможете:

  • Побудувати оверлеї Kustomize, що кастомізують базові ресурси для різних середовищ
  • Застосувати патчі та трансформації за допомогою kubectl apply -k без модифікації оригінального YAML
  • Порівняти Kustomize та Helm і обрати правильний інструмент для конкретного сценарію розгортання
  • Діагностувати проблеми рендерингу Kustomize за допомогою kubectl kustomize для попереднього перегляду результату

Чому цей модуль важливий

Розділ «Чому цей модуль важливий»

Kustomize дозволяє кастомізувати ресурси Kubernetes без шаблонів. Замість змінних і логіки (як у Helm) Kustomize використовує оверлеї та патчі для модифікації базових конфігурацій. Він вбудований у kubectl (kubectl apply -k), що робить його зручним для іспиту.

CKAD тестує Kustomize для:

  • Створення та застосування кастомізацій
  • Використання оверлеїв для різних середовищ
  • Патчінг ресурсів
  • Керування ConfigMaps та Secrets

Аналогія з наклейками

Уявіть, що купуєте ноутбук. Базовий ноутбук (базові ресурси) однаковий для всіх. Але ви додаєте наклейки, скіни та аксесуари (оверлеї), щоб зробити його своїм. Ви не перебудовуєте ноутбук — ви його кастомізуєте. Kustomize працює так само: зберігайте базові ресурси Kubernetes чистими, а потім застосовуйте оверлеї для dev/staging/prod.


КонцепціяОпис
BaseОригінальні, немодифіковані ресурси Kubernetes
OverlayКастомізації, що накладаються поверх бази
PatchМодифікації конкретних полів
kustomization.yamlФайл, що визначає, що кастомізувати
┌─────────────────────────────────────────────────────────┐
│ Потік Kustomize │
├─────────────────────────────────────────────────────────┤
│ │
│ База Оверлей │
│ ┌─────────────┐ ┌─────────────┐ │
│ │ deployment │───────▶│ + репліки │ │
│ │ service │ │ + env vars │ │
│ │ configmap │ │ + мітки │ │
│ └─────────────┘ └─────────────┘ │
│ │ │ │
│ └─────────┬───────────┘ │
│ ▼ │
│ ┌─────────────┐ │
│ │ Об'єднані │ │
│ │ ресурси │ │
│ └─────────────┘ │
│ │ │
│ ▼ │
│ kubectl apply -k ./ │
│ │
└─────────────────────────────────────────────────────────┘

Створення кастомізації

Розділ «Створення кастомізації»
my-app/
├── kustomization.yaml
├── deployment.yaml
└── service.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- deployment.yaml
- service.yaml

Застосування через kubectl

Розділ «Застосування через kubectl»
Terminal window
# Попередній перегляд того, що буде застосовано
kubectl kustomize ./my-app/
# Застосувати кастомізацію
kubectl apply -k ./my-app/
# Видалити ресурси
kubectl delete -k ./my-app/

Типові трансформації

Розділ «Типові трансформації»

Додати мітки до всіх ресурсів

Розділ «Додати мітки до всіх ресурсів»
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- deployment.yaml
- service.yaml
commonLabels:
app: my-app
environment: production
commonAnnotations:
owner: team-platform
managed-by: kustomize

Додати префікс/суфікс до імені

Розділ «Додати префікс/суфікс до імені»
namePrefix: prod-
nameSuffix: -v1

Результат: deployment стає prod-deployment-v1

Встановити простір імен

Розділ «Встановити простір імен»
namespace: production

Усі ресурси будуть розгорнуті в цьому просторі імен.


apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- deployment.yaml
configMapGenerator:
- name: app-config
literals:
- LOG_LEVEL=info
- API_URL=http://api.example.com

Генерація ConfigMap з файлів

Розділ «Генерація ConfigMap з файлів»
configMapGenerator:
- name: app-config
files:
- config.properties
- settings.json
secretGenerator:
- name: db-credentials
literals:
- username=admin
- password=secret123
# Або з файлів
secretGenerator:
- name: tls-certs
files:
- tls.crt
- tls.key
type: kubernetes.io/tls

Поведінка ConfigMap/Secret

Розділ «Поведінка ConfigMap/Secret»

За замовчуванням Kustomize додає хеш-суфікс до згенерованих ConfigMaps/Secrets:

  • app-config стає app-config-abc123
  • Посилання оновлюються автоматично

Вимкнути:

generatorOptions:
disableNameSuffixHash: true

Перевизначення тегів образів

Розділ «Перевизначення тегів образів»
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- deployment.yaml
images:
- name: nginx
newTag: "1.21"
- name: myapp
newName: my-registry.com/myapp
newTag: v2.0.0

Додавання або модифікація полів:

apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- deployment.yaml
patches:
- patch: |-
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app
spec:
replicas: 5
patches:
- path: increase-replicas.yaml

increase-replicas.yaml:

apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app
spec:
replicas: 5

Для точних модифікацій:

patches:
- target:
kind: Deployment
name: my-app
patch: |-
- op: replace
path: /spec/replicas
value: 5
- op: add
path: /metadata/labels/version
value: v2

Патч для всіх Деплойментів

Розділ «Патч для всіх Деплойментів»
patches:
- target:
kind: Deployment
patch: |-
- op: add
path: /spec/template/spec/containers/0/resources
value:
limits:
memory: 256Mi
cpu: 200m

Структура каталогів

Розділ «Структура каталогів»
my-app/
├── base/
│ ├── kustomization.yaml
│ ├── deployment.yaml
│ └── service.yaml
├── overlays/
│ ├── dev/
│ │ └── kustomization.yaml
│ ├── staging/
│ │ └── kustomization.yaml
│ └── prod/
│ └── kustomization.yaml
base/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- deployment.yaml
- service.yaml
overlays/dev/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- ../../base
namePrefix: dev-
namespace: development
patches:
- patch: |-
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app
spec:
replicas: 1
images:
- name: my-app
newTag: dev-latest
overlays/prod/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- ../../base
namePrefix: prod-
namespace: production
patches:
- patch: |-
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app
spec:
replicas: 5
images:
- name: my-app
newTag: v1.2.3
configMapGenerator:
- name: app-config
literals:
- LOG_LEVEL=warn
- ENABLE_DEBUG=false

Застосування оверлеїв

Розділ «Застосування оверлеїв»
Terminal window
# Застосувати dev
kubectl apply -k overlays/dev/
# Застосувати prod
kubectl apply -k overlays/prod/
# Попередній перегляд
kubectl kustomize overlays/prod/

Швидкий довідник для іспиту

Розділ «Швидкий довідник для іспиту»
Terminal window
# Попередній перегляд кастомізації
kubectl kustomize ./
# Застосувати кастомізацію
kubectl apply -k ./
# Видалити кастомізацію
kubectl delete -k ./
# Переглянути конкретний оверлей
kubectl kustomize overlays/prod/

Мінімальний kustomization.yaml

Розділ «Мінімальний kustomization.yaml»
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- deployment.yaml

Типові кастомізації

Розділ «Типові кастомізації»
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- deployment.yaml
- service.yaml
namespace: my-namespace
namePrefix: prod-
commonLabels:
app: my-app
images:
- name: nginx
newTag: "1.21"
configMapGenerator:
- name: config
literals:
- KEY=value

  • Kustomize вбудований у kubectl починаючи з версії 1.14. Вам не потрібно встановлювати нічого додаткового — просто використовуйте kubectl apply -k.

  • Хеш-суфікси на ConfigMaps/Secrets забезпечують поширення оновлень. Коли вміст змінюється, хеш змінюється, створюючи новий ConfigMap. Деплойменти, що на нього посилаються, автоматично оновлюються.

  • Kustomize проти Helm: Kustomize простіший (без шаблонів, без змінних), тоді як Helm потужніший (умови, цикли, пакування). Використовуйте Kustomize для простих оверлеїв; Helm — для складних застосунків.


ПомилкаЧому це шкодитьРішення
Неправильний шлях до базиРесурси не знайденіВикористовуйте відносні шляхи (../../base)
Невідповідність імені цілі патчуПатч не застосовуєтьсяЗбігайте точне ім’я ресурсу
Відсутній apiVersion у kustomizationНедійсний файлЗавжди вказуйте версію
Забули секцію resourcesНічого не розгорнутоПерелічіть усі файли ресурсів
Не переглянули перед застосуваннямНесподівані результатиЗавжди спочатку виконуйте kubectl kustomize

  1. Як застосувати каталог Kustomize?

    Відповідь `kubectl apply -k ./directory/`

    Прапорець -k вказує kubectl обробити kustomization.yaml у цьому каталозі.

  2. Як додати префікс до всіх імен ресурсів?

    Відповідь Додайте `namePrefix: prefix-` до kustomization.yaml. Усі ресурси отримають цей префікс до своїх імен.
  3. Яка різниця між base та overlay?

    Відповідь Base містить оригінальні, немодифіковані ресурси. Overlay посилається на base та додає кастомізації (інша кількість реплік, простори імен, мітки) для конкретних середовищ, таких як dev/staging/prod.
  4. Як перевизначити тег образу?

    Відповідь ```yaml images: - name: nginx newTag: "1.21" ``` Це змінює всі посилання на `nginx`, щоб використовувати тег `1.21`.

Завдання: Створити повну конфігурацію Kustomize з базою та оверлеями.

Частина 1: Створення бази

Terminal window
mkdir -p /tmp/kustomize-demo/base
cd /tmp/kustomize-demo
# Створити деплоймент
cat << 'EOF' > base/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-app
spec:
replicas: 1
selector:
matchLabels:
app: web
template:
metadata:
labels:
app: web
spec:
containers:
- name: nginx
image: nginx:1.20
ports:
- containerPort: 80
EOF
# Створити сервіс
cat << 'EOF' > base/service.yaml
apiVersion: v1
kind: Service
metadata:
name: web-app
spec:
selector:
app: web
ports:
- port: 80
EOF
# Створити базову кастомізацію
cat << 'EOF' > base/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- deployment.yaml
- service.yaml
EOF

Частина 2: Створення Dev-оверлею

Terminal window
mkdir -p overlays/dev
cat << 'EOF' > overlays/dev/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- ../../base
namePrefix: dev-
namespace: development
images:
- name: nginx
newTag: "1.21"
configMapGenerator:
- name: app-config
literals:
- ENV=development
- DEBUG=true
EOF

Частина 3: Створення Prod-оверлею

Terminal window
mkdir -p overlays/prod
cat << 'EOF' > overlays/prod/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- ../../base
namePrefix: prod-
namespace: production
patches:
- patch: |-
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-app
spec:
replicas: 3
images:
- name: nginx
newTag: "1.22"
configMapGenerator:
- name: app-config
literals:
- ENV=production
- DEBUG=false
EOF

Частина 4: Попередній перегляд та застосування

Terminal window
# Попередній перегляд dev
kubectl kustomize overlays/dev/
# Попередній перегляд prod
kubectl kustomize overlays/prod/
# Застосувати dev (спочатку створити простір імен)
kubectl create ns development
kubectl apply -k overlays/dev/
# Перевірити
kubectl get all -n development
# Очищення
kubectl delete -k overlays/dev/
kubectl delete ns development

Вправа 1: Базова кастомізація (Ціль: 3 хвилини)

Розділ «Вправа 1: Базова кастомізація (Ціль: 3 хвилини)»
Terminal window
mkdir -p /tmp/drill1 && cd /tmp/drill1
# Створити деплоймент
cat << 'EOF' > deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
spec:
replicas: 1
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx
EOF
# Створити кастомізацію
cat << 'EOF' > kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- deployment.yaml
namespace: default
commonLabels:
environment: test
EOF
# Попередній перегляд
kubectl kustomize ./
# Застосувати
kubectl apply -k ./
# Очищення
kubectl delete -k ./

Вправа 2: Перевизначення образу (Ціль: 2 хвилини)

Розділ «Вправа 2: Перевизначення образу (Ціль: 2 хвилини)»
Terminal window
mkdir -p /tmp/drill2 && cd /tmp/drill2
cat << 'EOF' > deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: app
spec:
selector:
matchLabels:
app: app
template:
metadata:
labels:
app: app
spec:
containers:
- name: app
image: nginx:1.19
EOF
cat << 'EOF' > kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- deployment.yaml
images:
- name: nginx
newTag: "1.22"
EOF
# Перевірити, що образ змінився
kubectl kustomize ./ | grep image
# Очищення
cd /tmp && rm -rf drill2

Вправа 3: Генератор ConfigMap (Ціль: 3 хвилини)

Розділ «Вправа 3: Генератор ConfigMap (Ціль: 3 хвилини)»
Terminal window
mkdir -p /tmp/drill3 && cd /tmp/drill3
cat << 'EOF' > deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: app
spec:
selector:
matchLabels:
app: app
template:
metadata:
labels:
app: app
spec:
containers:
- name: app
image: nginx
envFrom:
- configMapRef:
name: app-config
EOF
cat << 'EOF' > kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- deployment.yaml
configMapGenerator:
- name: app-config
literals:
- DATABASE_URL=postgres://localhost
- LOG_LEVEL=debug
EOF
# Попередній перегляд — зверніть увагу на хеш-суфікс
kubectl kustomize ./
# Очищення
cd /tmp && rm -rf drill3

Вправа 4: Патчі (Ціль: 4 хвилини)

Розділ «Вправа 4: Патчі (Ціль: 4 хвилини)»
Terminal window
mkdir -p /tmp/drill4 && cd /tmp/drill4
cat << 'EOF' > deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: web
spec:
replicas: 1
selector:
matchLabels:
app: web
template:
metadata:
labels:
app: web
spec:
containers:
- name: nginx
image: nginx
EOF
cat << 'EOF' > kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- deployment.yaml
patches:
- patch: |-
apiVersion: apps/v1
kind: Deployment
metadata:
name: web
spec:
replicas: 3
template:
spec:
containers:
- name: nginx
resources:
limits:
memory: 128Mi
cpu: 100m
EOF
# Перевірити, що патч застосовано
kubectl kustomize ./
# Очищення
cd /tmp && rm -rf drill4

Вправа 5: Префікс імені та простір імен (Ціль: 2 хвилини)

Розділ «Вправа 5: Префікс імені та простір імен (Ціль: 2 хвилини)»
Terminal window
mkdir -p /tmp/drill5 && cd /tmp/drill5
cat << 'EOF' > deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: app
spec:
selector:
matchLabels:
app: app
template:
metadata:
labels:
app: app
spec:
containers:
- name: nginx
image: nginx
EOF
cat << 'EOF' > kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- deployment.yaml
namePrefix: staging-
namespace: staging
commonLabels:
env: staging
EOF
# Перевірити трансформації
kubectl kustomize ./
# Очищення
cd /tmp && rm -rf drill5

Вправа 6: Повний сценарій з оверлеями (Ціль: 6 хвилин)

Розділ «Вправа 6: Повний сценарій з оверлеями (Ціль: 6 хвилин)»
Terminal window
mkdir -p /tmp/drill6/{base,overlays/dev,overlays/prod}
cd /tmp/drill6
# База
cat << 'EOF' > base/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: api
spec:
replicas: 1
selector:
matchLabels:
app: api
template:
metadata:
labels:
app: api
spec:
containers:
- name: api
image: my-api:latest
ports:
- containerPort: 8080
EOF
cat << 'EOF' > base/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- deployment.yaml
EOF
# Dev-оверлей
cat << 'EOF' > overlays/dev/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- ../../base
namePrefix: dev-
namespace: dev
images:
- name: my-api
newTag: dev-latest
EOF
# Prod-оверлей
cat << 'EOF' > overlays/prod/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- ../../base
namePrefix: prod-
namespace: prod
images:
- name: my-api
newTag: v1.0.0
patches:
- patch: |-
apiVersion: apps/v1
kind: Deployment
metadata:
name: api
spec:
replicas: 3
EOF
# Порівняти виведення
echo "=== DEV ===" && kubectl kustomize overlays/dev/
echo "=== PROD ===" && kubectl kustomize overlays/prod/
# Очищення
cd /tmp && rm -rf drill6

Модуль 2.4: Стратегії деплойменту — патерни blue/green, canary та ковзного розгортання.