Kustomize: трансформеры
namePrefix, labels, namespace и подмена образа: правки, которые накрывают всю группу ресурсов сразу.
Собрать манифесты в группу мало. Обычно к ним нужно применить одинаковую правку: дописать префикс ко всем именам, навесить общий label, отправить всё в другой namespace, подменить тег образа сразу везде.
Трансформер - это правило в kustomization.yaml, которое Kustomize применяет ко всем ресурсам группы при сборке. Исходные манифесты при этом не меняются ни на байт, правка живёт только в конфигурации Kustomize и появляется в отрендеренном выводе.
| Поле | Что накрывает | Тонкость |
|---|---|---|
namePrefix, nameSuffix | имена всех ресурсов | ссылки чинит только в известных полях |
namespace | namespace всех ресурсов | перебивает то, что записано в файлах |
commonLabels | метаданные и селекторы | на живом Deployment ошибка про immutable |
labels | метаданные, селекторы по выбору | includeSelectors: false селекторы не трогает |
images | имя, тег или digest образа | строка образа сопоставляется буквально |
namePrefix и nameSuffix
namePrefix дописывает строку в начало имени каждого ресурса, nameSuffix в конец.
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- deployment.yaml
- service.yaml
namePrefix: prod-
Deployment web станет prod-web, Service web станет prod-web. Это нужно, когда одно приложение живёт в нескольких экземплярах в одном namespace и имена не должны сталкиваться.
Важная деталь: Kustomize не просто переименовывает объекты, он ещё чинит ссылки между ними в известных ему полях. Если Ingress ссылался на Service web, после префикса в Ingress окажется prod-web. То же самое с ConfigMap в envFrom и в томах.
namespace
Поле namespace проставляет один namespace всем ресурсам группы:
namespace: demo
После этого kubectl apply -k . уложит объекты в demo, даже если в самих файлах namespace не указан или указан другой. Удобно держать манифесты без привязки к namespace, а адрес назначения задавать конфигурацией.
Общие labels и annotations
commonLabels вешает пары ключ-значение на все объекты группы:
commonLabels:
team: platform
app.kubernetes.io/part-of: shop
Тут прячется главная ловушка Kustomize. commonLabels пишет label и в metadata.labels, и в селекторы: spec.selector у Deployment, spec.selector у Service, spec.template.metadata.labels у Pod-шаблона. У уже созданного Deployment селектор менять нельзя, поле неизменяемое, и API-сервер откажет с ошибкой про immutable field. На свежем ресурсе всё пройдёт нормально.
Поэтому в новых версиях Kustomize commonLabels объявлен устаревшим, а на замену пришёл блок labels, где поведение задаётся явно:
labels:
- pairs:
team: platform
includeSelectors: false
С includeSelectors: false label попадёт только в метаданные и селекторы не тронет. commonLabels продолжает работать и встречается в большинстве чужих репозиториев, так что знать обе формы полезно.
Аннотации навешивает commonAnnotations. Селекторов у аннотаций нет, поэтому проблемы с неизменяемыми полями там не возникает.
Подмена образа
Блок images меняет образ контейнера, не трогая Deployment:
images:
- name: nginx
newTag: "1.25"
Kustomize найдёт контейнеры, у которых образ называется nginx, и поставит им тег 1.25. Можно заменить и сам образ:
images:
- name: nginx
newName: registry.example.com/mirror/nginx
newTag: "1.25"
- name: busybox
digest: sha256:9ae97d36d26566ff84e8893c64a6dc4fe8ca6d1144bf5b87b2b85a32def253c7
digest ставится вместо тега, если нужна привязка к конкретному слепку образа. Одновременно указывать newTag и digest нельзя.
Это самый частый трансформер в реальной работе. При выкатке новой версии CI правит одну строку в kustomization.yaml вместо поиска тега по всем манифестам.
Сопоставление идёт по строке образа ровно так, как она записана в
манифесте. Для docker.io/library/nginx:1.24 правило с name: nginx
молча не сработает, нужно полное name: docker.io/library/nginx.
Что обычно ломается
namePrefix чинит ссылки только в тех полях, про которые Kustomize знает. Имя Service, зашитое строкой в переменную окружения или в текст ConfigMap, останется старым. Такие места приходится править патчем или брать имя из downward API.
commonLabels на живом Deployment даёт ошибку про неизменяемый селектор. Лечится либо переходом на labels с includeSelectors: false, либо пересозданием ресурса.
Порядок полей в kustomization.yaml роли не играет, а вот порядок применения трансформеров фиксирован самим Kustomize. Проверять результат надёжнее не рассуждениями, а рендером: kubectl kustomize . покажет итог целиком.
Домашка
Теорию закрепляет задание на своём кластере: 1 шаг с проверкой. Кластер поднимается по треку Kubernetes локально, задания лежат в репозитории k8s-practice.
./run.sh start k8s-kustomize-transformers # развернуть стартовое состояние
./run.sh verify k8s-kustomize-transformers # проверить текущий шаг
Коротко
- Трансформер меняет всю группу ресурсов правкой в
kustomization.yaml, исходные файлы остаются нетронутыми. namePrefixиnameSuffixправят имена и чинят ссылки между объектами в известных полях.namespaceпроставляет один namespace всем объектам группы.commonLabelsлезет в селекторы и падает на живом Deployment; новый блокlabelsсincludeSelectors: falseэтого избегает.imagesподменяет тег, имя или digest образа, сопоставляя строку образа буквально.
Прошли материал до конца? Отметьте урок пройденным.
Прогресс сохранён в этом браузере
Почистишь историю или откроешь с телефона, и отметки пропадут. Оставь почту, они переедут в аккаунт. Пароль придумывать не нужно.
Готово. теперь в аккаунте: прогресс виден с любого устройства. Мой прогресс