赞
踩
前言: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来定义创建各应用及服务。
YAML(发音 /ˈjæməl/)是一个类似 XML、JSON 的数据序列化语言,YAML是专门用来写配置文件的语言,非常简洁和强大,使用比json更方便。它实质上是一种通用的数据串行化格式。其强调以数据为中心,旨在方便人类使用;并且适用于日常常见任务的现代编程语言。因而 YAML 本身的定义比较简单,号称“一种人性化的数据格式语言”。
文档间使用“—”(三个横线)在每文档开始作为分隔符。同时,文档也可以使用“…”(三个点号)作为结束符(可选)。
大小写敏感
- 就是字面上的意思
- 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
- # 其他内容...
对象(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
- 一组以区块格式(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"]]
- 字符串(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]
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 (中国标准时间)
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"
YAML 也可以使用一些更高级的类型,但是并不一定兼容所有解析器,包括集合(Sets)、有序映射(Ordered Map)、十六进制数据(Hexdecimal)和二进制数据(Binary)。
本文将不会对这几种类型进行讲解,感兴趣的读者可以自行搜索研究。
为了保持内容的简洁,避免过多重复的定义,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" }
- 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进程
- {
- '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)
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。