Tracks
多年来,我使用过无数配置文件,YAML 以其简洁与可读性脱颖而出。无论是在 Kubernetes 中搭建工作流、在 Docker 中定义服务,还是组织 API 请求,YAML 都能让复杂配置更易管理。它基于缩进的清爽结构,既去除了 XML 等格式的冗余,又保持了足够的灵活性。
在本指南中,我将带您了解 YAML 的语法、结构、高级特性与最佳实践,帮助您自信地使用它。
什么是 YAML?
YAML(Yet Another Markup Language / YAML Ain’t Markup Language)是一种以可读性与易用性为优先的数据序列化格式。XML 使用类似 HTML 的嵌套标签,JSON 则使用花括号与引号,风格类似 Python 字典;相比之下,YAML 更为简洁,通过缩进定义结构,更加贴近人类阅读习惯。
YAML 支持多种数据类型,包括标量(字符串、数字、布尔值)、序列(列表)和映射(键值对)。它广泛用于配置文件、基础设施自动化与数据交换,尤其常见于 Kubernetes、Docker 与 Ansible 等工具中。
此外,YAML 是 JSON 的超集,这意味着有效的 JSON 文件也可作为 YAML 进行解析。YAML 文件通常以 .yaml 或 .yml 为扩展名。
您也可以在其官方网站上了解更多 YAML 信息!
YAML 语法与结构
本节将介绍 YAML 语法的基本原则,包括键值对、列表、嵌套数据与注释。
基础语法规则
YAML 有几条基本语法规则:
- 使用空格缩进表示结构,请避免使用制表符(tab)。
- 键值对遵循
key: value的结构,类似其他语言。 - 行首使用连字符可表示列表。
- 使用
#可创建注释行。
# Here is an example of YAML
name: John Doe
age: 30
skills:
- Python
- YAML
键值对
YAML 以键值对表示数据,类似 Python 中的字典。这通常用于传递配置文件与设置所需的信息。无需用引号标注字符串或键,只需直接写出所需的键与值:
location: New York
country: USA
security-level: user
YAML 中的列表
列表使用连字符(-)表示,可在单个键下列出多个对象。在标记语言编辑器中查看时,通常会以项目符号的形式展示。
fruits:
- Apple
- Banana
- Cherry
嵌套数据
嵌套结构通过缩进来表示层级关系,可将其理解为嵌套字典。通过缩进,您可以标明哪些键是其他键的子集。
person:
name: Alice
details:
age: 25
city: London
注释
注释以 # 开头,会被 YAML 解析器忽略。这些注释为单行注释。
# This is a comment
username: admin
password: secret
YAML 高级特性
YAML 包含多行字符串、数据类型、锚点等强大特性,使文档更高效且结构更清晰。本节将结合实例介绍这些能力。
多行字符串
YAML 使用 |(字面量块)或 >(折叠块)来表示多行字符串。
|字面量块会为每个换行创建一个新的\n。>折叠块仅在连续换行处创建新行。
literal: |
This is a
multi-line string.
folded: >
This is another
multi-line string.
通过展示输出更便于理解上述差异。
- 对于
|(字面量块):
This is a
multi-line string.
- 对于
>(折叠块):
This is another multi-line string.
YAML 中的数据类型
YAML 支持多种数据类型,包括字符串、数字、布尔值和空值。它可根据格式自动检测类型,同时也允许显式类型定义。
以下示例展示了 YAML 中基础数据类型的用法:
string_implicit: Hello, YAML! # No quotes needed unless necessary
string_double_quoted: "Supports escape sequences like \n and \t"
string_single_quoted: 'Raw text, no escape sequences'
integer: 42 # Whole numbers
float: 3.14 # Numbers with decimals
boolean_true: true
boolean_false: false
null_value: null # Null value
null_tilde: ~ # Another way to represent null
YAML 允许在需要时使用 !!type 进行显式类型声明:
explicit_string: !!str 123 # Forces 123 to be a string
explicit_integer: !!int "42" # Forces "42" to be an integer
explicit_float: !!float "3.14" # Forces "3.14" to be a float
由于 YAML 常用于结构化数据,它支持:
- 列表(序列):
fruits:
- Apple
- Banana
- Cherry
- 字典(映射):
person:
name: Alice
age: 30
is_student: false
锚点与别名
YAML 允许使用锚点(&)定义可复用的值,并通过别名(*)在后续位置引用。这有助于减少配置文件中的重复,使其更整洁、易于维护。
defaults: &default_settings
retries: 3
timeout: 30
server1:
host: example.com
retries: *default_settings # Reuses the retries value from defaults
使用 <<: 语法可以将锚点中的键值对合并到另一个映射中。如果某个键在二者中同时存在,新值会覆盖原值。
defaults: &default_settings
retries: 3
timeout: 30
server1:
<<: *default_settings # Merges all key-value pairs from default_settings
host: example.com # This key is added to the merged data
最终解析后的结构如下:
server1:
retries: 3
timeout: 30
host: example.com
在大型配置文件中,锚点与别名尤为实用。它们能帮助保持 YAML 文件的 DRY(Don't Repeat Yourself,不要重复自己),也让后续更新更加容易。
YAML 的常见使用场景
YAML 广泛应用于软件开发、基础设施自动化与 API 管理。其可读性强的语法使其成为配置文件、数据序列化与基础设施即代码(IaC)的首选格式。下面我们来看一些最常见的应用。
配置文件
YAML 广泛用于诸如 Docker Compose、Kubernetes 和 CI/CD 流水线 等应用的配置。其易懂的特性使任何人都能快速读懂 Docker 的 YAML 配置文件并把握其作用。
version: '3'
services:
web:
image: nginx
ports:
- "80:80"
environment:
- NGINX_HOST=localhost
- NGINX_PORT=80
YAML 的可读性以及对锚点与别名的支持有助于减少重复,使其比 JSON 或 XML 更易维护。
在这门进阶Docker 课程中,了解更多 YAML 在 Docker 中的用法。
数据序列化与传输
YAML 可将复杂数据结构转换为人类可读、机器易于解析的格式,常用于 API 与配置管理工具中的数据序列化。
例如,一个使用 YAML 格式的 API 请求体:
user:
id: 123
name: "John Doe"
email: "johndoe@example.com"
active: true
YAML 基于缩进的结构消除了不必要的语法元素,相较 JSON 更加轻量、易读且便于修改。
基础设施即代码(IaC)
Ansible 与 Kubernetes 等配置管理工具利用 YAML 定义系统状态、自动化流程,并确保不同环境间的一致性。
- 在 Ansible 中,YAML 用于编写 playbook,定义系统状态、任务与依赖,确保基础设施组件配置一致。
- Kubernetes 使用 YAML 清单定义资源,如 Pod、Service 与 Deployment,从而实现对容器化应用的自动化编排。
以下是一个 Kubernetes Pod 配置示例:
apiVersion: v1
kind: Pod
metadata:
name: my-app
spec:
containers:
- name: app-container
image: my-app:latest
ports:
- containerPort: 8080
在这门Kubernetes 入门课程中,进一步了解 YAML 在 Kubernetes 中的使用。
API 文档
诸如 OpenAPI 与 Swagger 的 API 规范使用 YAML 以易读的方式定义端点与数据结构。YAML 常用于描述 API 方法、请求参数、响应格式与认证方式。
以下是一个 YAML 格式的 OpenAPI 规范示例:
openapi: 3.0.0
info:
title: User API
version: "1.0"
paths:
/users:
get:
summary: Retrieve a list of users
responses:
"200":
description: Successful response
例如,OpenAPI 规范使用 YAML 来编写 RESTful API 文档,从而为生成客户端 SDK、交互式 API 文档与自动化测试提供清晰蓝图。这种结构化格式能确保 API 实现的一致性。
处理 YAML 文件
YAML 广泛用于配置文件、自动化与数据序列化,但由于其依赖缩进,正确的格式尤为重要。以下介绍如何高效地读取、编写、校验与编辑 YAML。
在 Python 中读写 YAML
Python 的 PyYAML 库可解析与生成 YAML。
设想您有如下配置 YAML 文件:
database:
host: localhost
port: 5432
user: admin
password: secret
以下展示了如何在 Python 中操作该配置文件:
import yaml
# Load YAML data
with open("config.yaml", "r") as file:
data = yaml.safe_load(file) # safe_load prevents arbitrary code execution
# Modify data (optional)
data["database"]["user"] = "new_user"
# Write YAML data
with open("output.yaml", "w") as file:
yaml.dump(data, file, default_flow_style=False)
如果您也想在 Python 中处理 JSON 数据,请查看这篇全面的Python JSON 教程。
校验 YAML 文件
为确保结构正确,您可以使用工具检查用 tab 代替空格、重复字符、语法问题与尾随空格等异常。
以下是一些常用的 YAML 校验工具:
- 命令行工具:yamllint(基于 Python 的 linter)
- 在线校验器:YAML Lint、JSON Formatter 的 YAML Validator
编辑 YAML
您可以在任意文本编辑器中编写与编辑 YAML,但使用代码规范检查(lint)工具与语法高亮能显著提升可读性。
我常用的编辑器包括:
- VS Code(配合 YAML 插件)
- PyCharm(内置支持)
- Sublime Text(带 YAML 语法高亮)
YAML 中常见的错误与规避方法
尽管 YAML 简单易用,在实际操作中仍容易出现问题与笔误。本节将讨论这些常见错误,并给出编写清晰、正确文件的最佳实践。这也是我推荐使用 linter 或合适文本编辑器的原因!
混用 tab 与空格
YAML 依赖空格进行缩进——切勿混用空格与 tab。tab 会直接破坏 YAML 脚本。这其实是有意为之,因为不同系统对 tab 的解释不同。为尽量减少影响,推荐统一使用空格。
缩进不正确
请确保缩进一致,以避免解析错误。由于缩进是 YAML 表示层级的唯一方式,解析不当会给代码带来问题。一个 key: value 键值对很容易被塞进错误的位置,因此请时刻关注缩进!
忘记为特殊字符加引号
当字符串包含特殊字符或空格时应加引号。诸如反斜杠、逗号、感叹号等需要用引号包裹,才能按字符串解析。
path: "/home/user/documents"
message: "Hello, World!"
通过合理的校验、规范的编辑方式与 Python 的 PyYAML,您可以高效处理 YAML 文件并规避常见陷阱。
结语
YAML 是一种强大而简单的格式,被广泛用于配置、数据序列化与基础设施自动化。只要掌握其语法、结构与最佳实践,您就能在各类应用中高效地使用 YAML。
如果您希望在真实场景中应用 YAML:
- 在这门 机器学习的 CI/CD 课程中,了解 YAML 在 CI/CD 工作流中的使用方式。
- 在这门 Python API 入门课程中,探索 API 如何在规范中使用 YAML。
- 在这条 容器化与虚拟化学习路径中,更深入地学习容器化与基础设施自动化。
常见问题解答
YAML 是否具有通用性?
只要数据源或目标能够读取 YAML,它就是一种可行且有用的数据序列化与传输方式。请确保您发送数据的目标能够处理 YAML。
YAML 安全吗?YAML 文件会带来安全风险吗?
YAML 本身只是数据格式,但在解析不受信任的 YAML 文件时会产生安全风险。Python 的 PyYAML 中默认的 yaml.load() 方法可能执行嵌入在 YAML 中的任意代码,存在风险。请务必使用 yaml.safe_load() 以防止恶意代码被意外执行。同样地,在应用中使用 YAML 时,应确保严格的模式校验以避免安全漏洞。
YAML 能支持环境变量吗?
是的!虽然 YAML 本身不会直接处理环境变量,但许多工具(如 Docker Compose 与 Kubernetes)允许在 YAML 文件中引用环境变量。
如何在 YAML 中书写注释?
YAML 使用 # 符号支持单行注释,但不支持多行注释。如果需要多行注释,常见的替代做法是使用类似 _comment 的占位键。不过这仅是一种约定,除非您的应用特意过滤,否则 YAML 解析器不会忽略它。