跳到主内容
d.devtul.fun
EN
配置 · 2026-08-10

什么是 YAML?写给开发者的入门说明

大多数开发者接触到 YAML,都不是自己主动选的。一个 Kubernetes 的 manifest、一份 docker-compose.yml、一条 GitHub Actions 的流水线、一个 Ansible playbook —— 不知不觉你就在改一份"缩进有含义、少一个空格部署就崩"的文件了。这篇入门,是我希望当初有人先递给我的东西。

那些你没选 YAML、却已经遇到它的地方

凡是"需要人经常手读、手改"的配置,YAML 几乎都成了默认格式:

  • Kubernetes:每个对象(Pod、Service、Deployment)都用 YAML manifest 描述,然后用 kubectl apply -f 应用。
  • Docker Compose:多容器环境都写在单个 docker-compose.yml 里。
  • CI 流水线:GitHub Actions、GitLab CI、CircleCI 几乎都是 YAML。
  • Ansible:playbook 就是用 YAML 写的。

背后的逻辑是一致的:这些配置文件需要被人打开、修改、在 Pull Request 里评审。而 YAML 正是为这类读者设计的。

YAML 到底想成为什么

这个名字最早是 "Yet Another Markup Language",后来改口成 "YAML Ain't Markup Language",为的是强调它是数据格式、不是文档格式。它的设计目标很朴素:先让人读得懂,再让机器解析得动。JSON 把解析器的便利放在第一位,YAML 把盯着 diff 看到半夜的人放在第一位。

这个目标解释了你将遇到的所有怪癖:省掉的引号和花括号、缩进的含义、隐式类型推断。这一切都是拿"机器的严格"去换"人的舒服"。

YAML 是 JSON 的超集

任何合法的 JSON 文档,同时也是合法的 YAML。先看一段 JSON:

{
  "name": "devtul",
  "replicas": 3,
  "ports": [8080, 8443]
}

同样的数据用 YAML 写,花括号、逗号、大部分引号都没了:

name: devtul
replicas: 3
ports:
  - 8080
  - 8443

既然是超集,你可以直接把 JSON 粘进 YAML 文件里,它照样能解析。这很方便,但也意味着两种格式共享同一套底层数据模型 —— 差异几乎全在语法上。

YAML 1.1 和 1.2 —— 为什么你的 yes/no 表现不一样

这是最容易被低估的、跨工具混乱的根源。这个规范有两个被广泛部署的版本。

写法YAML 1.1YAML 1.2
yes / no / on / off布尔值字符串(只有 true/false 算布尔)
12:30秒数(750)不加引号就是字符串
~空值空值
八进制0777只认 0o777

举个例子,Kubernetes 通过 Go 解析器走的是 1.1 的语义,所以 replicas: off 会被解析成布尔值 false;而基于 1.2 解析器的工具会把它保留成字符串 "off"。同一个文件,两种值,还不报错。拿不准的东西,一律加引号。

四块积木

每份 YAML 文档都由四样东西组成:

  • 映射(mapping):键值集合,写成 key: value。
  • 序列(sequence):有序列表,用 - 短横线表示。
  • 标量(scalar):单个值,可以是字符串、数字、布尔或空。
  • 注释(comment):# 之后的内容,解析器忽略。

当映射的值本身又是映射或序列时,就得到了你在每个 Kubernetes manifest 里看到的嵌套结构。

YAML 怎么靠符号和缩进来推断类型

YAML 几乎没有任何关键字,类型全靠上下文推断:

count: 3          # 整数
ratio: 1.5        # 浮点
flag: true        # 布尔
name: devtul      # 字符串
note: "3"         # 字符串,因为加了引号
empty:            # 空
empty2: ~         # 也是空

这种推断方式,正是 YAML 写起来舒服、信起来危险的地方。同一行到底是啥,取决于你是否加了引号、缩进怎么写、以及谁来解析它。这就是这个格式的核心取舍。

几乎人人都会踩的三个坑

一、缩进不是装饰

YAML 用缩进表达层级。混用空格和 Tab,或者缩进"错"了几格,都会改变结构甚至直接报错。统一用两个空格,永远别用 Tab。

二、冒号后面必须有空格

key:value 不是映射项,而是字符串 "key:value"。必须写成 key: value,中间带个空格。这是新手第一份文件里最常见的笔误。

三、yes/no 变成了布尔

环境变量写成 DEBUG: no,静默地就变成了布尔 false,而不是字符串 "no"。国家区号、功能开关、类版本标记都会被这样吞掉。拿不准,就加引号。

在相信它之前,先让它解析一遍

YAML 最大的风险是:错误的文件往往看起来没错,直到某个工具在运行时把它拒掉。提交之前,把文档粘进 YAML 查看器,确认解析出来的结构和你想的一致 —— 尤其是布尔和数字。

继续阅读