文章背景图

如何写好 Kubernetes YAML:从对象结构到上线前校验

2026-07-25
3
-
- 分钟

Kubernetes YAML 不只是“能被解析的配置文件”,它表达的是你希望集群最终达到的状态。写得好的清单应当清晰、可审查、可复用,并能在上线前尽早发现错误。

一、先理解四个核心字段

大多数 Kubernetes 资源都从四个字段开始:

apiVersion:使用哪个 Kubernetes API 版本。

kind:要创建的资源类型,例如 Deployment、Service 或 ConfigMap。

metadata:对象的名称、命名空间、标签和注解。

spec:对象的期望状态,不同资源的 spec 结构不同。

status 通常由 Kubernetes 控制器维护,不应该手工写入清单。

二、一个结构完整的 Deployment 示例

apiVersion: apps/v1

kind: Deployment

metadata:

name: web

namespace: default

labels:

app.kubernetes.io/name: web

app.kubernetes.io/component: frontend

spec:

replicas: 2

selector:

matchLabels:

app.kubernetes.io/name: web

template:

metadata:

labels:

app.kubernetes.io/name: web

app.kubernetes.io/component: frontend

spec:

containers:

- name: nginx

image: nginx:stable-alpine

ports:

- name: http

containerPort: 80

resources:

requests:

cpu: 100m

memory: 64Mi

limits:

cpu: 500m

memory: 256Mi

readinessProbe:

httpGet:

path: /

port: http

initialDelaySeconds: 3

periodSeconds: 10

这个示例有几个值得注意的点:

1. Deployment 使用 apps/v1。

2. selector.matchLabels 必须与 template.metadata.labels 匹配,否则资源会被 API 拒绝或控制器无法正确选择 Pod。

3. 容器端口使用名称,后续 Service 和探针可以引用该名称。

4. 为容器设置 requests 和 limits,便于调度和资源控制。

5. readinessProbe 只决定 Pod 是否接收流量;它和 livenessProbe、startupProbe 的用途不同,不要互相替代。

三、标签与注解要分清

标签(labels)用于选择和组织对象,Service、Deployment 以及 kubectl 查询都会依赖标签。推荐采用 app.kubernetes.io/name、app.kubernetes.io/instance、app.kubernetes.io/component 等通用标签。

注解(annotations)用于保存不参与选择的附加信息,例如构建版本、变更说明、工具配置或外部系统标识。不要把大段业务配置硬塞进标签。

四、镜像要可追踪

实验环境可以使用普通标签,但生产环境不要依赖 latest。普通标签可能被重新指向不同镜像,导致同一份 YAML 在不同时间部署出不同内容。

更稳妥的做法是使用明确版本标签,或者固定镜像摘要:

image: example.com/web@sha256:<DIGEST>

同时建议设置合理的 imagePullPolicy,并记录镜像来源和构建版本。

五、不要把 Secret 明文写进仓库

Kubernetes Secret 的 data 字段只是 Base64 编码,并不是加密。密码、Token、私钥和云访问密钥不应直接写入公开仓库。

可以根据环境选择外部密钥管理、加密后的 Secret 工作流或受控的部署系统。无论采用哪种方式,都应限制 RBAC 权限并定期轮换凭据。

六、保持文件可读和可维护

1. 使用空格缩进,不要使用 Tab。

2. 同一项目保持一致的缩进和字段顺序。

3. 给容易被误解析的字符串加引号,例如版本号、布尔值样式字符串和以零开头的值。

4. 一个文件可以用 --- 分隔多个对象,但大型项目最好按应用和环境组织目录。

5. 基础配置与环境差异分离;配置变多时可以使用 Kustomize,复杂模板化场景再考虑 Helm。

6. 不要把从 kubectl get -o yaml 导出的完整对象直接当模板,因为其中往往包含 status、resourceVersion、uid 和 managedFields 等运行时字段。

七、上线前进行四层检查

第一层:检查本地生成结果,不写入集群。

kubectl apply --dry-run=client -f app.yaml

第二层:让 API Server 按真实资源结构验证,但不持久化。

kubectl apply --dry-run=server --validate=strict -f app.yaml

第三层:查看即将发生的差异。

kubectl diff -f app.yaml

第四层:确认后再应用。

kubectl apply -f app.yaml

原笔记中提到的 kubectl validate 并不是常用的独立子命令。更可靠的做法是使用 apply 的 --dry-run 和 --validate=strict,让客户端与 API Server 一起检查字段。

八、应用后继续验证

YAML 被接受不代表应用已经健康。部署后还应检查:

kubectl rollout status deployment/web

kubectl get pod -o wide

kubectl describe deployment web

kubectl get events --sort-by=.metadata.creationTimestamp

重点关注镜像拉取、探针失败、资源不足、调度失败和权限拒绝等事件。

总结

一份好的 Kubernetes YAML,应该同时满足“语法正确、API 正确、关系正确、安全可控、可重复部署”五个条件。先写清期望状态,再通过严格校验和差异预览把问题挡在上线前,比出错后再查日志高效得多。

参考资料:

https://kubernetes.io/docs/concepts/overview/working-with-objects/

https://kubernetes.io/docs/concepts/overview/working-with-objects/common-labels/

https://kubernetes.io/docs/reference/kubectl/generated/kubectl_apply/

原创

如何写好 Kubernetes YAML:从对象结构到上线前校验

本文链接: 如何写好 Kubernetes YAML:从对象结构到上线前校验

本文采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处。

评论交流

文章目录