所有 Kubernetes 资源(无论是 Pod、Service、Deployment、ConfigMap 还是 Ingress)的 YAML 配置文件都遵循统一的顶层结构,包含 apiVersion、kind、metadata 和 spec(大多数情况下)等字段。
这是 Kubernetes 声明式 API 和 资源模型 的基础。

一、K8s YAML 的通用结构(所有资源共用)

apiVersion: <API 组/版本>      # 必填:指定资源类型和版本
kind: <资源类型>               # 必填:如 Pod, Deployment, Service...
metadata:                     # 必填:资源的元数据
  name: <资源名称>
  namespace: <命名空间>       # 可选,默认 default
  labels:
    app: my-app
  annotations:
    description: "This is a demo"
spec:                         # 大多数资源有:定义期望状态(核心内容!)
  # 具体字段因 kind 而异
status:                       # ❌ 用户通常不写!由 K8s 系统自动填充(实际状态)
  phase: Running

✅ 这个结构对所有 K8s 内置资源(Built-in Resources)都适用。

二、各字段详解

1. apiVersion

  • 表示该资源属于哪个 API 组 和 版本
  • 常见值:
    • v1 → 核心组(Pod, Service, Namespace…)
    • apps/v1 → 应用相关(Deployment, StatefulSet, DaemonSet)
    • networking.k8s.io/v1 → 网络(Ingress, NetworkPolicy)
    • batch/v1 → 批处理(Job, CronJob)
    • storage.k8s.io/v1 → 存储(StorageClass)

如何查某个资源的 apiVersion?

kubectl api-resources | grep Deployment
# 输出:deployments   apps/v1

2. kind

  • 资源的类型名称,首字母大写
  • 常见值:Pod, Service, Deployment, ConfigMap, Secret, Ingress, PersistentVolumeClaim…

3. metadata

  • 所有资源必须有,包含标识和管理信息
  • 关键子字段:
    • name:资源名称(集群内唯一)
    • namespace:所属命名空间(Namespaced 资源才有)
    • labels:键值对标签(用于选择器、分组)
    • annotations:非标识性元数据(如构建信息、文档链接)

4. spec

  • 定义用户期望的状态(desired state)
  • 这是你最需要关注的部分!
  • ⚠️ 不同 kind 的 spec 结构完全不同!
    • Pod.spec 包含 containers, volumes…
    • Service.spec 包含 selector, ports, type…
    • Deployment.spec 包含 replicas, template(里面才是 Pod spec)…

✅ 记住:apiVersion + kind 决定了 spec 的结构。

5. status(重要!)

  • 记录资源的实际状态(observed state)
  • 由 K8s 控制平面自动维护,用户通常不写(写了也会被忽略)
  • 例如:Pod 的 status.phase、Deployment 的 status.availableReplicas

三、对比不同资源的 YAML(看相同与不同)

示例 1:Pod

apiVersion: v1
kind: Pod
metadata:
  name: nginx-pod
spec:
  containers:
  - name: nginx
    image: nginx
    ports:
    - containerPort: 80

示例 2:Deployment

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deploy
spec:
  replicas: 2
  selector:
    matchLabels:
      app: nginx
  template:          # ← 注意:这里嵌套了一个 Pod 模板!
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx

示例 3:Service

apiVersion: v1
kind: Service
metadata:
  name: nginx-svc
spec:
  selector:
    app: nginx
  ports:
    - port: 80
      targetPort: 80
  type: ClusterIP

观察:

  • 顶层结构完全一致(apiVersion, kind, metadata, spec)
  • 只有 spec 内容不同,因为它们管理的对象不同

四、自定义资源(CRD)也遵循此结构!

即使是你自己定义的 CRD(Custom Resource Definition),比如 MyDatabase,它的实例 YAML 也长这样:

apiVersion: database.example.com/v1alpha1
kind: MyDatabase
metadata:
  name: my-db
spec:
  size: 10Gi
  version: "5.7"

✅ 这就是 Kubernetes 可扩展性 的体现:所有资源,无论内置还是自定义,都有一致的 API 形状。

五、实用技巧:如何知道某个资源的 YAML 结构?

方法 1:用 kubectl explain

kubectl explain deployment
kubectl explain deployment.spec.template.spec.containers

方法 2:导出现有资源

kubectl get deployment nginx -o yaml

总结

问题 答案
所有 K8s YAML 都有 apiVersion、kind 吗? ✅ 是的!这是强制规范
metadata 是必须的吗? ✅ 是的!至少要有 name
spec 字段都一样吗? ❌ 不一样!它由 kind 决定
我可以自己定义新资源吗? ✅ 可以!通过 CRD,且仍遵循此结构

记住这个公式:

apiVersion + kind = 决定 spec 长什么样

metadata = 资源的“身份证”

status = K8s 填写的“体检报告”

现在看到任何 K8s YAML,都能快速识别它的“骨架”,剩下的就是熟悉各种 spec 的细节了。

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐