YAML文件格式

前言:YAML 并不是一种新奇的语言,YAML 首次发表于 2001 年,距离现在已经过去差不多 20 个年头。YAML 虽然不如 JSON、XML 之类的语言流行,应用也没有那么广泛,但是 YAML 也有它的优势。

一、简介

YAML 是一种较为人性化的数据序列化语言,可以配合目前大多数编程语言使用。

YAML 的语法比较简洁直观,特点是使用空格来表达层次结构,其最大优势在于数据结构方面的表达,所以 YAML 更多应用于编写配置文件,其文件一般以 .yml 为后缀。

YAML 目前的官方全称为 “YAML Ain't Markup Language(YAML 不是标记语言)”,但有意思的是,其实 YAML 最初的含义是 “Yet Another Markup Language(还是一种标记语言)”。

> 目前 YAML 的最新版本为 1.2(第三个版本),本文将以 YAML 1.2 的标准进行讲解。

二、正文

在运维日常工作中又很多遇到yaml,例如写ansible的playbook,利用yaml来定义创建各应用及服务。

2.1概念

YAML(发音 /ˈjæməl/)是一个类似 XML、JSON 的数据序列化语言,YAML是专门用来写配置文件的语言,非常简洁和强大,使用比json更方便。它实质上是一种通用的数据串行化格式。其强调以数据为中心,旨在方便人类使用;并且适用于日常常见任务的现代编程语言。因而 YAML 本身的定义比较简单,号称“一种人性化的数据格式语言”。

2.2 优点

  • 便捷性:不必添加大量参数到命令行中执行命令。
  • 可维护性:yaml文件可以通过控制源头,跟踪每次操作。
  • 灵活性:yaml可创建比命令行更加复杂的结构。
  • 简易:易使用

2.3 语法规则

  • 大小写敏感。
  • 使用缩进表示层级关系。
  • 缩进不允许使用Tab键,只允许空格。
  • 缩进空格数目不重要,只要相同层级的元素左侧对齐。
  • #表示注释。

2.4 组织结构

文档间使用“—”(三个横线)在每文档开始作为分隔符。同时,文档也可以使用“…”(三个点号)作为结束符(可选)。

三、结构类型

3.1 基本语法

 大小写敏感

- 就是字面上的意思

One: 1
one: 2

用缩进表示层级关系

- 缩进只能使用空格,不能用 TAB 字符
- 缩进的空格数量不重要,但是同一层级的元素左侧必须对齐

# YAML
one:
  two: 2
  three:
    four: 4
    five: 5

// 以上的内容转成 JSON 后
"one": {
  "two": 2,
  "three": {
    "four": 4,
    "five": 5 
  }
}

用 # 表示注释

- 只支持单行注释

# 我是注释
# 我也是注释

 一个文件中可以包含多个文件的内容

- 用“ --- ”即三个破折号表示一份内容的开始
- 用“ ... ”即三个小数点表示一份内容的结束(非必需)

---
# 这是第一份内容
one: 1
# 其他内容...
...

---
# 这是第二份内容
two: 2
# 其他内容...

3.2 数据结构与类型

对象(Mapping)
表示以键值对(key: value)形式出现的数据

- 使用“冒号+空格”来分开

# YAML
key: value

// JSON
"key": "value"

- 支持多层嵌套(缩进表示层级关系

# YAML
key:
  child-key1: value1
  child-key2: value2

// JSON
"key": {
  "child-key1": "value1",
  "child-key2": "value2",
}

- 支持流式风格( Flow style)的语法(用花括号包裹,用逗号加空格分隔,类似 JSON)

# YAML
key: { child-key1: value1, child-key2: value2 }

// JSON
"key": { "child-key1": "value1", "child-key2": "value2" }

- 使用问号“?”声明一个复杂对象,允许你使用多个词汇(数组)来组成键

# YAML
?
  - keypart1
  - keypart2
:
  - value1
  - value2

3.3  数组(Sequence)

- 一组以区块格式(Block Format)(即“破折号+空格”)开头的数据组成一个数组

# YAML
values:
  - value1
  - value2
  - value3

// JSON
"values": ["value1", "value2", "value3"]

- 同时也支持内联格式(Inline Format)来表达(用方括号包裹,逗号加空格分隔,类似 JSON)

# YAML
values: [value1, value2, value3]

// JSON
"values": ["value1", "value2", "value3"]

- 支持多维数组(用缩进表示层级关系

# YAML
values:
  -
    - value1
    - value2
  -
    - value3
    - value4

// JSON
"values": [[ "value1", "value2"], ["value3", "value4"]]

 3.3 标量(Scalars)
表示 YAML 中最基本的数据类型

- 字符串(String
1. 字符串一般不需要用引号包裹,但是如果字符串中使用了反斜杠“\”开头的转义字符必须使用引号包裹

# YAML
strings:
  - Hello without quote # 不用引号包裹
  - Hello
   world # 拆成多行后会自动在中间添加空格
  - 'Hello with single quotes' # 单引号包裹
  - "Hello with double quotes" # 双引号包裹
  - "I am fine. \u263A" # 使用双引号包裹时支持 Unicode 编码
  - "\x0d\x0a is \r\n" # 使用双引号包裹时还支持 Hex 编码
  - 'He said: "Hello!"' # 单双引号支持嵌套"

// JSON
"strings":
  ["Hello without quote",
   "Hello world",
   "Hello with single quotes",
   "Hello with double quotes",
   "I am fine. ☺",
   "\r\n is \r\n",
   "He said: 'Hello!'"]


2. 对于多行的文字,YAML 提供了两种特殊的语法支持

保留换行(Newlines preserved)
> 使用竖线符“ | ”来表示该语法,每行的缩进和行尾空白都会被去掉,而额外的缩进会被保留

# YAML
lines: |
  我是第一行
  我是第二行
    我是吴彦祖
      我是第四行
  我是第五行

// JSON
"lines": "我是第一行\n我是第二行\n  我是吴彦祖\n     我是第四行\n我是第五行"

折叠换行(Newlines folded)
> 使用右尖括号“ > ”来表示该语法,只有空白行才会被识别为换行,原来的换行符都会被转换成空格

# YAML
lines: >
  我是第一行
  我也是第一行
  我仍是第一行
  我依旧是第一行
  
  我是第二行
  这么巧我也是第二行

// JSON
"lines": "我是第一行 我也是第一行 我仍是第一行 我依旧是第一行\n我是第二行 这么巧我也是第二行"

- 布尔值(Boolean)
1. “true”、“True”、“TRUE”、“yes”、“Yes”和“YES”皆为真
2. “false”、“False”、“FALSE”、“no”、“No”和“NO”皆为假

# YAML
boolean:
  - true # True、TRUE
  - yes # Yes、YES
  - false # False、FALSE
  - no # No、NO

// JSON
"boolean": [true, true, false, false]

- 整数(Integer)
支持二进制表示

# YAML
int:
  - 666
  - 0001_0000 # 二进制表示

// JSON
"int": [666, 4096]

- 浮点数(Floating Point)
支持科学计数法

# YAML
float:
  - 3.14
  - 6.8523015e+5 # 使用科学计数法

// JSON
"float": [3.14, 685230.15]

- 空(Null
“null”、“Null”和“~”都是空,不指定值默认也是空

# YAML
nulls:
  - null
  - Null
  - ~
  -

// JSON
"nulls": [null, null, null, null]

3.4 时间戳(Timestamp)

YAML 也支持 ISO 8601 格式的时间数据
> 这里使用 JavaScript 对象进行对比

# YAML
date1: 2020-05-26
date2: 2020-05-26T01:00:00+08:00
dete3: 2020-05-26T02:00:00.10+08:00
date4: 2020-05-26 03:00:00.10 +8

// JavaScript
date1: Tue May 26 2020 08:00:00 GMT+0800 (中国标准时间),
date2: Tue May 26 2020 01:00:00 GMT+0800 (中国标准时间),
dete3: Tue May 26 2020 02:00:00 GMT+0800 (中国标准时间),
date4: Tue May 26 2020 03:00:00 GMT+0800 (中国标准时间)

3.5 类型转换

YAML 支持使用严格类型标签“!!”(双感叹号+目标类型)来强制转换类型

# YAML
a: !!float '666' # !! 为严格类型标签
b: '666' # 其实双引号也算是类型转换符
c: !!str 666 # 整数转为字符串
d: !!str 666.66 # 浮点数转为字符串
e: !!str true # 布尔值转为字符串
f: !!str yes # 布尔值转为字符串

// JSON
"a": 666,
"b": "666",
"c": "666",
"d": "666.66",
"e": "true"
"f": "yes"

3.6 其他高级类型

YAML 也可以使用一些更高级的类型,但是并不一定兼容所有解析器,包括集合(Sets)有序映射(Ordered Map)十六进制数据(Hexdecimal)二进制数据(Binary)。

本文将不会对这几种类型进行讲解,感兴趣的读者可以自行搜索研究。

3.7 数据重用于合并

为了保持内容的简洁,避免过多重复的定义,YAML 提供了由锚点标签“&”引用标签“*”组成的语法,利用这套语法可以快速引用相同的一些数据...

// YAML
a: &anchor # 设置锚点
  one: 1
  two: 2
  three: 3
b: *anchor # 引用锚点

// JSON
"a": {
  "one": 1,
  "two": 2,
  "three": 3
},
"b": {
  "one": 1,
  "two": 2,
  "three": 3
}

配合合并标签“<<”使用可以与任意数据进行合并,你可以把这套操作想象成面向对象语言中的继承...

# YAML
human: &base # 添加名为 base 的锚点
    body: 1
    hair: 999
singer:
    <<: *base # 引用 base 锚点,实例化时会自动展开
    skill: sing # 添加额外的属性
programer:
    <<: *base # 引用 base 锚点,实例化时会自动展开
    hair: 6 # 覆写 base 中的属性
    skill: code # 添加额外的属性

// JSON
"human": { "body": 1, "hair": 999 },
"singer": { "body": 1, "hair": 999, "skill": "sing" },
"programer": { "body": 1, "hair": 6, "skill": "code" }

四、yaml文件实例

K8S:

apiVersion: v1             #指定api版本,此值必须在kubectl apiversion中
kind: Pod                  #指定创建资源的角色/类型
metadata:                  #资源的元数据/属性
name: web04-pod          #资源的名字,在同一个namespace中必须唯一
labels:                  #设定资源的标签,详情请见http://blog.csdn.net/liyingke112/article/details/77482384
k8s-app: apache
version: v1
kubernetes.io/cluster-service: "true"
annotations:             #自定义注解列表
- name: String         #自定义注解名字
spec:#specification of the resource content 指定该资源的内容
restartPolicy: Always    #表明该容器一直运行,默认k8s的策略,在此容器退出后,会立即创建一个相同的容器
nodeSelector:            #节点选择,先给主机打标签kubectl label nodes kube-node1 zone=node1
zone: node1
containers:
- name: web04-pod        #容器的名字
image: web:apache      #容器使用的镜像地址
imagePullPolicy: Never #三个选择Always、Never、IfNotPresent,每次启动时检查和更新(从registery)images的策略,
# Always,每次都检查
# Never,每次都不检查(不管本地是否有)
# IfNotPresent,如果本地有就不检查,如果没有就拉取
command: ['sh']        #启动容器的运行命令,将覆盖容器中的Entrypoint,对应Dockefile中的ENTRYPOINT
args: ["$(str)"]       #启动容器的命令参数,对应Dockerfile中CMD参数
env:                   #指定容器中的环境变量
- name: str            #变量的名字
value: "/etc/run.sh" #变量的值
resources:             #资源管理,请求请见http://blog.csdn.net/liyingke112/article/details/77452630
requests:            #容器运行时,最低资源需求,也就是说最少需要多少资源容器才能正常运行
cpu: 0.1           #CPU资源(核数),两种方式,浮点数或者是整数+m,0.1=100m,最少值为0.001核(1m)
memory: 32Mi       #内存使用量
limits:              #资源限制
cpu: 0.5
memory: 32Mi
ports:
- containerPort: 80    #容器开发对外的端口
name: httpd          #名称
protocol: TCP
livenessProbe:         #pod内容器健康检查的设置,详情请见http://blog.csdn.net/liyingke112/article/details/77531584
httpGet:             #通过httpget检查健康,返回200-399之间,则认为容器正常
path: /            #URI地址
port: 80
#host: 127.0.0.1   #主机地址
scheme: HTTP
initialDelaySeconds: 180 #表明第一次检测在容器启动后多长时间后开始
timeoutSeconds: 5    #检测的超时时间
periodSeconds: 15    #检查间隔时间
#也可以用这种方法
#exec: 执行命令的方法进行监测,如果其退出码不为0,则认为容器正常
#  command:
#    - cat
#    - /tmp/health
#也可以用这种方法
#tcpSocket: //通过tcpSocket检查健康
#  port: number
lifecycle:             #生命周期管理
postStart:           #容器运行之前运行的任务
exec:
command:
- 'sh'
- 'yum upgrade -y'
preStop:             #容器关闭之前运行的任务
exec:
command: ['service httpd stop']
volumeMounts:          #详情请见http://blog.csdn.net/liyingke112/article/details/76577520
- name: volume         #挂载设备的名字,与volumes[*].name 需要对应
mountPath: /data     #挂载到容器的某个路径下
readOnly: True
volumes:                 #定义一组挂载设备
- name: volume           #定义一个挂载设备的名字
#meptyDir: {}
hostPath:
path: /opt           #挂载设备类型为hostPath,路径为宿主机下的/opt,这里设备类型支持很多种
对应的json格式
{
'kind': 'Pod',
'spec': {
'restartPolicy': 'Always',
'containers': [
{
'livenessProbe': {
'initialDelaySeconds': 180,
'httpGet': {
'path': '/',
'scheme': 'HTTP',
'port': 80
},
'timeoutSeconds': 5,
'periodSeconds': 15
},
'name': 'web04-pod',
'image': 'web:apache',
'args': [
'$(str)'
],
'volumeMounts': [
{
'readOnly': True,
'mountPath': '/data',
'name': 'volume'
}
],
'ports': [
{
'protocol': 'TCP',
'containerPort': 80,
'name': 'httpd'
}
],
'command': [
'sh'
],
'env': [
{
'name': 'str',
'value': '/etc/run.sh'
}
],
'imagePullPolicy': 'Never',
'lifecycle': {
'preStop': {
'exec': {
'command': [
'service httpd stop'
]
}
},
'postStart': {
'exec': {
'command': [
'sh',
'yum upgrade -y'
]
}
}
},
'resources': {
'requests': {
'cpu': 0.1,
'memory': '32Mi'
},
'limits': {
'cpu': 0.5,
'memory': '32Mi'
}
}
}
],
'volumes': [
{
'hostPath': {
'path': '/opt'
},
'name': 'volume'
}
],
'nodeSelector': {
'zone': 'node1'
}
},
'apiVersion': 'v1',
'metadata': {
'labels': {
'k8s-app': 'apache',
'version': 'v1',
'kubernetes.io/cluster-service': 'true'
},
'name': 'web04-pod',
'annotations': [
{
'name': 'String'
}
]
}
}
ansible
---
- hosts: agent                                    # 定义主机
remote_user: root                           # 定义执行此playbook的用户
tasks:                                              # 任务
- name: install mysql-server                             #自定义名称
yum: name=mysql-server state=present       # yum模块安装mysql-server
- name: start mysql-server
service: name=mysqld state=started            # service模块启动mysql服务
- name: check mysql service
shell: ps -ef |grep mysqld                             # shell模块查看mysql进程

对应的json格式:

{
'tasks': [
{
'yum': 'name=mysql-server state=present',
'name': 'install mysql-server'
},
{
'name': 'start mysql-server',
'service': 'name=mysqld state=started'
},
{
'shell': 'ps -ef |grep mysqld',
'name': 'check mysql service'
}
],
'hosts': 'agent',
'remote_user': 'root'
}]
利用python讲yaml格式转换为json
pip install pyyaml                # 安装pyyaml模块


import yaml


with open('config.yaml','r') as f:
content = yaml.load(f)
print(content)

<think>好的,用户想了解YAML文件的格式规范。首先,我需要回忆一下之前提供的引用内容,确保信息准确。根据引用1,YAML是一种人类可读的数据序列化格式,用于配置和数据交换,使用缩进和结构表示层次。引用3提到了具体的语法规则,比如缩进用空格而不是制表符,开头缩进两个空格,冒号和逗号后的空格处理。还有注释用“#”符号,以及“---”表示文件开始。 接下来,引用4补充了纯量的表示方法,比如数值、布尔值、null和时间格式,以及数据类型强制转换和引用锚点的使用。这些都需要涵盖进去。用户可能需要具体的例子,所以需要举一些YAML的示例代码,比如键值对、列表、嵌套结构等。 用户可能还关心YAML的应用场景,比如在Kubernetes中的使用,或者作为配置文件,这点引用2和引用3都有提到。需要确保回答结构清晰,分点说明,比如基本语法、数据类型、特殊语法、注释、格式验证工具等。 还要注意用户提到的系统级指令,比如数学表达式用$...$,但YAML主要涉及语法规范,可能用不到太多数学公式。但需要检查是否有需要格式化的地方,比如代码块用三个反引号包裹,并标明语言类型。 最后,生成相关问题时要考虑用户可能进一步的问题,比如与JSON的区别,高级特性,常见错误,在Docker或K8s中的具体应用,以及如何处理复杂结构。需要确保问题覆盖用户可能想深入的方向。</think>### YAML文件格式规范说明 YAMLYAML Ain’t Markup Language)是一种以人类可读性为核心的数据序列化格式,广泛用于配置文件、数据交换和容器编排(如Kubernetes)[^3]。其核心规范如下: --- #### 一、基本语法规则 1. **缩进表示层级** - 使用空格缩进(**禁止使用制表符Tab**),通常每级缩进2个空格[^3] - 示例: ```yaml server: port: 8080 environment: production ``` 2. **键值对与分隔符** - 冒号`:`表示键值对,**冒号后必须加一个空格** - 短横线`-`表示列表项,后需加空格[^3] - 示例: ```yaml features: - logging - authentication ``` 3. **多行文本** - 使用`|`保留换行符或`>`折叠换行符 - 示例: ```yaml description: | This is a multiline text block ``` --- #### 二、数据类型规范 1. **纯量(Scalars)** - 数值:直接书写,如`weight: 68.5` - 布尔值:`true`/`false`(小写)[^4] - Null值:用`~`表示,如`parent: ~`[^4] - 时间:ISO8601格式,如`2023-08-20T15:30:00+08:00`[^4] 2. **强制类型转换** - 使用`!!`指定类型,如`e: !!str 123`将数值转为字符串[^4] 3. **引用与锚点** - `&`定义锚点,`*`引用锚点,`<<`合并数据[^4] - 示例: ```yaml defaults: &defaults timeout: 30 development: <<: *defaults debug: true ``` --- #### 三、特殊语法结构 1. **文档起始符** - 使用`---`表示文件开始(非强制) 2. **多文档分隔** - 用`...`分隔多个YAML文档 - 示例: ```yaml # 文档1 name: ConfigA ... # 文档2 name: ConfigB ``` --- #### 四、注释与验证 1. **注释** - 以`#`开头,如`# 数据库配置`[^3] 2. **格式验证工具** - 推荐使用在线工具(如yamlvalidator.com)或IDE插件检查缩进和语法 --- #### 典型应用示例 ```yaml # Kubernetes部署配置 apiVersion: apps/v1 kind: Deployment metadata: name: web spec: replicas: 3 template: spec: containers: - name: app image: nginx:latest ports: - containerPort: 80 ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

84岁带头冲锋

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值