2. 核心 API 资源模型:Pod、Service、Deployment 等核心资源的 Group/Version/Kind 结构、资源元数据与 Spec/Status 设计模式

Kubernetes 的声明式 API 是控制平面的核心交互界面。每个资源对象都遵循统一的 Group/Version/Kind (GVK) 标识体系,并采用 Spec/Status 设计模式来分离用户期望状态与系统实际状态。本章将深入剖析 Pod、Service、Deployment 等核心资源的 GVK 结构、元数据规范以及 Spec/Status 的实现细节。

2.1 Group/Version/Kind (GVK) 标识体系

Kubernetes API 使用 GVK 三元组唯一标识一个资源类型。Group 表示资源的功能域(如 apps、networking.k8s.io),Version 表示 API 的成熟度(如 v1、v1beta1),Kind 表示资源的具体类型(如 Pod、Deployment)。

资源类型 API Group Version Kind 核心用途
Pod core (空字符串) v1 Pod 运行容器的最小调度单元
Service core (空字符串) v1 Service 提供稳定的网络访问入口
Deployment apps v1 Deployment 声明式管理无状态工作负载
StatefulSet apps v1 StatefulSet 管理有状态工作负载
Ingress networking.k8s.io v1 Ingress 七层负载均衡与路由
CustomResourceDefinition apiextensions.k8s.io v1 CustomResourceDefinition 扩展 API 资源类型
关键理解: GVK 是 API 路由的核心。当客户端发起请求时,API Server 通过 Group 确定路由前缀,通过 Version 选择序列化/反序列化版本,通过 Kind 确定资源行为。例如 apps/v1/Deployment 的完整 REST 路径为 /apis/apps/v1/namespaces/{ns}/deployments。

2.2 资源元数据 (ObjectMeta) 设计

每个 Kubernetes 资源都包含一个 metadata 字段,用于描述资源的标识、标签、注解、所有权和生命周期信息。元数据是资源模型的基础层,所有 GVK 资源共享同一套元数据结构。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  namespace: production
  labels:
    app: nginx
    tier: frontend
  annotations:
    deployment.kubernetes.io/revision: "3"
    prometheus.io/scrape: "true"
  ownerReferences:
    - apiVersion: apps/v1
      kind: ReplicaSet
      name: nginx-deployment-7d8f9c
      uid: a1b2c3d4-e5f6-7890-abcd-ef1234567890
  finalizers:
    - foregroundDeletion
  managedFields:
    - manager: kube-controller-manager
      operation: Update
      apiVersion: apps/v1
      fieldsType: FieldsV1
      fieldsV1:
        f:spec:
          f:replicas: {}
元数据字段 类型 说明
name string 资源在当前命名空间内的唯一标识,符合 DNS-1123 子域名规范
namespace string 资源所属的逻辑隔离空间,集群级别资源(如 Node)不包含此字段
labels map[string]string 用于资源分组、选择器和查询的键值对,支持基于标签的关联
annotations map[string]string 用于存储非标识性元数据,如工具信息、构建版本、策略配置
ownerReferences []OwnerReference 声明资源的所有者,用于级联删除和垃圾回收
finalizers []string 删除前的预清理钩子,阻止立即删除直到所有 finalizer 被移除
resourceVersion string 资源版本号,用于乐观锁和 Watch 机制
uid string 资源在整个集群生命周期内的唯一标识,不可变更
最佳实践: 使用 labels 进行资源选择(如 Service 选择 Pod),使用 annotations 存储非查询性配置(如 Prometheus 抓取配置、Ingress 重写规则)。避免在 labels 中存储大体积或频繁变化的数据,因为 labels 被用于索引和查询。

2.3 Spec/Status 设计模式

Kubernetes 资源模型的核心设计哲学是 声明式期望状态 (Spec) 与观测实际状态 (Status) 的分离。这种模式使得控制器可以持续协调,将系统从当前状态驱动到期望状态。

Spec/Status 协调循环设计模式 用户 / 客户端 Spec (期望状态) Status (实际状态) 控制器 (协调循环) 写入 / 更新 Watch / 读取 更新状态 调谐 实际系统 反馈 / 观测 读取 核心原则:用户只写 Spec,控制器只写 Status。Status 反映系统真实状态,Spec 表达用户期望,二者差异驱动协调循环。

2.4 核心资源 Spec/Status 深度解析

2.4.1 Pod:原子调度单元

Pod 是 Kubernetes 中最小的部署和调度单元。其 Spec 定义了容器的运行期望,Status 则反映 Pod 的生命周期阶段和网络信息。

apiVersion: v1
kind: Pod
metadata:
  name: web-pod
  labels:
    app: web
spec:
  containers:
    - name: nginx
      image: nginx:1.25
      ports:
        - containerPort: 80
      resources:
        requests:
          memory: "64Mi"
          cpu: "250m"
        limits:
          memory: "128Mi"
          cpu: "500m"
  restartPolicy: Always
  nodeSelector:
    disktype: ssd
status:
  phase: Running
  conditions:
    - type: Ready
      status: "True"
      lastTransitionTime: "2024-01-15T10:30:00Z"
  hostIP: 10.0.0.5
  podIP: 192.168.1.10
  containerStatuses:
    - name: nginx
      ready: true
      restartCount: 0
      state:
        running:
          startedAt: "2024-01-15T10:30:05Z"
Pod Spec 关键字段 说明
containers 定义容器镜像、端口、资源请求/限制、环境变量、挂载卷
initContainers 在主容器之前运行的初始化容器,完成前置条件
volumes 定义 Pod 级别的存储卷,供容器挂载
nodeSelector 将 Pod 调度到具有特定标签的节点
restartPolicy 容器退出后的重启策略:Always、OnFailure、Never
Pod Status 关键字段 说明
phase Pod 生命周期阶段:Pending、Running、Succeeded、Failed、Unknown
conditions Pod 的详细状态条件数组,如 PodScheduled、Ready、Initialized、ContainersReady
podIP Pod 在集群网络中的 IP 地址,由 CNI 插件分配
containerStatuses 每个容器的详细状态,包括重启次数、就绪状态、当前状态(Waiting/Running/Terminated)

2.4.2 Service:稳定的网络抽象

Service 为一组动态变化的 Pod 提供稳定的网络端点。其 Spec 定义了选择器和端口映射,Status 则包含负载均衡的端点信息。

apiVersion: v1
kind: Service
metadata:
  name: web-service
spec:
  selector:
    app: web
  ports:
    - protocol: TCP
      port: 80
      targetPort: 8080
  type: ClusterIP
  clusterIP: 10.96.0.1
status:
  loadBalancer:
    ingress:
      - ip: 203.0.113.10
  conditions:
    - type: LoadBalancerReady
      status: "True"
Service Spec 关键字段 说明
selector 标签选择器,用于匹配后端 Pod
ports 端口映射定义,包括 port(Service 端口)、targetPort(Pod 端口)、nodePort(NodePort 类型时使用)
type 服务类型:ClusterIP、NodePort、LoadBalancer、ExternalName
clusterIP Service 在集群内部的虚拟 IP,可指定或自动分配
注意: Service 的 status.loadBalancer.ingress 仅在 type: LoadBalancer 且云厂商 LB 就绪后才会填充。对于 ClusterIP 类型,Status 主要包含 conditions 字段,用于反映 Service 的健康状态。

2.4.3 Deployment:声明式工作负载管理

Deployment 是管理无状态应用最常用的资源。它通过 ReplicaSet 实现 Pod 的滚动更新、回滚和扩缩容。其 Spec 定义了副本数、更新策略和 Pod 模板,Status 则跟踪更新进度和可用性。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxUnavailable: 1
      maxSurge: 1
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
        - name: nginx
          image: nginx:1.25
          ports:
            - containerPort: 80
status:
  observedGeneration: 3
  replicas: 3
  updatedReplicas: 3
  readyReplicas: 3
  availableReplicas: 3
  conditions:
    - type: Available
      status: "True"
      lastUpdateTime: "2024-01-15T11:00:00Z"
      reason: MinimumReplicasAvailable
    - type: Progressing
      status: "True"
      reason: NewReplicaSetAvailable
Deployment Spec 关键字段 说明
replicas 期望的 Pod 副本数量
selector 标签选择器,必须与 Pod 模板中的 labels 匹配
strategy 更新策略:RollingUpdate(滚动更新)或 Recreate(重建)
template Pod 模板,定义 Pod 的完整 Spec
revisionHistoryLimit 保留的历史版本数量,用于回滚
Deployment Status 关键字段 说明
observedGeneration 控制器最后观测到的 Spec 版本号,用于检测 Spec 是否已被处理
replicas 当前管理的 Pod 总数
updatedReplicas 已更新到最新版本的 Pod 数量
readyReplicas 就绪探针通过的 Pod 数量
availableReplicas 可用于服务流量的 Pod 数量(就绪且运行超过 minReadySeconds)
conditions Deployment 的可用性和进度条件,用于判断更新是否成功

2.5 资源模型版本演进与兼容性

Kubernetes 通过 API 版本机制管理资源模型的演进。不同版本之间通过 内部版本 (Internal Version) 进行转换,确保向后兼容。

API 版本转换与内部版本机制 v1alpha1 实验性版本 v1beta1 Beta 版本 v1 (GA) 内部版本 (Internal Version) etcd 存储 (内部版本序列化) 所有外部版本在写入 etcd 前都转换为内部版本存储;读取时从内部版本转换为请求的外部版本。这种设计使得新增 API 版本无需迁移 etcd 数据。

2.6 资源模型准入策略适配要点

当 API 版本演进时,资源模型的 Spec 字段可能发生变化。准入控制器(如 MutatingWebhook、ValidatingWebhook)需要适配不同版本的资源模型,确保策略的正确执行。

  • 版本感知的默认值注入: MutatingWebhook 需要根据请求的 API 版本注入对应版本的默认值。例如,apps/v1beta1 的 Deployment 可能缺少 spec.progressDeadlineSeconds 字段,而 apps/v1 则必须包含。
  • 字段兼容性检查: ValidatingWebhook 应验证字段在不同版本间的兼容性。例如,v1 中废弃的字段在 v1beta1 中可能仍然可用,但应发出警告。
  • 转换 Webhook 的字段映射: 对于 CRD 的自定义版本,ConversionWebhook 需要正确处理 Spec 和 Status 字段的映射关系,确保数据不丢失。
  • Status 子资源的写保护: 准入控制器应确保普通用户无法直接修改 Status 字段,只有控制器和具有 update/status 权限的主体才能写入 Status。
实践建议: 在编写准入策略时,始终使用 request.object 和 request.oldObject 的 apiVersion 字段判断资源版本。对于跨版本的策略逻辑,建议使用内部版本进行统一处理,避免为每个外部版本编写重复的校验代码。