← Kubernetes: Kustomize и Helm
5 мин · просто · Урок 8 из 9

Helm: values-файл вместо --set

Порядок наложения значений, слияние нескольких файлов и правила, по которым Helm сливает словари и списки.

У каждого чарта Helm 3 есть values.yaml с настройками по умолчанию. Переопределяют их двумя способами: флагом --set прямо в команде или отдельным файлом через -f.

Файл со значениями - это обычный YAML той же структуры, что и values.yaml чарта. Класть в него надо только то, что отличается от дефолта:

# myvalues.yaml
replicaCount: 2
image:
  repository: nginx
  tag: "1.25"
resources:
  limits:
    memory: 256Mi

Передаётся при установке или обновлении:

helm install web ./myapp -f myvalues.yaml -n demo

Чтобы понять, какие ключи чарт вообще понимает, смотрят его дефолты:

helm show values ./myapp

Порядок приоритета

Значения накладываются слоями, и каждый следующий слой перекрывает предыдущий:

  1. values.yaml внутри чарта.
  2. Файлы из -f, слева направо.
  3. --set, --set-string, --set-file.

Из этого следует практическое правило: --set перебивает всё, а из нескольких -f побеждает последний.

Несколько файлов используют, чтобы разделить общее и частное:

helm upgrade --install web ./myapp -n demo \
  -f values/common.yaml \
  -f values/prod.yaml

В common.yaml лежит то, что одинаково во всех средах, в prod.yaml только отличия прода. Второй файл ложится поверх первого.

Как именно сливаются значения

Словари сливаются вглубь. Если в common.yaml задан image.repository, а в prod.yaml только image.tag, в итоге останутся оба ключа.

Списки заменяются целиком. Здесь легко ошибиться: массив ingress.hosts из второго файла не добавится к массиву из первого, а вытеснит его. Чтобы получить объединение, список приходится выписывать в верхнем файле полностью.

Удалить ключ, заданный ниже по цепочке, можно присвоив ему null:

# prod.yaml
nodeSelector: null

Это не то же самое, что пустой словарь: null убирает ключ из итогового набора значений, и шаблон увидит его отсутствующим.

Что заданоКак накладываетсяИтог
словарьсливается вглубьостаются ключи из обоих файлов
списокзаменяется целикомверхний файл вытесняет нижний
nullудаляет ключшаблон видит значение отсутствующим

Что реально применилось

Итоговый набор значений релиза показывает helm get values:

helm get values web -n demo        # только переопределения
helm get values web -n demo -a     # полный набор, включая дефолты чарта

Флаг -a особенно полезен при разборе полётов: он отвечает на вопрос, с каким значением приложение реально живёт, вместо догадок по нескольким файлам.

Опечатка в имени ключа проходит молча: схему values Helm по умолчанию не проверяет, и replicasCount: 3 просто ничего не сделает. Часть чартов кладёт рядом values.schema.json, тогда ошибка всплывает сразу, но рассчитывать на это нельзя. Ловится сравнением helm get values -a с тем, что задавали.

Зачем файл, если есть --set

--set хорош для одной-двух правок на лету. Файл выигрывает всё остальное время: он лежит в git рядом с кодом, его читают целиком и по нему видно историю изменений. Команда при этом не превращается в километровый хвост флагов, который потом никто не воспроизведёт.

Что обычно ломается

Тег образа без кавычек парсится как число. tag: 1.25 в YAML это число с плавающей точкой, а Kubernetes ждёт строку. Теги, версии и всё числоподобное пишут в кавычках.

Структура вашего файла обязана повторять структуру values.yaml чарта. Значение, положенное на уровень выше или ниже нужного, не вызовет ошибки и просто останется неиспользованным.

Значения для вложенного чарта живут под его именем: redis.auth.password, а не auth.password. Это частая причина «настройка не применяется» при работе с чартами-зонтиками.

Домашка

Теорию закрепляет задание на своём кластере: 1 шаг с проверкой. Кластер поднимается по треку Kubernetes локально, задания лежат в репозитории k8s-practice.

./run.sh start k8s-helm-values-file     # развернуть стартовое состояние
./run.sh verify k8s-helm-values-file    # проверить текущий шаг

Коротко

Прошли материал до конца? Отметьте урок пройденным.