K8s 手写YAML 教程


一、核心底层逻辑(先搞懂,后面全是套公式)

1. 唯一判断依据:kubectl explain里的尖括号<>

YAML里每个字段的写法,完全由它的尖括号类型决定,和字段名本身无关。

  • 看到[] → 列表类型
  • 看到map → 字典类型
  • 看到string/int/bool/Quantity → 单值类型
  • 看到Object/Container/XXX → 嵌套对象类型

2. 缩进铁则(所有错误的根源)

  • 缩进只能用2个空格,绝对不能用Tab
  • 父子层级必须差2个空格,同级必须完全对齐
  • 列表元素-,必须比它的父字段多缩进2个空格,-后面必须跟1个空格

二、所有类型「标识→公式→绝对不能做→正确例子」

1. 基础单值类型(共6种,不换行)

通用规则:不加-,冒号后1个空格,直接写值,不换行。

<string>
  • 公式:字段名: 字符串值
  • 绝对不能做:不能加-,不能缩进,特殊字符不加引号
  • 正确例子:
name: tomcat-pod
image: tomcat:8.5-jre8-alpine
command: "/bin/sh"
<integer>
  • 公式:字段名: 整数值
  • 绝对不能做:不能加引号,不能加-
  • 正确例子:
replicas: 3
containerPort: 8080
terminationGracePeriodSeconds: 30
<boolean>
  • 公式:字段名: true/false(必须小写)
  • 绝对不能做:不能写True/False/yes/no,不能加-
  • 正确例子:
privileged: false
readOnly: true
runAsNonRoot: true
<number>
  • 公式:字段名: 数值(整数或小数)
  • 绝对不能做:不能加引号,不能加-
  • 正确例子:
cpu: 0.5
memory: 1.5
<any>
  • 公式:字段名: 任意值(字符串/数字/布尔都可以)
  • 绝对不能做:没有限制
  • 正确例子:
data: 123
data: "abc"
data: true
<null>
  • 公式:字段名: null
  • 绝对不能做:不能写其他值
  • 正确例子:
value: null

2. 特殊单值对象类型(共5种,不换行)

通用规则:不加-,冒号后1个空格,直接写值,不换行。

<Quantity>(资源数量)
  • 公式:字段名: "值+单位"(必须加引号)
  • 绝对不能做:不能不加引号,不能写纯数字
  • 正确例子:
cpu: "500m"
memory: "1Gi"
storage: "10Gi"
<Duration>(时间)
  • 公式:字段名: "值+单位"(单位:ns/ms/s/m/h)
  • 绝对不能做:不能写纯数字,单位不能错
  • 正确例子:
initialDelaySeconds: 30s
timeoutSeconds: 5m
periodSeconds: 1h
<IntOrString>(整数或字符串)
  • 公式:字段名: 整数值字段名: "字符串值"
  • 绝对不能做:没有限制
  • 正确例子:
port: 8080
port: "http"
<Time>(时间戳)
  • 公式:字段名: "RFC3339格式时间"
  • 绝对不能做:不能写其他格式
  • 正确例子:
creationTimestamp: "2026-05-25T00:00:00Z"
<ByteSize>(字节大小)
  • 公式:字段名: "值+单位"(单位:KiB/MiB/GiB)
  • 绝对不能做:不能写纯数字
  • 正确例子:
maxSize: "100Mi"

3. 列表类型(所有带[]的,必须换行)

通用规则:

  1. 字段名单独一行,必须换行
  2. 每个元素前加--必须比父字段多缩进2个空格
  3. -后面必须跟1个空格
  4. 列表元素的子字段,必须比-多缩进2个空格
<[]string>
  • 公式:
字段名:
  - 字符串值1
  - 字符串值2
  • 绝对不能做:不能直接写值,不能写行内列表,-后不能没空格
  • 正确例子:
args:
  - "-Xms512m"
  - "-Xmx1024m"
  - "-Dspring.profiles.active=prod"
<[]integer>
  • 公式:
字段名:
  - 整数值1
  - 整数值2
  • 绝对不能做:不能直接写数字,不能写行内列表
  • 正确例子:
ports:
  - 80
  - 443
  - 8080
<[]Object>(对象列表)
  • 公式:
字段名:
  - 子字段1: 值1
    子字段2: 值2
  - 子字段1: 值3
    子字段2: 值4
  • 绝对不能做:不能直接写子字段,-不能和父字段对齐
  • 正确例子(imagePullSecrets):
imagePullSecrets:
  - name: regcred
  - name: harbor-secret
<[]XXX>(任意对象列表,如[]Container/[]ContainerPort
  • 公式和<[]Object>完全一致,按子字段的类型继续写即可
  • 正确例子(containersports嵌套):
spec:
  containers:
    - name: tomcat-pod
      image: tomcat:8.5-jre8-alpine
      ports:
        - containerPort: 8080
          name: http
        - containerPort: 8009
          name: ajp
特殊情况:空列表
  • 公式:字段名: [](必须写在同一行)
  • 绝对不能做:不能换行,不能只写字段名
  • 正确例子:
imagePullSecrets: []

4. 字典/映射类型(所有带map的,必须换行)

通用规则:

  1. 字段名单独一行,必须换行
  2. 每个键值对单独一行,缩进2个空格
  3. 绝对不能加-
<map[string]string>
  • 公式:
字段名:
  键1: 值1
  键2: 值2
  • 绝对不能做:不能加-,不能写行内字典
  • 正确例子(labels):
labels:
  app: tomcat
  version: v1
  env: production
<map[string]integer>
  • 公式:
字段名:
  键1: 整数值1
  键2: 整数值2
  • 绝对不能做:不能加-,不能写行内字典
  • 正确例子:
portMappings:
  http: 8080
  https: 8443
<map[string]boolean>
  • 公式:
字段名:
  键1: true/false
  键2: true/false
  • 绝对不能做:不能加-,不能写行内字典
  • 正确例子:
features:
  debug: true
  auth: false
<map[string]Quantity>
  • 公式:
字段名:
  键1: "值+单位"
  键2: "值+单位"
  • 绝对不能做:不能加-,数字必须加引号
  • 正确例子(limits/requests):
limits:
  cpu: "1"
  memory: "1Gi"
requests:
  cpu: "500m"
  memory: "512Mi"
<map[string]Object>
  • 公式:
字段名:
  键1:
    子字段1: 值1
    子字段2: 值2
  键2: 值3
  • 绝对不能做:不能加-,不能写行内字典
  • 正确例子(annotations):
annotations:
  author:
    name: admin
    email: admin@example.com
  desc: 测试Tomcat应用
特殊情况:空字典
  • 公式:字段名: {}(必须写在同一行)
  • 绝对不能做:不能换行,不能只写字段名
  • 正确例子:
emptyDir: {}

5. 通用嵌套对象类型(所有其他<XXX>,必须换行)

通用规则:

  1. 字段名单独一行,必须换行
  2. 每个子字段单独一行,缩进2个空格
  3. 绝对不能加-,不能直接赋值
<Object>(最常见,如metadata/spec
  • 公式:
字段名:
  子字段1: 值1
  子字段2: 值2
  • 绝对不能做:不能加-,不能直接赋值
  • 正确例子:
metadata:
  name: tomcat-pod
  labels:
    app: tomcat
spec:
  restartPolicy: Always
  containers: []
<Container>/<ContainerPort>/<ResourceRequirements>等(任意对象)
  • 公式和<Object>完全一致,按子字段的类型继续写即可
  • 正确例子(resources对象):
resources:
  limits:
    cpu: "1"
    memory: "1Gi"
  requests:
    cpu: "500m"
    memory: "512Mi"

三、缩进&换行终极判断表(再也不用纠结)

类型要不要换行要不要加-缩进规则
基础单值类型❌ 不换行❌ 不加-直接写在同一行
特殊单值对象类型❌ 不换行❌ 不加-直接写在同一行
空列表/空字典❌ 不换行❌ 不加-直接写[]/{}
非空列表类型✅ 必须换行✅ 必须加-列表字段名: 后换行,-比父字段多2格
非空字典类型✅ 必须换行❌ 不加-字典字段名: 后换行,键值对缩进2格
嵌套对象类型✅ 必须换行❌ 不加-对象字段名: 后换行,子字段缩进2格

四、新手必犯的10个致命错误(附修正)

  1. 错误:-和父字段对齐
# 错误
spec:
  containers:
  - name: tomcat

# 正确
spec:
  containers:
    - name: tomcat
  1. 错误:-后面没有空格
# 错误
containers:
  -name: tomcat

# 正确
containers:
  - name: tomcat
  1. 错误:列表元素的子字段和-对齐
# 错误
containers:
  - name: tomcat
  image: tomcat:8.5

# 正确
containers:
  - name: tomcat
    image: tomcat:8.5
  1. 错误:混用Tab和空格
  • 修正:编辑器设置为自动用2个空格代替Tab,全程只用空格缩进
  1. 错误:布尔值写大写
# 错误
privileged: False

# 正确
privileged: false
  1. 错误:资源数量不加引号
# 错误
cpu: 1
memory: 1Gi

# 正确
cpu: "1"
memory: "1Gi"
  1. 错误:空列表/空字典换行
# 错误
imagePullSecrets:

emptyDir:

# 正确
imagePullSecrets: []
emptyDir: {}
  1. 错误:冒号后面没有空格
# 错误
name:tomcat
image:tomcat:8.5

# 正确
name: tomcat
image: tomcat:8.5
  1. 错误:字符串含特殊字符不加引号
# 错误
value: -Xms512m

# 正确
value: "-Xms512m"
  1. 错误:写status字段
  • 修正:status是K8s自动生成的只读字段,绝对不要手动写

五、完整实战示例(Tomcat Pod,全标注类型&缩进)

# <string> 不换行
apiVersion: v1
# <string> 不换行
kind: Pod
# <Object> 必须换行,缩进0格
metadata:
  # <string> 不换行,缩进2格
  name: tomcat-pod
  # <map[string]string> 必须换行,缩进2格
  labels:
    # <string> 不换行,缩进4格
    app: tomcat
    # <string> 不换行,缩进4格
    version: v1
# <Object> 必须换行,缩进0格
spec:
  # <string> 不换行,缩进2格
  restartPolicy: Always
  # <[]Container> 必须换行,缩进2格
  containers:
    # 列表元素,缩进4格,-后1个空格
    - name: tomcat-pod-java  # <string> 不换行,缩进6格
      # <string> 不换行,缩进6格
      image: tomcat:8.5-jre8-alpine
      # <[]ContainerPort> 必须换行,缩进6格
      ports:
        # 列表元素,缩进8格,-后1个空格
        - containerPort: 8080  # <integer> 不换行,缩进10格
          # <string> 不换行,缩进10格
          name: http
      # <ResourceRequirements> 必须换行,缩进6格
      resources:
        # <map[string]Quantity> 必须换行,缩进8格
        limits:
          # <Quantity> 不换行,缩进10格
          cpu: "1"
          # <Quantity> 不换行,缩进10格
          memory: "1Gi"
        # <map[string]Quantity> 必须换行,缩进8格
        requests:
          # <Quantity> 不换行,缩进10格
          cpu: "500m"
          # <Quantity> 不换行,缩进10格
          memory: "512Mi"
  # <[]Toleration> 必须换行,缩进2格
  tolerations:
    # 列表元素,缩进4格,-后1个空格
    - key: node-role.kubernetes.io/master  # <string> 不换行,缩进6格
      # <string> 不换行,缩进6格
      effect: NoSchedule
  # 空列表 不换行,缩进2格
  imagePullSecrets: []

六、写YAML的万能流程(任何资源都适用)

  1. 查根字段kubectl explain <资源类型> --api-version=<版本>,如kubectl explain pod --api-version=v1
  2. 递归查子字段kubectl explain <资源类型>.<字段> --recursive,如kubectl explain pod.spec.containers --recursive
  3. 按类型套公式
    • 看到[] → 换行,加-,按缩进规则写
    • 看到map → 换行,不加-,键值对缩进2格
    • 看到基础/特殊单值 → 直接写,不换行
    • 看到Object/XXX → 换行,不加-,子字段缩进2格
  4. 工具校验
    • kubectl apply --dry-run=client -f your.yaml(官方校验,无副作用)
    • 或用 https://www.yamllint.com/ 在线检查缩进和语法

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐