YAML 转 JSON:K8s 配置必备
Kubernetes 配置文件用 YAML、Docker Compose 用 YAML、GitHub Actions 用 YAML——YAML 在云原生时代无处不在。但调试时 JSON 更直观、API 返回的是 JSON、部分工具只支持 JSON。本文详解 YAML 与 JSON 的互转。
什么是 YAML?
YAML(YAML Ain't Markup Language)是一种人类可读的数据序列化格式,特点:
- 缩进表示层级
- 用空格(不用 Tab)
- 注释用
# - 字符串通常不需要引号
- 支持引用、多行字符串
YAML 示例
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
labels:
app: nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.21
ports:
- containerPort: 80
什么是 JSON?
JSON(JavaScript Object Notation)是机器可读的数据交换格式:
- 严格的语法(双引号必需、无尾逗号)
- 不支持注释
- 不支持多行字符串
JSON 示例
{
"apiVersion": "apps/v1",
"kind": "Deployment",
"metadata": {
"name": "nginx",
"labels": {
"app": "nginx"
}
},
"spec": {
"replicas": 3,
"selector": {
"matchLabels": {
"app": "nginx"
}
},
"template": {
"metadata": {
"labels": {
"app": "nginx"
}
},
"spec": {
"containers": [
{
"name": "nginx",
"image": "nginx:1.21",
"ports": [
{
"containerPort": 80
}
]
}
]
}
}
}
}
YAML vs JSON 对比
| 维度 | YAML | JSON | |
| 可读性 | 高 | 中 | |
| 严格性 | 宽松 | 严格 | |
| 注释 | 支持 # | 不支持 | |
| 多行字符串 | 支持 ` | >` | 不支持 |
| 引号 | 可省略 | 必需双引号 | |
| Tab 缩进 | 不允许 | 不适用 | |
| 应用场景 | 配置文件 | API 传输 | |
| 解析速度 | 较慢 | 快 | |
| 跨语言 | 主流语言都支持 | 主流语言都支持 |
52tool YAML/JSON 转换器
工具地址:JSON/YAML 转换
功能
- YAML → JSON
- JSON → YAML
- 语法校验
- 格式美化
- 缩进设置(2/4 空格)
- 浏览器端处理
实战 1:YAML 转 JSON
输入:
server:
port: 8080
host: localhost
database:
url: postgres://localhost:5432/mydb
pool: 10
输出:
{
"server": {
"port": 8080,
"host": "localhost"
},
"database": {
"url": "postgres://localhost:5432/mydb",
"pool": 10
}
}
实战 2:JSON 转 YAML
输入:
{
"name": "myapp",
"version": "1.0.0",
"dependencies": {
"express": "^4.18.0",
"lodash": "^4.17.21"
}
}
输出:
name: myapp
version: 1.0.0
dependencies:
express: ^4.18.0
lodash: ^4.17.21
实战 3:语法校验
输入错误 YAML:
server:
port: 8080
host: localhost # 缩进错误
输出错误信息:
ERROR: Indentation error at line 3
Expected 2 spaces, got 1
实战场景
场景 1:K8s 配置调试
K8s 用 YAML,但 kubectl 实际处理的是 JSON。调试时把 YAML 转 JSON:
- 复制 YAML 到 52tool 转换器
- 转 JSON
- 检查字段名、嵌套结构是否正确
场景 2:API 配置转 JSON
某些工具只接受 JSON 配置:
# Helm values.yaml 转 JSON 给 API
curl -X POST https://api.example.com/deploy \
-H "Content-Type: application/json" \
-d @values.json
场景 3:CI/CD 配置查看
GitHub Actions 配置(.github/workflows/main.yml)转 JSON 看结构:
name: CI
on: [push]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
转 JSON 后便于程序化处理。
场景 4:配置合并
多个 YAML 配置合并:
- 把每个 YAML 转 JSON
- 用程序合并 JSON(更易处理)
- 转回 YAML 输出
场景 5:API Mock
API 返回 JSON,要做成 YAML 配置文件供前端用:
- 复制 API JSON 响应
- 转 YAML
- 美化输出
场景 6:OpenAPI 文档
OpenAPI 3.0 支持 YAML 和 JSON。YAML 适合人写,JSON 适合工具处理:
OpenAPI YAML → 转 JSON → 用工具生成 SDK
YAML 语法要点
1. 缩进
必须用空格,不能用 Tab。通常 2 空格:
parent:
child:
grandchild: value
2. 注释
# 这是注释
key: value # 行末注释
3. 字符串
# 不需要引号
name: John
# 包含特殊字符需要引号
greeting: "Hello, world!"
path: "/usr/local/bin"
# 单引号是字面字符串
escape: 'No \n escape'
# 双引号支持转义
newline: "Line1\nLine2"
4. 多行字符串
# 字面块(保留换行)
description: |
This is line 1
This is line 2
# 折叠块(换行变空格)
description: >
This is a long
paragraph that
will be joined
5. 列表
# 块序列
items:
- item1
- item2
- item3
# 流式序列
items: [item1, item2, item3]
6. 字典
# 块映射
person:
name: John
age: 30
# 流式映射
person: {name: John, age: 30}
7. 引用
defaults: &defaults
adapter: postgres
host: localhost
development:
<<: *defaults
database: myapp_dev
production:
<<: *defaults
database: myapp_prod
8. 布尔和数字
active: true # 布尔
count: 42 # 整数
pi: 3.14 # 浮点
null_value: null # null
empty: # 也表示 null
9. 多文档
--- 分隔多个文档:
---
name: doc1
---
name: doc2
K8s 用一个文件存多份配置时常用。
常见 YAML 错误
错误 1:Tab 缩进
server:
port: 8080 # 错误!Tab 不允许
修复:用 2 个空格。
错误 2:缩进不一致
parent:
child1: value
child2: value # 多了一个空格
修复:所有同级别字段缩进相同。
错误 3:冒号后无空格
key:value # 错误!
key: value # 正确
错误 4:特殊字符未引号
version: 1.0.0 # 被解析为字符串"1.0.0"
version: "1.0.0" # 明确字符串
path: /usr/bin # 没问题
text: "Hello: World" # 含冒号需引号
错误 5:列表项缩进
items:
- item1 # 推荐与父级同列
- item2
items:
- item1 # 也合法,但不推荐
- item2
编程实现
JavaScript
// npm install js-yaml
import yaml from 'js-yaml';
// YAML → JSON
const obj = yaml.load(yamlString);
const json = JSON.stringify(obj, null, 2);
// JSON → YAML
const yamlStr = yaml.dump(obj);
Python
import yaml
import json
# YAML → JSON
with open('config.yaml') as f:
data = yaml.safe_load(f)
json_str = json.dumps(data, indent=2)
# JSON → YAML
yaml_str = yaml.dump(data, default_flow_style=False)
Go
import (
"encoding/json"
"gopkg.in/yaml.v3"
)
// YAML → JSON
var data interface{}
yaml.Unmarshal(yamlBytes, &data)
jsonBytes, _ := json.Marshal(data)
命令行
# yq 工具(推荐)
yq eval -o=json config.yaml > config.json
yq eval -o=yaml config.json > config.yaml
# Python 一行
python -c "import yaml, json; print(json.dumps(yaml.safe_load(open('config.yaml'))))"
进阶技巧
技巧 1:用锚点减少重复
defaults: &defaults
timeout: 30
retries: 3
service1:
<<: *defaults
url: http://service1
service2:
<<: *defaults
url: http://service2
技巧 2:多文档处理
# config.yaml
---
apiVersion: v1
kind: Service
---
apiVersion: v1
kind: ConfigMap
import yaml
with open('config.yaml') as f:
docs = list(yaml.safe_load_all(f))
for doc in docs:
print(doc['kind'])
技巧 3:YAML Schema 校验
用 JSON Schema 校验 YAML(先转 JSON):
import jsonschema
schema = {...}
data = yaml.safe_load(yaml_str)
jsonschema.validate(data, schema)
与其他工具配合
YAML + JSON 格式化
工具:JSON 格式化
YAML 转 JSON 后格式化输出,更易读。
YAML + 文本对比
工具:文本对比
对比两个 YAML 配置的差异(先转 JSON 再对比更精确)。
YAML + K8s 部署
K8s 接受 YAML,但内部转为 JSON。开发时转 JSON 调试。
常见问题解答
Q: YAML 中 Tab 真的不能用吗?
A: 是的,YAML 标准不允许 Tab 缩进。多数解析器会报错。配置编辑器"用空格代替 Tab"。
Q: JSON 转 YAML 后再转 JSON 会一致吗?
A: 字段顺序可能不同。YAML 不保证字段顺序,JSON 也不保证(除非用 Orderedict)。需要严格一致建议直接处理 JSON。
Q: YAML 1.1 和 1.2 有什么区别?
A: 主要差异:1.2 移除了"yes/no"被解析为布尔的规则(1.1 中 enabled: yes 等于 enabled: true,1.2 中是字符串"yes")。建议用 1.2。
Q: 大型 YAML 文件解析慢怎么办?
A: 大型 YAML 用流式解析(PyYAML 的 safe_load_all),或考虑拆分多个文件。JSON 解析更快。
Q: YAML 注释转 JSON 后会保留吗?
A: 不会。JSON 不支持注释,转换后注释丢失。如果要保留,需要在 JSON 中作为字段(如 _comment)。
Q: 工具会保存我的 YAML 内容吗?
A: 52tool 转换器在浏览器端运行,输入不上传服务器。适合处理 K8s 配置、密码等敏感内容。
总结
YAML 和 JSON 是配置和数据传输的两大格式:
- YAML → JSON 调试:52tool 转换器
- JSON 格式化:JSON 格式化
- JSON 校验:JSON 校验
- 文本对比:文本对比
记住:YAML 写配置,JSON 调试和传输。两个工具配合用,云原生开发事半功倍。