问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

YAML是什么?

创作时间:
作者:
@小白创作中心

YAML是什么?

引用
CSDN
1.
https://blog.csdn.net/bestpasu/article/details/146482331

YAML(YAML Ain't Markup Language)是一种以数据为中心、高度可读的序列化语言,广泛应用于配置文件、数据交换和自动化工具中。本文将从多个维度对YAML进行全面解析,包括其定义与历史演变、核心语法特性、主要应用场景、与JSON的对比、工具生态、局限性及注意事项,并通过一个Kubernetes Deployment配置文件的实战解析,帮助读者深入理解YAML在实际应用中的核心语法和结构化表达能力。

1. 定义与历史演变

  • 全称与定位
    YAML的全称最初为“Yet Another Markup Language”(另一种标记语言),后更改为“YAML Ain’t Markup Language”,强调其数据描述属性而非文档标记功能。它被设计为人类友好、跨语言的通用数据格式,尤其适合表达复杂数据结构。

  • 发展历程

  • 2001年:由Clark Evans、Ingy döt Net和Oren Ben-Kiki共同提出,旨在替代XML的复杂性。

  • 2004年:发布YAML 1.0标准,确立基本语法。

  • 2010年:推出YAML 1.2版本,成为JSON的超集(兼容JSON语法),并优化了可读性和扩展性。

  • 2010年后:随着容器化(Docker、Kubernetes)和DevOps(Ansible)的兴起,成为现代基础设施即代码(IaC)的核心配置格式。

2. 核心语法特性

  • 结构规则

  • 缩进分层:使用空格(禁止制表符)表示层级关系,缩进长度灵活但需对齐。

  • 注释支持:以#开头,增强可读性。

  • 多文档分隔:用---分隔多个文档,...表示结束。

  • 数据类型与结构

  • 标量(Scalars):包括字符串、布尔值、整数、浮点数、日期、空值(null~)等,字符串通常无需引号。

  • 序列(Sequences/列表):以连字符-开头或方括号[]表示。

  • 映射(Mappings/对象):键值对用冒号:分隔,支持嵌套。

  • 复合结构:可嵌套序列与映射,如列表中的字典。

  • 高级功能

  • 多行字符串:通过|保留换行符或>折叠换行符。

  • 锚点与引用:使用&定义锚点,*引用锚点,避免重复数据。

  • 合并映射:通过<<合并多个映射,简化配置。

3. 主要应用场景

  • 配置文件

  • DevOps工具:如Kubernetes的Pod定义、Ansible的Playbook、Docker Compose文件等。

  • 框架配置:Ruby on Rails、Spring等框架的配置文件。

  • 数据交换与序列化

  • 跨语言数据共享:支持Python、Java、JavaScript等语言的序列化库(如PyYAML、SnakeYAML)。

  • API定义:OpenAPI(Swagger)规范使用YAML描述接口。

  • 复杂数据表示

  • 日志与监控规则:Prometheus、Grafana等工具的配置。

  • 基础设施即代码(IaC):Terraform、AWS CloudFormation的模板。

4. YAML与JSON的对比

维度
YAML
JSON
可读性
依赖缩进和自然语言风格,支持注释,适合人工编辑
依赖大括号和引号,结构紧凑,适合机器解析
数据类型
支持更复杂类型(如日期、多行字符串、锚点引用)
仅支持基本类型(字符串、数字、数组、对象)
语法简洁性
无需冗余符号(如引号、逗号),结构清晰
需要严格符号(引号、逗号)
兼容性
自1.2版本起完全兼容JSON,可混合使用JSON语法
是YAML的子集,独立作为数据交换标准
适用场景
配置文件、复杂数据结构
API通信、Web服务

5. 工具与生态

  • 解析库

  • Python:PyYAML、ruemal.yaml。

  • JavaScript:js-yaml。

  • Java:SnakeYAML。

  • Ruby:内置YAML模块。

  • 验证与格式化工具

  • yamllint:检查语法和格式规范。

  • 在线转换器:实现YAML与JSON、XML的互转。

6. 局限性及注意事项

  • 格式敏感性:缩进错误易导致解析失败,需严格对齐。
  • 安全性问题:部分解析器可能执行不安全代码,需禁用危险功能(如PyYAML的FullLoader)。
  • 性能:处理大规模数据时,解析速度可能逊于JSON。

YAML凭借其可读性、灵活性和跨平台特性,成为现代软件开发中不可或缺的配置和数据交换工具。尽管与JSON存在竞争,但两者在不同场景下互补:YAML擅长人工维护的配置,而JSON更适合机器间的轻量级通信。随着云原生和自动化技术的普及,YAML的应用范围将持续扩展。

实战解析:Kubernetes Deployment配置文件

以下是一个Kubernetes Deployment配置文件的实际例子,并逐段解析其语法和功能:

apiVersion: apps/v1          # API版本(字符串)
kind: Deployment             # 资源类型(字符串)
metadata:
  name: nginx-deployment     # 元数据:名称
  labels:
    app: nginx               # 标签键值对
spec:
  replicas: 3                # 整数:副本数
  selector:
    matchLabels:
      app: nginx
  template:                  # Pod模板(嵌套结构)
    metadata:
      labels:
        app: nginx
    spec:
      containers:            # 列表(以 - 开头)
- name: nginx
        image: nginx:1.25     # 字符串值
        ports:
- containerPort: 80  # 整数:容器端口
        resources:           # 嵌套映射
          limits:
            memory: "128Mi"  # 带单位的字符串需要引号
            cpu: "500m"
          requests:
            memory: "64Mi"
            cpu: "250m"
        command: ["/bin/sh"] # 列表的另一种语法(JSON风格)
        args:
- -c
- echo "Hello, YAML!" # 多行参数示例(隐式字符串)
      restartPolicy: Always

逐段解析

  1. 基本结构
  • apiVersionkind:定义Kubernetes资源的类型和版本,均为字符串。YAML允许省略引号(除非包含特殊字符)。
  • metadata:描述资源的元数据,如名称(name)和标签(labels)。
    缩进规则namelabels需对齐,表示同层级。
  1. 标签与选择器
  • labelsselector:通过键值对(app: nginx)标识资源,selector.matchLabels确保Deployment管理带有此标签的Pod。
    映射嵌套matchLabelsselector的子键。
  1. 副本数与模板
  • replicas: 3:直接使用整数,无需引号。Kubernetes将启动3个Pod副本。
  • template:定义Pod的嵌套结构,包含metadataspec
    层级缩进template下的所有内容需缩进2个空格(或统一倍数)。
  1. 容器配置
  • containers:以连字符-开头的列表,每个列表项是一个容器定义。
  • nameimage:容器名称和镜像版本,均为字符串。
  • ports:列表中的嵌套映射(containerPort: 80)。
  • resources:复杂映射,包含limitsrequests的资源限制。
    引号规则"128Mi"因包含字母Mi,需加引号避免解析错误。
  1. 命令与参数
  • command:使用JSON风格的列表(["/bin/sh"]),显式表示数组。与YAML的-列表语法等价。
  • args:多行参数通过缩进和连字符表示,- -c- echo "..."会被解析为["-c", "echo 'Hello, YAML!'"]
  1. 数据类型与风格
  • 隐式类型推断replicas: 3自动识别为整数,containerPort: 80同理。
  • 显式字符串memory: "128Mi"强制保留字符串格式,避免Kubernetes误解析为数值。

YAML在此场景的优势

  1. 可读性:缩进和注释让复杂的容器配置清晰易读,比JSON更适合人工维护。
// 对比JSON(相同配置):
{
  "apiVersion": "apps/v1",
  "kind": "Deployment",
  "metadata": {
    "name": "nginx-deployment",
    "labels": {"app": "nginx"}
  },
  "spec": {
    "replicas": 3,
    "selector": {"matchLabels": {"app": "nginx"}},
    "template": {
      "metadata": {"labels": {"app": "nginx"}},
      "spec": {
        "containers": [
          {
            "name": "nginx",
            "image": "nginx:1.25",
            "ports": [{"containerPort": 80}],
            "resources": {
              "limits": {"memory": "128Mi", "cpu": "500m"},
              "requests": {"memory": "64Mi", "cpu": "250m"}
            },
            "command": ["/bin/sh"],
            "args": ["-c", "echo \"Hello, YAML!\""]
          }
        ],
        "restartPolicy": "Always"
      }
    }
  }
}
  1. 灵活性:支持多行字符串、锚点引用(如重复的app: nginx可通过锚点&app_label简化)。
  2. 生态集成:Kubernetes、Ansible等工具原生支持YAML,直接通过配置文件驱动基础设施。

扩展:YAML的高级用法

# 示例:使用锚点(&)和引用(*)避免重复
base_config: &base
  timeout: 30
  retries: 3
service_a:
  <<: *base         # 合并base_config的键值对
  endpoint: "api.a.com"
service_b:
  <<: *base
  endpoint: "api.b.com"

通过这种模式,YAML可以显著减少冗余配置,适合管理多个相似服务。

该示例展示了YAML在真实场景中的核心语法和结构化表达能力,结合注释和缩进,使其成为DevOps领域配置管理的首选格式。

© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号