~/guides/yaml-anchors-kubernetes-configmaps

YAML

YAML-якоря в Kubernetes: как не копировать один и тот же env-блок в двадцать подов

Практическое применение &anchor и *alias в манифестах Kubernetes для DRY-конфигурации без внешних шаблонизаторов вроде Helm.

Deployment, Service и парочка CronJob используют одни и те же переменные окружения, ресурсные лимиты и одинаковые labels. Копипастить этот блок в каждый манифест руками — верный способ через полгода забыть обновить его в одном месте из пяти. Решение лежит прямо в спецификации YAML, и для этого не нужен Helm.

Базовый синтаксис якоря и ссылки

common-env: &common-env
  LOG_LEVEL: info
  REGION: eu-west-1

spec:
  containers:
    - name: api
      env: *common-env

Амперсанд &common-env объявляет якорь — именованную точку в документе, на которую можно сослаться. Звездочка *common-env — это алиас, который подставляет туда содержимое якоря целиком, как если бы вы выписали его вручную.

Слияние через оператор двойного меньше

Просто подставить блок целиком не всегда достаточно — иногда нужно взять базовые поля и добавить к ним что-то специфичное именно для этого пода.

base-resources: &base-resources
  requests:
    cpu: "100m"
    memory: "128Mi"

spec:
  containers:
    - name: worker
      resources:
        <<: *base-resources
        limits:
          cpu: "500m"
          memory: "512Mi"

Оператор <<: мержит поля якоря с остальными ключами того же уровня. Если поле встречается и в якоре, и явно рядом с <<:, явное значение выигрывает.

Конструкция Что делает Где уместно
&name Объявляет якорь На любом значении: скаляр, список, объект
*name Подставляет значение якоря Там, где нужен точно такой же блок
<<: *name Мержит поля якоря с соседними Когда нужен базовый набор + переопределения

Частая ловушка: якорь работает только внутри одного YAML-документа

Если Deployment и ConfigMap лежат в разных файлах, поделиться якорем между ними напрямую не получится — YAML-парсер обрабатывает каждый файл независимо. Собрать оба манифеста в один файл через --- разделитель и держать якорь в первом документе тоже не сработает: большинство инструментов, включая kubectl, обрабатывают каждый документ отдельно даже внутри одного файла.

Если якоря все же расплодились по файлу и хочется увидеть, как это выглядит после полного разворачивания, YAML Anchors & Aliases Resolver покажет итоговый документ без единой ссылки — иногда это единственный способ понять, что реально получит под при деплое.

Когда якорей уже недостаточно

Если общих блоков становится по-настоящему много и они начинают жить в разных файлах, это обычно сигнал, что пора смотреть в сторону Kustomize или Helm — оба инструмента решают ровно эту задачу, но уже на уровне нескольких файлов, а не одного документа. Якоря хороши для одного манифеста с повторами внутри, а не для управления целым набором окружений.

Итоговый чеклист

Якоря и алиасы работают только в пределах одного YAML-документа, не между файлами и не между ----разделенными документами одного файла.

Оператор слияния <<: удобен для базовых полей с точечными переопределениями, обычный алиас *name — для полного дублирования одного и того же блока без изменений.

Перед тем как городить якоря по всему манифесту, стоит прикинуть, не проще ли будет читателю, если Kustomize или Helm возьмут эту работу на себя.