
YAML уже много лет остаётся стандартным способом писать манифесты Kubernetes. Любой пример, туториал и файл конфигурации, которые попадаются на глаза, написаны на нём. Проблема не в том, что YAML — плохой формат. Проблема в том, что YAML даёт множество вариантов, и не все они одинаково хороши для манифестов Kubernetes. Одни возможности делают файлы менее читаемыми, другими легко воспользоваться неправильно, а третьи приводят к неожиданному поведению.
Интересно вот что: большинство этих возможностей Kubernetes не нужны. Он опирается лишь на небольшое подмножество YAML. Отсюда возник простой вопрос: если Kubernetes нужна только малая часть YAML, почему бы не стандартизировать именно эту часть, а остальное не использовать? Вместо того чтобы вводить новый язык конфигурации, SIG CLI представила KYAML, более строгий и последовательный способ писать YAML. А мы в VK Cloud перевели об этом статью.
Что такое KYAM
KYAML — это строгое подмножество (или «диалект») стандартного YAML, спроектированное так, чтобы существующая экосистема разбирала его без изменений, как предложено в KEP 5295. Он не вводит ни нового формата, ни нового парсера. Он лишь сужает набор решений при написании YAML, чтобы в итоге все принимали одни и те же.
Воспринимайте его не столько как новый язык, сколько как согласованный стиль. Всё, что допустимо в KYAML, допустимо и в YAML.
Как KYAML это решает
У стандартного YAML есть несколько известных ловушек. Свои есть и у JSON.
Чувствительность к отступам. В YAML структуру задают отступы, а значит, файл с неправильным отступом может остаться синтаксически корректным, но описывать не тот объект, который задумывался. Особенно болезненно это проявляется с инструментами шаблонизации вроде Helm, где отступами управляют снаружи, вне контекста YAML.
Неявное приведение типов. Кавычки вокруг строк в YAML необязательны, и это звучит удобно ровно до тех пор, пока не перестаёт быть удобным. Некоторые значения, похожие на строки, без предупреждения превращаются в другие типы. Классический пример — «Norway Bug».
country: NO
В стандартном YAML NO читается как булево false, а не как строка "NO", и это застало врасплох не одного человека.
JSON тоже не ответ. Он не поддерживает комментарии, строг к висячим запятым и требует брать в кавычки каждый ключ, и ничто из этого не делает написание конфигов приятным.
KYAML решает всё это, делая структуру и типы явными:
Не полагается на отступы при описании структуры.
Всегда заключает строковые значения в кавычки, поэтому неявного приведения типов не происходит.
Всегда использует
{}для отображений и структур.Всегда использует
[]для списков.Допускает комментарии и висячие запятые, в отличие от JSON.
Содержит заголовок
---, чтобы с первого взгляда отличать его от JSON, поскольку оба начинаются с{.
В YAML это называется потоковым стилем, в отличие от привычного блочного стиля, которым пользуется большинство. KYAML находится посередине между JSON и YAML: он явнее, чем YAML по умолчанию, и дружелюбнее, чем JSON.
Для сравнения вот один и тот же манифест Pod в обоих форматах.
Стандартный YAML
apiVersion: v1 kind: Pod metadata: name: my-pod labels: app: demo spec: containers: - name: nginx image: nginx:1.20
KYAML
--- { apiVersion: "v1", kind: "Pod", metadata: { name: "my-pod", labels: { app: "demo", }, }, spec: { containers: [{ name: "nginx", image: "nginx:1.20", }], }, }
Обратите внимание на строковые значения в двойных кавычках, фигурные скобки вокруг каждого отображения, квадратные скобки вокруг списка и висячие запятые. Дополнительный синтаксис задаёт структуру документа явно, а не через отступы.
Как вывести YAML в формате KYAML
Получить вывод в формате KYAML можно несколькими способами.
Вариант 1: kubectl -o kyaml
Начиная с Kubernetes 1.34 kubectl поддерживает KYAML как нативный формат вывода.
# Kubernetes 1.35+ (beta; возможность включена по умолчанию, но параметр -o kyaml в CLI всё ещё нужен) kubectl get deployment my-app -o kyaml # Kubernetes 1.34 (alpha, включается вручную) export KUBECTL_KYAML=true kubectl get deployment my-app -o kyaml
Чтобы сохранить вывод в файл:
kubectl get deployment my-app -o kyaml > my-app.yaml
Делать KYAML форматом вывода по умолчанию пока не планируется. Если вам удобнее работать с KYAML по умолчанию, задайте нужное значение через kuberc4. Подробности смотрите в документации kuberc.
# Kubernetes 1.36+ kubectl kuberc set --section defaults --command get --option output=kyaml # Kubernetes 1.33–1.35 (префикс alpha всё ещё обязателен) kubectl alpha kuberc set --section defaults --command get --option output=kyaml
Вариант 2: yamlfmt от Kubernetes
Вместе с sigs.k8s.io/yaml поставляется инструмент yamlfmt, который преобразует файлы в KYAML.
Установка через Go:
go install sigs.k8s.io/yaml/yamlfmt@latest
Если запустить его на файле, он выведет KYAML-версию в stdout. Он принимает и каталог: тогда преобразует и выведет каждый файл внутри. Поэтому, чтобы преобразование сохранилось, вывод нужно перенаправить в файл (или файлы).
yamlfmt -o=kyaml my-deployment.yaml
Он также может показать diff вместо полного преобразования:
yamlfmt -o=kyaml -d my-deployment.yaml
Вариант 3: yamlfmt от Google
В версии v0.21.0 у yamlfmt от Google появился отдельный форматтер kyaml для преобразования существующих файлов.
Установите через Go или возьмите бинарник со страницы релизов:
go install github.com/google/yamlfmt/cmd/yamlfmt@latest
Он также доступен как pre-commit хук и как Docker-образ для CI-пайплайнов.
Добавьте конфиг .yamlfmt в корень проекта:
formatter: type: kyaml
Посмотрите результат, не изменяя файл:
yamlfmt -dry my-deployment.yaml
затем примените:
yamlfmt my-deployment.yaml
Чтобы преобразовать целый каталог:
yamlfmt ./k8s/
Форматтер kyaml не принимает дополнительной конфигурации и не имеет общих опций с форматтером по умолчанию, поэтому при смешивании возникнет ошибка.
Подробнее о доступных режимах и флагах смотрите в документации по использованию команд.
Стоит ли переходить на KYAML?
Каждый валидный файл KYAML — это валидный файл YAML. Поэтому, что бы вы ни написали на KYAML, существующим инструментам, kubectl, CI-пайплайнам — ничему из этого не нужно меняться. KYAML можно даже передать на вход любой версии kubectl, а не только 1.34+, потому что в конечном счёте это просто YAML.
KYAML не строго обязателен. Можно и дальше писать YAML в блочном стиле, и всё будет работать. Но это осознанный выбор: сделать конфиги устойчивее к ошибкам и последовательнее, особенно в команде или большом репозитории.
Это не столько миграция, сколько более удачная привычка.

