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 资源类型 |
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) 的分离。这种模式使得控制器可以持续协调,将系统从当前状态驱动到期望状态。
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,可指定或自动分配 |
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) 进行转换,确保向后兼容。
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 字段判断资源版本。对于跨版本的策略逻辑,建议使用内部版本进行统一处理,避免为每个外部版本编写重复的校验代码。