灯下哥谭 灯下哥谭
首页
关于
  • Hermes Agent 平台
  • Claude Code
  • OpenClaw
  • GPU 推理节点运维
  • DeepSeek Harness
  • MySQL 运维知识地图
  • Elasticsearch 运维知识地图
  • Redis 运维知识地图
  • TiDB 体系
  • DBA 常用 SQL 与命令
  • Nginx 运维知识地图
  • Prometheus 监控
  • Docker
  • Systemd
  • Iptables
  • Firewalld
  • Sshd
  • MySQL8 运维 SOP 手册
  • MySQL 实战 45 讲(读书笔记)
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

灯下哥谭

灯还亮着
首页
关于
  • Hermes Agent 平台
  • Claude Code
  • OpenClaw
  • GPU 推理节点运维
  • DeepSeek Harness
  • MySQL 运维知识地图
  • Elasticsearch 运维知识地图
  • Redis 运维知识地图
  • TiDB 体系
  • DBA 常用 SQL 与命令
  • Nginx 运维知识地图
  • Prometheus 监控
  • Docker
  • Systemd
  • Iptables
  • Firewalld
  • Sshd
  • MySQL8 运维 SOP 手册
  • MySQL 实战 45 讲(读书笔记)
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • 工作笔记

  • 容器与编排

    • kubectl常用命令
    • Kubernetes核心概念详解:Namespace、Pod、Deployment、PV和PVC
    • Kubernetes之yaml文件详解
      • 写完怎么确认它是对的
      • 坑与边界
    • k8s部署MySQL
    • Kubernetes (k8s) 相关名词详解
    • PV、PVC、StorageClass的区别和联系
    • Docker使用笔记:容器保活、快速起 MySQL、密码管理器部署三件事
    • Browserless 使用笔记:把 Chrome 变成一个可以被并发调用的网络服务
  • Nginx

  • 监控

  • 网络安全

  • 其他

  • Linux笔记
  • 容器与编排
灯下哥谭
2022-03-29
目录

Kubernetes之yaml文件详解原创

Kubernetes的YAML文件是用于定义Kubernetes对象(如Pod、Service、Deployment等)的一种格式化文件。这些文件通常由开发人员和运维人员使用,并通过kubectl工具进行部署和管理。

版本说明

本文写于 2022-03,基于 Kubernetes 1.20 左右。
在 1.31 上的差异:本文若涉及 PodSecurityPolicy(policy/v1beta1),该资源已在 1.21 弃用、1.25 彻底移除,需改用 Pod Security Admission(命名空间级 pod-security.kubernetes.io 标签);Ingress 资源自 1.22 起仅支持 networking.k8s.io/v1(不再支持 extensions/v1beta1/networking.k8s.io/v1beta1),使用时请核对 apiVersion 是否已更新;Deployment/Service/ConfigMap 等基础资源的 YAML 结构未变。

以下是一个基本的Kubernetes YAML文件的示例:

apiVersion: v1
kind: Pod
metadata:
  name: my-pod
  labels:
    app: my-app
spec:
  containers:
    - name: my-container
      image: nginx:latest

1
2
3
4
5
6
7
8
9
10
11

Kubernetes YAML文件的主要结构由以下几个部分组成:

  • apiVersion:用于指定该对象的Kubernetes API版本。该版本必须与所使用的Kubernetes版本兼容。

    为什么有的写 v1、有的写 apps/v1:Kubernetes 的 API 按「组 / 版本」组织。Pod、Service、ConfigMap、Secret 这些最早的资源属于核心组(core group),它的组名是空字符串,所以只写版本号 v1;后来加入的资源都归到具名组里,写法是 <组名>/<版本>——Deployment 属于 apps 组,写 apps/v1;Ingress 属于 networking.k8s.io 组,写 networking.k8s.io/v1。

    不用背,随时能查:

    kubectl api-resources | grep -i deployment
    # NAME          SHORTNAMES   APIVERSION   NAMESPACED   KIND
    # deployments   deploy       apps/v1      true         Deployment
    
    1
    2
    3

    APIVERSION 那一列就是该集群当前该写的值。要查某个字段怎么填,用 kubectl explain:

    kubectl explain deployment.spec.strategy          # 看这个字段有哪些子字段、各自什么含义
    kubectl explain deployment.spec --recursive       # 一次性列出整棵字段树
    
    1
    2

    这两条命令的好处是答案直接来自你这个集群的 API Server,不会像搜到的博客那样给你一个已经被移除的字段。

  • kind:用于指定该对象的类型。常见的类型有Pod、Service、Deployment、ConfigMap、Secret等。

  • metadata:用于指定该对象的元数据,包括名称、标签、注释等信息。

  • spec:用于指定该对象的规范,包括容器、服务端口、存储卷等配置信息。

在一个Kubernetes YAML文件中,可以定义多个Kubernetes对象,每个对象之间用 --- 分隔开来。例如:


apiVersion: v1
kind: Pod
metadata:
  name: my-pod
  labels:
    app: my-app
spec:
  containers:
    - name: my-container
      image: nginx:latest

---
apiVersion: v1
kind: Service
metadata:
  name: my-service
spec:
  selector:
    app: my-app
  ports:
    - name: http
      port: 80
      targetPort: 80

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

在上面的示例中,定义了一个Pod和一个Service对象。

Kubernetes YAML文件的定义格式是相对灵活的,开发人员和运维人员可以根据需要灵活定义和组织它们。在定义时,可以使用一些基本的Kubernetes YAML文件的语法和结构元素,例如注释、缩进、序列和映射等。

总的来说,Kubernetes YAML文件是定义Kubernetes对象的一种简单但强大的方式。熟练掌握Kubernetes YAML文件的语法和结构可以更好地帮助开发人员和运维人员管理和部署Kubernetes对象。

除了上述基本结构外,Kubernetes YAML文件还支持许多其他功能和特性。下面列举了一些常用的Kubernetes YAML文件的功能和技巧:

  • 注释:使用 # 符号来添加注释。注释可以添加在任何位置,以提高代码的可读性。
apiVersion: v1
kind: Pod
metadata:
  name: my-pod  # 定义Pod名称
spec:
  containers:
    - name: my-container  # 定义容器名称
      image: nginx:latest  # 定义容器镜像

1
2
3
4
5
6
7
8
9
  • 多行字符串:使用 | 符号来定义多行字符串。这在定义大块的配置文件时非常有用。
apiVersion: v1
kind: ConfigMap
metadata:
  name: my-config
data:
  my-conf.yaml: |
    key1: value1
    key2: value2
    key3: value3

1
2
3
4
5
6
7
8
9
10
  • 环境变量:可以通过 env 属性来定义容器的环境变量。
apiVersion: v1
kind: Pod
metadata:
  name: my-pod
spec:
  containers:
    - name: my-container
      image: nginx:latest
      env:
        - name: ENV_VAR1
          value: "value1"
        - name: ENV_VAR2
          value: "value2"
1
2
3
4
5
6
7
8
9
10
11
12
13
  • 存储卷:可以使用 volumes 属性来定义Pod中的存储卷。

apiVersion: v1
kind: Pod
metadata:
  name: my-pod
spec:
  containers:
    - name: my-container
      image: nginx:latest
      volumeMounts:
        - name: my-volume
          mountPath: /data
  volumes:
    - name: my-volume
      configMap:
        name: my-config

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
  • 配置文件:可以使用 configMap 和 secret 属性来定义Pod中的配置文件。
apiVersion: v1
kind: Pod
metadata:
  name: my-pod
spec:
  containers:
    - name: my-container
      image: nginx:latest
      volumeMounts:
        - name: my-config
          mountPath: /etc/my-app
      env:
        - name: ENV_VAR1
          valueFrom:
            configMapKeyRef:
              name: my-config
              key: env-var1
        - name: ENV_VAR2
          valueFrom:
            secretKeyRef:
              name: my-secret
              key: env-var2
  volumes:
    - name: my-config
      configMap:
        name: my-config
    - name: my-secret
      secret:
        name: my-secret

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
  • 部署:可以使用 Deployment 对象来定义Pod的部署和升级策略。
apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-deploy
spec:
  replicas: 3
  selector:
    matchLabels:
      app: my-app
  template:
    metadata:
      labels:
        app: my-app
    spec:
      containers:
        - name: my-container
          image: nginx:latest

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

# 写完怎么确认它是对的

YAML 的问题分两层:格式对不对(缩进、引号),字段对不对(拼写、层级、该集群支不支持)。分别有对应的验证手段,都不需要真的创建资源。

# 1. 只做客户端校验:格式和已知字段
kubectl apply --dry-run=client -f pod.yaml
1
2

期望输出 pod/my-pod created (dry run)。这一步能查出缩进错误和明显的字段拼写错误,但它用的是 kubectl 内置的 schema,不认识 CRD。

# 2. 送到 API Server 做完整校验,但不落盘
kubectl apply --dry-run=server -f pod.yaml
1
2

这一步才是真正可靠的:API Server 会跑完整的字段校验、准入控制(admission webhook)和默认值填充,只是不写进 etcd。CRD、Operator 自定义资源、准入策略拦截,全都能在这里暴露出来。

# 3. 看看服务端最终会把它变成什么样(默认值都填上之后)
kubectl apply --dry-run=server -o yaml -f pod.yaml
1
2

输出里会多出一大堆你没写的字段——imagePullPolicy、restartPolicy、terminationGracePeriodSeconds、各种默认的 resources。排查「我没配这个东西为什么会有这个行为」时,先看这份补全后的 YAML,答案通常就在里面。

# 4. 已经创建的资源,看实际生效的完整定义
kubectl get deployment my-deploy -o yaml
1
2

# 坑与边界

1. YAML 里绝对不能用 Tab 缩进。 YAML 规范只接受空格,一个 Tab 就会报 error converting YAML to JSON: yaml: found character that cannot start any token——这条报错信息完全没提 Tab,第一次遇到很难猜。编辑器里把「插入 Tab 时转换为空格」打开,能省掉大量时间。

2. | 和 > 是两种不同的多行字符串。 | 保留换行(literal),> 会把换行折叠成空格(folded)。配置文件内容(如上文的 my-conf.yaml、Nginx 配置、脚本)必须用 |,用 > 会把整个配置压成一行,程序读进去就是语法错误。带 - 后缀(|-)表示去掉结尾多余的换行,通常更符合预期。

3. 版本号、端口、布尔值必须加引号。 YAML 会自作主张地推断类型:version: 1.20 解析成浮点数 1.2(末尾的 0 被吃掉),on / yes / no 解析成布尔值,08 可能被当成非法八进制。ConfigMap 的 data 字段只接受字符串,写数字会直接报错。规则很简单:data: 下面的值一律加引号。

4. 挂载 Secret 时注意文件权限。 volumes.secret 挂进去的文件默认权限是 0644,同 Pod 内的任何进程都能读。SSH 私钥、证书这类要求严格权限的文件需要显式设 defaultMode: 0400,否则 ssh 会直接拒绝使用并报 Permissions are too open。

5. 把 volume 挂到一个已有内容的目录上,会遮盖原有文件。 例如把 ConfigMap 挂到 /etc/nginx/,镜像里原本的 nginx.conf 就消失了,容器起不来。正确做法是挂到子目录(/etc/nginx/conf.d/),或者用 subPath 只覆盖单个文件——但要注意 subPath 挂载的文件不会随 ConfigMap 更新自动刷新,改完配置必须重启 Pod。

6. 本文示例里的 nginx:latest 只是占位,生产环境别照抄。 为了让示例聚焦在 YAML 结构上,下面统一写了 image: nginx:latest。真实环境必须把 tag 锁到具体小版本(如 nginx:1.27.3):latest 是可变引用,某次重建就可能撞上大版本跳变、配置不兼容、容器起不来,而且回滚时无法确定上一次跑的到底是哪个镜像。同样的口径见 k8s 部署 MySQL 与 Docker 使用笔记。

7. 一个文件里用 --- 分隔多个对象时,顺序不重要但依赖关系重要。 kubectl apply 会按顺序提交,但 Kubernetes 是最终一致的——Deployment 先于它引用的 ConfigMap 创建也不会报错,只是 Pod 会短暂停在 ContainerCreating 直到 ConfigMap 出现。真正会失败的是引用不存在的 Namespace,那会直接被拒绝。

#学习笔记#Kubernetes#Docker
上次更新: 9/11/2026

← Kubernetes核心概念详解:Namespace、Pod、Deployment、PV和PVC k8s部署MySQL→

最近更新
01
DeepSeek Harness 实战 06|学习笔记:插件、工具、技能不在同一个维度上 原创
09-11
02
DeepSeek Harness 实战 05|让两个编码 Agent 共用一份长期记忆 原创
09-09
03
DeepSeek Harness 实战 04|学习笔记:从「已知限制」里读出三处设计张力 原创
09-08
更多文章>
Theme by Vdoing
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式