Kubernetes 对象规约(Spec)与状态(Status)
一、核心概念对比
维度 | 规约(Spec) | 状态(Status) |
---|---|---|
定义方 | 用户声明 | 系统生成 |
修改权限 | 用户可编辑 | 只读(由控制器维护) |
内容示例 | 副本数、镜像版本、资源限制 | 实际副本数、Pod状态、最后更新时间 |
设计目的 | 描述期望状态 | 反映实际状态 |
更新触发 | 用户手动修改 | 控制器自动同步 |
二、规约(Spec)深度解析
1. 核心字段结构
apiVersion: apps/v1
kind: Deployment
spec: # ReplicaSet 规约
selector: # 标签选择器
matchLabels:
app: nginx
replicas: 3 # 期望副本数
strategy: # 更新策略
type: RollingUpdate
template: # Pod模板
metadata:
labels:
app: nginx
spec: # Pod 规约
containers:
- name: nginx
image: nginx:1.25
resources:
limits:
cpu: "1"
2. 关键设计原则
- 声明式配置:描述"应该是什么"而非操作步骤
- 幂等性:多次应用相同配置结果一致
- 字段强校验:API Server会拒绝非法字段
3. 多层级Spec示例
graph TD A[Deployment Spec] --> B[ReplicaSet Spec] B --> C[Pod Spec] C --> D[Container Spec]
三、状态(Status)详细机制
1. 典型状态结构
status:
availableReplicas: 2
conditions:
- type: Available
status: "True"
lastUpdateTime: "2025-05-01T12:00:00Z"
observedGeneration: 1 # 对应的Spec版本
2. 状态类型详解
Pod状态相位(Phase)
状态 | 触发条件 |
---|---|
Pending | 容器未完全启动 |
Running | 至少一个容器运行中 |
Succeeded | 所有容器成功退出(Job场景) |
Failed | 所有容器终止且至少一个失败 |
Unknown | 节点通信异常 |
状态条件(Conditions)
conditions:
- type: Ready
status: "True"
reason: PodCompleted
message: "All containers have terminated successfully"
四、状态同步流程
1. 控制器工作序列
sequenceDiagram participant User participant APIServer participant Controller participant etcd User->>APIServer: kubectl apply -f spec.yaml APIServer->>etcd: 存储Spec Controller->>APIServer: Watch资源变更 Controller->>etcd: 获取当前状态 alt 状态不符 Controller->>APIServer: 执行调谐操作 end APIServer->>etcd: 更新Status
2. 版本控制机制
metadata.generation
:Spec 版本号
-
作用:记录资源规格(
spec
)的变更次数,是一个单调递增的整数。 -
触发条件: 每次用户修改资源的
spec
字段(如更新镜像、调整副本数)时,metadata.generation
会自动加 1。 -
意义
:
- 表示资源的期望状态(
spec
)的版本号。 - 例如,初始创建时
generation=1
,第一次修改后变为generation=2
。
- 表示资源的期望状态(
status.observedGeneration
:最后处理的 Spec 版本
- 作用:记录控制器最后一次成功处理的
spec
版本号。 - 更新逻辑:
- 控制器在协调(Reconcile)资源时,会检查当前
spec
的generation
是否大于status.observedGeneration
。 - 如果是,则执行状态更新逻辑(如创建/删除 Pod),完成后将
observedGeneration
更新为当前的generation
。
- 控制器在协调(Reconcile)资源时,会检查当前
- 意义:
- 标识控制器是否已处理最新的
spec
。若两者相等,说明资源状态已与最新期望状态同步;若不相等,说明控制器可能未响应或处理中。
- 标识控制器是否已处理最新的
# 获取名为 nginx 的 Deployment 资源的 metadata.generation 字段值,即该 Deployment 的 Spec 版本号。
kubectl get deploy nginx -o jsonpath='{.metadata.generation}'
五、高级应用模式
1. 状态自动修复
# Pod Disruption Budget示例
apiVersion: policy/v1
kind: PodDisruptionBudget
spec:
minAvailable: 2
selector:
matchLabels:
app: nginx
Pod Disruption Budget (PDB) 是 Kubernetes 中用于保护应用在自愿中断(如节点维护、集群缩容等)时保持可用性的机制。你提供的 YAML 示例定义了一个 PDB,通过 minAvailable: 2
确保标签为 app: nginx
的 Pod 在中断时至少有 2 个副本保持运行。以下是具体解析和注意事项:
核心字段解析
minAvailable: 2
表示即使发生自愿中断(如kubectl drain
),也必须保证至少 2 个匹配selector
的 Pod 处于可用状态。例如:- 如果当前有 3 个
app: nginx
的 Pod,Kubernetes 最多只允许驱逐 1 个(剩下 2 个可用) - 如果当前只有 2 个 Pod,则不允许任何驱逐操作,否则会违反 PDB 规则。
- 如果当前有 3 个
selector.matchLabels
指定 PDB 作用的 Pod 范围,必须与目标 Pod 的标签匹配。例如,这里的app: nginx
需对应 Deployment/StatefulSet 中 Pod 的标签
使用场景与行为逻辑
- 适用场景:
- 适用于由控制器(如 Deployment、StatefulSet)管理的多副本应用,确保高可用性。
- 典型场景包括节点升级、手动驱逐 Pod 或集群自动缩容。
- 与
maxUnavailable
的区别:minAvailable
是保证“最少可用数量”,而maxUnavailable
是限制“最大不可用数量”。两者不能同时定义- 例如
maxUnavailable: 1
表示最多允许 1 个 Pod 不可用,适用于滚动更新时控制中断比例
- 百分比与整数的选择:
minAvailable
可以是整数(如2
)或百分比(如"50%"
)。百分比会根据 Pod 总数向上取整(例如 7 个 Pod 的 50% 会被计算为 4 个)。
注意事项
- 非自愿中断不生效:PDB 仅针对自愿中断(如
kubectl drain
),节点故障等非自愿中断不受 PDB 限制 - 控制器兼容性:
- PDB 通常配合 Deployment/StatefulSet 使用,若使用自定义控制器需确保启用
scale
子资源。 - 单实例应用可设置
maxUnavailable: 0
,但需与运维团队协调手动操作。
- PDB 通常配合 Deployment/StatefulSet 使用,若使用自定义控制器需确保启用
- 冲突与优先级: 如果 PDB 要求与资源实际状态冲突(如副本数不足),驱逐操作会被拒绝。
2. 自定义状态扩展
# CRD状态字段示例
status:
customStatus: "Healthy"
lastProbeTime: "2025-05-01T12:00:00Z"
如果用户通过 status: customStatus: “Healthy” lastProbeTime: “2025-05-01T12:00:00Z”
这项设置自定义状态,但是当运行后,程序会根据检测结果再次自动再更新到customStatus字段对应的状态,并更新lastProbeTime时间。
评论需开启科学上网!