Перейти к основному содержимому

YAML

Разработчику Аналитику Тестировщику
Архитектору Инженеру


YAML

Основы YAML

YAML (YAML Ain’t Markup Language) — формат сериализации данных, предназначенный для хранения и передачи информации. Он отличается высокой читаемостью и простотой использования, что делает его популярным выбором для конфигурационных файлов, настроек приложений и обмена данными.

Тот же смысл, что в примерах конфигурационных данных, в YAML записывается короче, чем в XML, и удобнее для правки руками, чем JSON. Сравнение форматов — в конце главы JSON. Типовой учебный файл — docker-compose.yml; готовые стеки с построчным разбором — Docker Compose — готовые стеки; сборка образа для build:Dockerfile — 10 типовых образов.


Синтаксис

Правила синтаксиса YAML:

  • Вместо фигурных скобок ({}) и квадратных скобок ([]) из JSON YAML использует отступы для вложенности объектов и списков;
  • Отступы должны быть пробелами, а не табуляцией;
  • Табуляция запрещена в YAML;
  • Ключи и значения разделяются двоеточием (:), за которым следует пробел.
  • Значения без кавычек считаются строками;
  • Целые и дробные числа пишутся без кавычек;
  • Логические значения - true или false;
  • Нулевые значения - null;
  • Элементы списка начинаются с дефиса (-), за которым следует пробел;
  • Вложенные объекты создаются с помощью отступов;
  • Для многострочных строк используются символы | (сохраняет переносы строк) или > (объединяет строки);
  • Комментарии начинаются с символа #.

Play ITЗагрузка интерактивного демо…

Чит-лист - https://cheatsheets.zip/yaml

Пример обычного словаря:

name: Alice
age: 25

Пример списка (упорядоченной коллекции элементов):

fruits:
- apple
- banana
- cherry

Пример вложенной структуры (сочетания словарей и списков):

server:
host: localhost
port: 8080
users:
- name: Alice
role: admin
- name: Bob
role: user

YAML применяется для конфигурационных файлов. Пример, в Docker Compose:

version: '3'
services:
web:
image: nginx
ports:
- "80:80"
db:
image: postgres
environment:
POSTGRES_PASSWORD: example


Составление YAML-манифестов

Составление манифестов строится на строгом соблюдении структуры отступов, использовании пар «ключ — значение» и понимании схемы конкретного инструмента — например, Kubernetes или Ansible. YAML чрезвычайно чувствителен к пробелам: малейшая ошибка в форматировании сделает манифест невалидным. Ниже — фундаментальные правила и пошаговый процесс написания; интерактивный разбор — в блоке YAML-манифесты выше.

Базовые правила синтаксиса

Правила из раздела Синтаксис для манифестов сводятся к четырём обязательным привычкам:

  • Отступы только пробелами — табуляция (Tab) строго запрещена. Используйте 2 или 4 пробела на каждый уровень вложенности и не смешивайте ширину в одном файле.
  • Регистрозависимость — ключи Name, name и NAME — три разных поля; в Kubernetes поле kind: Pod и kind: pod — не одно и то же.
  • Разделение документов — несколько манифестов в одном файле разделяют строкой --- (см. раздел Несколько документов в одном файле ниже).
  • Комментарии — начинаются с # и не влияют на разбор, но помогают сопровождать конфиг.

Основные структуры данных

Манифест состоит из трёх типов элементов.

Скаляры (ключ: значение) — строки, числа, булевы значения:

name: "web-server"
port: 80
enabled: true

Словари (объекты) — группы связанных параметров с отступом:

metadata:
name: production-app
namespace: default

Списки (массивы) — каждый элемент начинается с - и пробела:

args:
- "--verbose"
- "--log-level=debug"

Пример: манифест Pod (Kubernetes)

Чаще всего манифесты пишут для оркестрации контейнеров. Базовый манифест Pod включает четыре обязательных блока:

# 1. Версия API инструмента
apiVersion: v1

# 2. Тип создаваемого ресурса (регистр важен!)
kind: Pod

# 3. Метаданные — имя, ярлыки, пространство имён
metadata:
name: nginx-demo
labels:
tier: frontend

# 4. Спецификация — что именно должно работать
spec:
containers:
- name: nginx-container
image: nginx:1.25
ports:
- containerPort: 80

Подробнее о ресурсах кластера — в справочнике по Kubernetes.

Пошаговый алгоритм

  1. Определите целевую схему — узнайте, какие ключи поддерживает платформа. Для Kubernetes: kubectl explain <resource> (например, kubectl explain pod.spec) показывает структуру полей.
  2. Не пишите с нуля — генерируйте базовые шаблоны. Пустой манифест Pod можно выгрузить так:
kubectl run nginx --image=nginx --dry-run=client -o yaml > pod.yaml
  1. Проверяйте линтерами — перед применением прогоняйте файл через yamllint, YAML Lint или встроенные плагины IDE; для Kubernetes — kubeconform или kubeval (см. раздел Проверка файла ниже).
  2. Экранируйте спецсимволы — строки с двоеточием, &, * или логическими операторами оборачивайте в кавычки: message: "Error: failed to connect".

Helm и Kustomize

Для больших проектов манифесты часто шаблонизируют или накладывают слоями под разные окружения (dev, stage, prod). Два самых популярных инструмента в экосистеме Kubernetes решают эту задачу по-разному: Helm — шаблонизация текста ({{ .Values.replicaCount }}), Kustomize — патчи поверх «чистого» YAML без шаблонного синтаксиса. Подробный разбор с примерами — в Реализации Kubernetes.

Helm упаковывает YAML в Chart (чарт): переменные — в values.yaml, манифесты — в templates/ с подстановкой при деплое.

my-app/
Chart.yaml # имя и версия чарта
values.yaml # переменные по умолчанию
templates/ # YAML-шаблоны с {{ ... }}
deployment.yaml
service.yaml

Плюсы: история релизов и откат (helm rollback), готовые чарты из Artifact Hub, условия и циклы в шаблонах. Минусы: YAML в templates/ труднее читать и отлаживать.

Kustomize не использует шаблоны. Базовые манифесты лежат в base/, для каждого окружения — overlay в overlays/, собираемый через kustomization.yaml. Встроен в kubectl apply -k ./overlays/prod.

├── base/
│ ├── deployment.yaml
│ └── kustomization.yaml
└── overlays/
├── dev/
│ └── kustomization.yaml # например, replicas: 1
└── prod/
└── kustomization.yaml # replicas: 5, лимиты памяти

Плюсы: файлы остаются валидным YAML, проще code review, не нужна отдельная утилита. Минусы: нет условий и циклов, нет встроенной истории релизов.

КритерийHelmKustomize
ПодходШаблонизация ({{ ... }})Патчи и наложение слоёв
УстановкаОтдельная утилита helmВстроен в kubectl (ключ -k)
Чужой софт из репозиторияИдеально (готовые чарты)Слабее
Условия и циклыДаНет
История релизовДаНет

Helm — если пакетируете приложение для других людей или деплоите популярный open-source со своими values. Kustomize — если структура своего приложения одинакова, а между dev и prod отличаются реплики, лимиты и секреты. На практике часто комбинируют: Helm для упаковки и релизов, Kustomize — для финальной настройки под конкретный кластер.


Многострочные строки — | и >

СимволПоведениеКогда использовать
| (literal)Сохраняет переводы строкЛоги, SQL, сертификаты PEM
> (folded)Переносы превращаются в пробелы (кроме пустой строки)Длинные абзацы текста
sql: |
SELECT id, name
FROM users
WHERE active = true;

description: >
Это один абзац,
разбитый на несколько строк
в исходнике.

Алиасы и якоря (& и *)

Повторяющийся фрагмент можно описать один раз и сослаться на него — удобно в Ansible и больших Compose-файлах:

defaults: &app_defaults
restart: unless-stopped
logging:
driver: json-file

services:
web:
<<: *app_defaults
image: nginx:alpine
api:
<<: *app_defaults
image: my-api:1.0

&app_defaultsякорь (имя узла), *app_defaultsссылка на тот же объект, &lt;&lt;: — слияние ключей (расширение YAML 1.1, поддерживается многими парсерами).


Несколько документов в одном файле

Разделитель --- начинает новый YAML-документ в том же файле (потоковый YAML):

---
theme: dark
specialMode: true
---
# второй документ — например, другой профиль
theme: light
specialMode: false

Парсер должен читать все документы по очереди, а не только первый.


Типичные ловушки

ЗаписьРиск
enabled: yes / onВ YAML 1.1 некоторые парсеры превращают в true
version: 3.10Может стать числом 3.1, а не строкой "3.10"
port: 08080В старых парсерах ведущий 0 — восьмеричное число
Смешение табов и пробелов в отступахСинтаксическая ошибка или "тихий" сдвиг уровня
Не заключённая в кавычки строка #комментарий# начинает комментарий — обрыв значения

Безопасная привычка — версии и коды, где важны ведущие нули, писать в кавычках: version: "3.10", port: "08080".

# Явные типы через кавычки
version: "3.10"
build: "00142"
enabled: "yes" # строка, не boolean

Тот же конфиг, что в JSON (из раздела "Конфигурации")

theme: dark
specialMode: true
defaultPath: C:/Users/Timur/Documents/Backup

С комментариями для сопровождения:

# Настройки интерфейса
theme: dark
specialMode: true
defaultPath: C:/Users/Timur/Documents/Backup

Чтение YAML в коде

Python (безопасный разбор — только базовые типы):


import yaml

with open("config.yaml", encoding="utf-8") as f:
config = yaml.safe_load(f)

print(config["theme"]) # dark

yaml.load() без ограничений может выполнить произвольные объекты из файла — в конфигах используйте safe_load.


Проверка файла

Локально часто применяют yamllint (синтаксис и стиль отступов) и схемы Kubernetes (kubeconform, kubeval) для манифестов. Ошибка обычно указывает номер строки — как у JSON-парсера.


Сравнение с JSON

КритерийYAMLJSON
Комментарии#Нет в RFC
ВложенностьОтступы{} / []
Один кореньОдин или несколько документов (---)Один объект или массив
Подводные камниОтступы, неявные типыTrailing comma, одинарные кавычки

Публичный HTTP API почти всегда отдаёт JSON; деплой и инфраструктура — часто YAML.


По YAML с документацией чуть более скудно, поэтому, чтобы углубиться в этот формат, в первую очередь следует ознакомиться с официальным сайтом YAML - https://yaml.org/

Спецификация: https://yaml.org/spec/1.2.2/


Практическое задание
  1. Перепишите JSON из главы JSON (профиль пользователя или appsettings) в YAML.
  2. Добавьте комментарий # к двум полям.
  3. Создайте список из трёх элементов с дефисом -.
  4. Проверьте файл в демо выше или через yamllint.
  5. Намеренно смешайте таб и пробел в отступе — убедитесь, что парсер ругается.
  6. Запишите version: 3.10 без кавычек и с кавычками — сравните тип в вашем парсере.
  7. Соберите минимальный манифест Pod по образцу из раздела Составление YAML-манифестов и проверьте его через kubectl apply --dry-run=client -f pod.yaml (если есть доступ к кластеру).

Основа по протоколу

Базовый разбор HTTP и HTTPS находится в отдельной статье — HTTP как основа веб-интеграций.