YAML,另一种标记语言?不止是标记语言!

本文详细介绍YAML语言的基础知识,包括语法特点、数据类型及高级用法,适用于Kubernetes配置等场景。

早先的文章《Kubernetes入门实践--部署运行Go项目》里我们使用YAML定义了Deployment对象,Kubernetes推荐的使用方式也是用一个YAML文件来描述你所要部署的 API 对象。然后统一使用kubectl apply命令完成对这个对象的创建和更新操作。YAML是一种序列化语言,它通常被用作配置文件的一种格式。除了在Kubernetes项目以外像Docker-ComposeGitlab CI/CD项目的配置文件使用的也是YAML格式。通过这些在技术领域的明星项目也能反映出YAML在过去几年里的流行度。

这篇文章我们就详细地对YAML做一下入门,后面学习Kubernetes的过程中需要自己动手写那些API对象的声明配置文件时也好拿这个教程做个参考。

YAML是"Yet Another Markup Language"(另一种标记语言)的缩写。但后来项目的维护者将其重命名成了"YAML Ain‘t Markup Language"(YAML 不止是标记语言),以更加强调其面向数据的特性。所以你看,文章的标题,并不是我想标题党,是我真不知道起啥标题好才拿过来用的~。

一个简单的YAML文件

让我们先来看一个YAML文件的示例,做一个简要的概述。

--- 
 doe: "a deer, a female deer"
 ray: "a drop of golden sun"
 pi: 3.14159
 xmas: true
 french-hens: 3
 calling-birds: 
   - huey
   - dewey
   - louie
   - fred
 xmas-fifth-day: 
   calling-birds: four
   french-hens: 3
   golden-rings: 5
   partridges: 
     count: 1
     location: "a pear tree"
   turtle-doves: two

文件以三个短横线开头。这些短横线表示新YAML文档的开始。YAML支持在单个文件里存放多个文档,解析器会将每组短横线识别为新文档的开始。

接下来,我们将看到构成大部分典型YAML文档的常用结构:键-值对。Doe是一个指向字符串值"a deer, a female deer."的键。

YAML支持的不仅仅是字符串值。上面的文件以六个键-值对开始。它们的值有四种不同的数据类型。键doeray的值都是字符串。pi是一个浮点数。xmas是一个布尔值。french-hens是一个整数。可以用单引号或双引号将字符串括起来,也可以根本不用引号。YAML将无引号的数字识别为整数或浮点数。

第七项是个数组。calling-birds有四个元素,每个数组元素都由一个短横线开头。

我用两个空格缩进了calling-birds中的元素。缩进是YAML表示嵌套的方式。空格缩进的数量可以因文件而异,相同层级的元素左侧对齐即可,但是不允许使用Tab制表符。

最后,我们看到xmas-fifth-day,里面还有五个元素,每个元素都缩进了。我们可以将xmas-fifth-day视为包含两个字符串、两个整数和另一个字典值的字典。YAML支持这种键值嵌套和混合类型。

在我们深入研究YAML之前,让我们先看看这个文档用JSON表示是什么样子。可以在百度或者Google上搜一下YAMLJSON的网页工具,这类工具有很多。

{
  "doe": "a deer, a female deer",
  "ray": "a drop of golden sun",
  "pi": 3.14159,
  "xmas": true,
  "french-hens": 3,
  "calling-birds": [
    "huey",
    "dewey",
    "louie",
    "fred"
  ],
  "xmas-fifth-day": {
    "calling-birds": "four",
    "french-hens": 3,
    "golden-rings": 5,
    "partridges": {
      "count": 1,
      "location": "a pear tree"
    },
    "turtle-doves": "two"
  }
}

缩进和空白符

空白符是YAML格式的一部分,其中换行符表示字段的结束,缩进用于组织YAML文档的结构,用来表示文档的层级或者叫嵌套关系。不过YAML值允许使用空格符进行缩进,不允许使用制表符Tab键,这是因为不同的工具对待制表符的方式不同。缩进的空格数目不重要,只要相同层级的元素左侧对齐即可,比如下面这个文档,因为同级元素未对齐,在解析器里会报错

foo: bar
     pleh: help
     stuff:
       foo: bar
       bar: foo

所以总结下来记住下面四点即可:

  • 换行符表示字段的结束。

  • 使用缩进表示层级关系。

  • 缩进时不允许使用制表符Tab键,只允许使用空格。

  • 缩进的空格数目不重要,只要相同层级的元素左侧对齐即可。

注释

YAML中的注释以#号开头。它们可以出现在字段值之后,也可以占据整行。

___
# This is a full line comment
foo: bar # this is a comment, too

YAML数据类型

键-值对是YAML的基本构建块。YAML文档中的每一项都是至少一个字典的成员。键的类型始终是字符串。

YAML的键-值对中的值是标量。它们的表现行为类似于JavascriptPython等语言中的标量类型。通常我们只要记住将字符串括在引号中,数字不加引号就足够了,解析器会自动解析出值的类型。

下面我们就详细看一下YAML的值都支持哪些数据类型,我们先从数组和字典这两种符合类型说起,然后再逐步拆解看里面的普通类型。一般看完这两种复合类型就可以掌握YAML的基本用法,上手编写和修改YAML文档了。

数组

YAML的数组可以写在一行里

items: [ 1, 2, 3, 4, 5 ]
names: [ "one", "two", "three", "four" ]

也可以写在多行里,每一行指定一个元素

---
items:
  - 1 
  - 2 
  - 3
  - 4 
  - 5 
names:
  - "one"
  - "two"
  - "three"
  - "four"

多行格式对于包含复杂对象的列表非常有用。

___
items:
  - things:
      thing1: huey
      things2: dewey
      thing3: louie
  - other things:
      key: value

数组可以包含任何有效的YAML值。同一个数组中的值不必是同一类型。

字典

与数组一样,可以将字典放入单行内。我们在上面看到了这种格式。类型Python打印字典的格式:

---
foo: { thing1: huey, thing2: louie, thing3: dewey }

也见过在多行里指定字典元素的格式:

---
foo: bar
bar: foo

当然字典也可以自由嵌套,并且持有任何有效的YAML值。

---
foo:
  bar:
    - bar
    - rab
    - plop

数字类型

YAML可以识别数字类型。我们在上面看到了浮点和整数。YAML还支持其他几种数字类型。

整数可以用十进制、十六进制或八进制表示,Ox表示一个值是十六进制的,前导零表示一个八进制值。

 foo: 12345
 bar: 0x12d4
 plop: 023332

转换成JSON后整数都是十进制表示的

{
  "foo": 12345,
  "bar": 4820,
  "plop": 9946
}

YAML既支持固定浮点数,也支持指数浮点数。

 foo: 1230.15
 bar:  12.3015e+05

最后YAML里也可以表示正负无穷和非数字NaN (Not a Number的缩写)

foo: .inf
bar: -.Inf
plop: .NAN

字符类型

YAML的字符串为Unicode编码。在大多数情况下,不必用引号将它们括起来。

foo: this is a normal string

但是如果我们想要处理转义序列,我们需要使用双引号的字符串。

foo: "this is not a normal string\n"
bar: this is not a normal string\n

YAML将上面第一个值处理为以回车符和换行符结尾。由于第二个值未加引号,因此YAML\n视为两个普通的字符。

foo: this is not a normal string
bar : this is not a normal string\n

YAML不会对使用单引号的字符串进行转义,但是单引号可以避免将字符串内容解释为文档格式。

字符串值可以写在多行里。使用大于号,可以指定字符串块。

bar: >
  this is not a normal string it
  spans more than
  one line
  see?

但是解析器会把他们解析成单行字符串:

bar : this is not a normal string it spans more than one line see?

如果想让YAML把上面的字符串也解析成多行的,需要使用管道符  |

bar: |
  this is not a normal string it
  spans more than
  one line
  see?

Null

YAML里用波浪号~或者不带引号的null直接表示空值。

foo: ~
bar: null

布尔值

YAML用关键字TrueOnYes表示真。用FalseOffNo表示假。

---
foo: True
bar: False
light: On
TV: Off

高级选项

多文档

YAML文档以三个短横线开始,以三个英文句号结束。一些YAML处理程序会强制要求文档以三个短横线开始,结束运算符通常是可选的。例如,JavaJackson不会在没有开始的情况下处理YAML文档,但是PythonPyYAML会。

当一个文件包含多个文档时,通常使用文档结束操作符。比如下面这个例子

---
bar: foo
foo: bar
...
---
one: two
three: four

使用下面的Python脚本解析这个YAML文件:

import yaml

if __name__ == '__main__':
    stream = open("foo.yaml", 'r')
    dictionary = yaml.load_all(stream)

    for doc in dictionary:
        print("New document:")
        for key, value in doc.items():
            print(key + " : " + str(value))
            if type(value) is list:
                print(str(len(value)))

脚本会解析出YMAL文件里的两个文档对象:

New document:
bar : foo
foo : bar
New document:
one : two
three : four

总结

YAML是一种功能强大的语言,可用于配置文件、应用程序之间的消息和保存应用程序状态。我们介绍了它最常用的特性,包括如何使用内置数据类型和构造复杂文档。它还支持自定义函数、正则表达式这样的高级功能。后面学习Kubernetes的过程中需要自己动手写那些API对象的声明配置文件时可以拿这个教程做个参考。

参考链接

YAML tutorial get started

YAML1.2规范

- END -

关注公众号,获取更多精选技术原创文章

<think> 我们被要求解释YAML文件的定义和用途。根据引用[1]和[2],YAML一种可读性高的数据序列化格式,最初的含义是“Yet Another Markup Language”(仍是一种标记语言),后来变为“YAML Ain't Markup Language”(递归缩写,强调其不是标记语言)。 ### 定义 YAMLYAML Ain't Markup Language)是一种人类可读的数据序列化语言,通常用于配置文件和数据交换。它使用缩进来表示层级关系,并且支持复杂的数据结构,如列表、字典和标量值。YAML的设计目标包括易于阅读、适合程序读写、支持多种编程语言以及易于与脚本语言交互。 ### 主要特点 1. **可读性高**:YAML使用缩进和简洁的语法,使得文件结构清晰易读。 2. **支持多种数据类型**:包括标量(字符串、布尔值、整数、浮点数等)、序列(列表)和映射(字典)。 3. **支持注释**:使用`#`符号添加注释。 4. **支持引用和锚点**:可以定义数据块并在其他地方引用,避免重复。 5. **跨语言**:YAML可以被多种编程语言解析(如PythonJava、Ruby等)。 ### 基本语法 - **缩进**:使用空格(不能使用制表符)表示层级,相同缩进为同一层级。 - **键值对**:使用冒号`:`分隔键和值,如`key: value`。 - **列表**:使用连字符`-`表示列表项,如: ```yaml fruits: - apple - banana - orange ``` - **字典**:键值对的集合,如: ```yaml person: name: John age: 30 ``` ### 用途 根据引用[1][3][4],YAML的主要用途包括: 1. **配置文件**:在软件开发中,YAML常用于配置应用程序、服务和工具。例如,Docker和Kubernetes(k8s)使用YAML作为默认配置文件格式,用于定义容器部署和资源管理。 2. **数据交换**:由于YAML的可读性和跨语言支持,它适用于不同系统之间的数据交换。 3. **资源编排**:在Kubernetes中,YAML文件(称为资源清单文件)用于描述集群中的资源对象(如Pod、Service、Deployment等),通过kubectl命令使用这些文件可以编排和部署资源。 4. **数据序列化**:将数据结构或对象状态转换为YAML格式,以便存储或传输。 ### 示例 以下是一个简单的YAML文件示例(引用[4]): ```yaml server: port: 8080 path: /hello ``` 此例定义了一个嵌套结构,`server`有两个属性:`port`和`path`。 ### 注意事项 - YAML对大小写敏感。 - 缩进必须一致(通常使用两个空格)。 - 字符串可以不用引号,但包含特殊字符时需用引号括起来。 综上所述,YAML一种用于配置和数据交换的轻量级数据序列化语言,凭借其可读性和灵活性被广泛应用于现代软件开发中[^1][^2][^3][^4]。 §§相关问题§§ 1. YAML与JSON格式有何异同? 2. 如何在Python中解析YAML文件? 3. Kubernetes中的YAML文件结构是怎样的? 4. YAML文件中的锚点和引用如何使用? </think> ### YAML文件的定义与用途解析 #### **定义** YAMLYAML Ain't Markup Language)是一种**人类可读的数据序列化格式**,具有以下核心特征: 1. **递归命名**: - 最初全称 "Yet Another Markup Language"(一种标记语言)[^2] - 现解释为 "YAML Ain't Markup Language"(强调非标记语言的本质)[^1][^2] 2. **设计目标**: - 高可读性:通过缩进和简洁语法实现 - 跨语言兼容:支持Python/Java/Ruby等主流语言 - 数据结构表达:原生支持列表、字典等复杂结构 3. **文件格式**: - 扩展名为 `.yaml` 或 `.yml`[^4] #### **核心特性** | 特性 | 说明 | 示例 | |------|------|------| | **层级结构** | 通过缩进表示层级(空格非Tab) | `parent:↵ child: value` | | **数据类型** | 支持标量/列表/字典等 | `colors: [red, blue]` | | **大小写敏感** | Key和值区分大小写 | `Port: 80` ≠ `port: 80` | | **注释支持** | 用 `#` 添加注释 | `# 这是注释` | | **引用机制** | 通过 `&` 锚点和 `*` 引用避免重复 | `defaults: &base↵ key: value` | #### **主要用途** 1. **配置管理**(核心场景): - **云原生配置**:Kubernetes(k8s)资源清单文件[^3] ```yaml apiVersion: v1 kind: Pod metadata: name: nginx-pod spec: containers: - name: nginx image: nginx:1.14 ``` - **应用配置**:Spring Boot的`application.yml`[^4] ```yaml server: port: 8080 path: /api ``` 2. **数据序列化**: - 替代JSON/XML实现更易读的数据交换 - 支持复杂数据结构(如嵌套字典) 3. **DevOps工具链**: - Docker Compose配置 - CI/CD流水线定义(如GitLab CI) #### **与XML/JSON对比** | 格式 | 可读性 | 冗余度 | 学习曲线 | 典型场景 | |------|--------|--------|----------|----------| | YAML | ⭐⭐⭐⭐⭐ | 极低 | 平缓 | 配置文件 | | JSON | ⭐⭐ | 中 | 简单 | API数据交换 | | XML | ⭐ | 高 | 陡峭 | 企业级系统 | > 注:YAML可无损转换为JSON[^1],但反向转换可能丢失格式信息 #### **使用注意事项** 1. **缩进规则**: - 必须使用空格(通常2或4空格) - 同层级元素左对齐[^3][^4] ```yaml # 正确 level1: level2: value # 错误(混合缩进) level1: level2: value # 错误缩进 ``` 2. **特殊字符处理**: - 字符串含冒号需加引号:`msg: "重要:警告"` - 多行文本用 `|` 或 `>` 符号[^4] YAML凭借其简洁性和人机双读优势,已成为云原生时代基础设施即代码(IaC)的核心载体[^3],特别适合需要频繁人工编辑的配置文件场景。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值