当你需要在 Kubernetes 上运行一个应用时,直接创建 Pod 是最简单的方式——但 Pod 不会自动重启、不会自动扩缩、不会滚动更新。生产环境中,你需要更高级的工作负载管理器来确保应用的可靠性。
Kubernetes 提供了多种工作负载类型,每种都有明确的设计意图:Deployment 管理无状态应用,StatefulSet 管理有状态应用,DaemonSet 确保每个节点运行一个实例,Job 处理一次性任务。理解它们的区别和适用场景,是正确使用 Kubernetes 的关键。
一、Pod 生命周期与探针
Pod 是所有工作负载的基础。理解 Pod 的生命周期和健康检查机制,是掌握上层工作负载的前提。
1.1 Pod 的启动流程
Init 容器用于 Pod 启动前的初始化工作——等待依赖服务就绪、下载配置文件、注册服务发现。它们按顺序执行,全部成功后主容器才启动。
1.2 三种探针
| 探针 | 目的 | 失败后果 | 典型配置 |
|---|---|---|---|
| Startup Probe | 判断容器是否已启动 | 重启容器 | 慢启动应用(periodSeconds: 10, failureThreshold: 30) |
| Liveness Probe | 判断容器是否健康运行 | 重启容器 | HTTP 健康检查或进程存活检查 |
| Readiness Probe | 判断容器是否可接收请求 | 从 Service Endpoints 移除 | 检查依赖是否就绪 |
spec: containers: - name: my-app image: my-app:v1 startupProbe: httpGet: path: /healthz port: 8080 periodSeconds: 10 failureThreshold: 30 # 最多等待 300 秒启动 livenessProbe: httpGet: path: /healthz port: 8080 periodSeconds: 15 failureThreshold: 3 # 连续 3 次失败则重启 readinessProbe: httpGet: path: /ready port: 8080 periodSeconds: 5 failureThreshold: 3 # 连续 3 次失败则移出 EndpointsStartup Probe 是 Kubernetes 1.18 引入的,专门解决慢启动应用的问题。在此之前,开发者只能通过设置较长的 initialDelaySeconds 来等待容器启动,但这会导致快速启动的应用也要等待相同时间。Startup Probe 启用后,Liveness Probe 只在 Startup Probe 成功后才开始检查,两者互不干扰。
1.3 重启策略
| 策略 | 说明 | 适用工作负载 |
|---|---|---|
| Always | 容器退出后总是重启 | Deployment、ReplicaSet、StatefulSet |
| OnFailure | 只有非零退出码才重启 | Job |
| Never | 从不重启 | CronJob(一次性任务) |
二、ReplicaSet:副本数量管理
ReplicaSet 确保指定数量的 Pod 副本始终运行。它是 Deployment 的底层实现,通常不直接使用。
apiVersion: apps/v1kind: ReplicaSetmetadata: name: nginx-rsspec: replicas: 3 # 期望副本数 selector: matchLabels: app: nginx # 必须匹配 Pod 的 Label template: # Pod 模板 metadata: labels: app: nginx spec: containers: - name: nginx image: nginx:1.25ReplicaSet 控制器的工作逻辑:
- 计算当前匹配
selector的 Pod 数量 - 如果数量 <
replicas:按template创建新 Pod - 如果数量 >
replicas:按优先级删除多余 Pod - 如果 Pod 失败退出:自动重建
ReplicaSet 的 selector 必须匹配 template.metadata.labels,否则 ReplicaSet 无法管理自己创建的 Pod。Kubernetes API 会验证这一约束。
三、Deployment:滚动更新与回滚
Deployment 是最常用的工作负载类型。它在 ReplicaSet 之上增加了版本管理和滚动更新能力。
3.1 Deployment 与 ReplicaSet 的关系
每次更新 Deployment 的 Pod 模板(如修改 image 版本),Deployment 会创建一个新的 ReplicaSet,并逐步将流量从旧 ReplicaSet 迁移到新 ReplicaSet。旧 ReplicaSet 不会被删除——它保留着回滚所需的历史版本。
3.2 滚动更新策略
spec: strategy: type: RollingUpdate rollingUpdate: maxSurge: 1 # 更新时最多多创建 1 个 Pod(可以是百分比) maxUnavailable: 0 # 更新时最多允许 0 个 Pod 不可用| 参数 | 说明 | 默认值 |
|---|---|---|
maxSurge | 更新过程中超出期望副本数的最大 Pod 数 | 25% |
maxUnavailable | 更新过程中不可用 Pod 的最大数量 | 25% |
maxSurge=1, maxUnavailable=0 的更新过程:
整个过程始终保持至少 3 个可用 Pod,服务不中断。
3.3 回滚
# 查看 Deployment 的历史版本kubectl rollout history deployment/nginx
# 回滚到上一个版本kubectl rollout undo deployment/nginx
# 回滚到指定版本kubectl rollout undo deployment/nginx --to-revision=2
# 查看回滚状态kubectl rollout status deployment/nginxDeployment 默认保留 10 个历史 ReplicaSet(通过 revisionHistoryLimit 控制)。回滚时,Deployment 将旧 ReplicaSet 的副本数恢复到期望值,同时缩容当前 ReplicaSet。
四、StatefulSet:有状态应用
Deployment 适合无状态应用——任何 Pod 都可以处理任何请求,Pod 之间没有区别。但有状态应用(如数据库、消息队列)需要稳定的网络标识、持久化存储和有序的部署/终止。
4.1 StatefulSet 提供的保证
| 保证 | 说明 | Deployment 是否提供 |
|---|---|---|
| 稳定网络标识 | Pod 名称有序且固定(statefulset-name-0, -1, -2) | 否 |
| 稳定持久化存储 | 每个 Pod 绑定独立的 PVC,Pod 重建后重新挂载同一 PVC | 否 |
| 有序部署 | Pod 按 0→1→2 的顺序创建,前一个 Ready 后才创建下一个 | 否 |
| 有序终止 | Pod 按 2→1→0 的逆序删除 | 否 |
apiVersion: apps/v1kind: StatefulSetmetadata: name: mysqlspec: serviceName: mysql # 必须指定 Headless Service replicas: 3 selector: matchLabels: app: mysql template: metadata: labels: app: mysql spec: containers: - name: mysql image: mysql:8.0 volumeMounts: - name: data mountPath: /var/lib/mysql volumeClaimTemplates: # 每个 Pod 自动创建独立 PVC - metadata: name: data spec: accessModes: ["ReadWriteOnce"] resources: requests: storage: 10GiStatefulSet 必须配合 Headless Service 使用。Headless Service 的 clusterIP 为 None,DNS 查询直接返回每个 Pod 的 IP,而不是 Service VIP:
apiVersion: v1kind: Servicemetadata: name: mysqlspec: clusterIP: None # Headless Service selector: app: mysql ports: - port: 3306Pod 的 DNS 名称格式为 mysql-0.mysql.default.svc.cluster.local,无论 Pod 重建多少次,这个名称始终指向同一个 PVC 和同一个数据。
4.2 StatefulSet vs Deployment
| 场景 | 选择 | 原因 |
|---|---|---|
| Web 服务、API 服务 | Deployment | 无状态,Pod 之间无区别 |
| MySQL 主从集群 | StatefulSet | 主从角色不同,需要稳定标识和持久化 |
| Redis Cluster | StatefulSet | 每个节点有独立数据,需要稳定网络标识 |
| Kafka 集群 | StatefulSet | Broker ID 需要固定,日志目录需要持久化 |
五、DaemonSet:每个节点一个 Pod
DaemonSet 确保每个(或特定)Node 上运行一个 Pod 副本。典型用途:
- 日志收集:每个节点运行 Fluentd/Filebeat
- 监控代理:每个节点运行 Prometheus Node Exporter
- 网络插件:每个节点运行 Calico/Cilium CNI agent
- 存储插件:每个节点运行 CSI node driver
apiVersion: apps/v1kind: DaemonSetmetadata: name: node-exporterspec: selector: matchLabels: app: node-exporter template: metadata: labels: app: node-exporter spec: tolerations: # 容忍 Master 节点的污点 - key: node-role.kubernetes.io/control-plane effect: NoSchedule containers: - name: node-exporter image: prom/node-exporter ports: - containerPort: 9100 hostPort: 9100 # 暴露到宿主机端口当新 Node 加入集群时,DaemonSet 自动在该 Node 上创建 Pod;当 Node 移除时,Pod 自动被回收。replicas 字段不需要指定——副本数等于匹配的 Node 数量。
六、Job 与 CronJob:批处理任务
Job 用于运行一次性任务,确保任务成功完成。CronJob 用于定时执行 Job。
6.1 Job
apiVersion: batch/v1kind: Jobmetadata: name: data-migrationspec: completions: 5 # 需要成功完成 5 次 parallelism: 2 # 最多 2 个 Pod 并行执行 backoffLimit: 6 # 最多重试 6 次 template: spec: restartPolicy: OnFailure # Job 使用 OnFailure 或 Never containers: - name: migrate image: my-migrate-tool| 参数 | 说明 |
|---|---|
completions | 需要成功完成的 Pod 总数 |
parallelism | 同时运行的 Pod 最大数量 |
backoffLimit | 失败重试上限,超过后 Job 标记为 Failed |
6.2 CronJob
apiVersion: batch/v1kind: CronJobmetadata: name: daily-backupspec: schedule: "0 2 * * *" # 每天 2:00 执行 concurrencyPolicy: Forbid # 禁止并发执行 successfulJobsHistoryLimit: 3 failedJobsHistoryLimit: 1 jobTemplate: spec: template: spec: restartPolicy: OnFailure containers: - name: backup image: my-backup-tool| concurrencyPolicy | 说明 |
|---|---|
| Allow | 允许并发执行(默认) |
| Forbid | 禁止并发,上次未完成则跳过本次 |
| Replace | 替换上次未完成的 Job |
七、HPA:自动扩缩容
Horizontal Pod Autoscaler(HPA)根据指标自动调整 Deployment/StatefulSet 的副本数。
apiVersion: autoscaling/v2kind: HorizontalPodAutoscalermetadata: name: nginx-hpaspec: scaleTargetRef: apiVersion: apps/v1 kind: Deployment name: nginx minReplicas: 2 maxReplicas: 10 metrics: - type: Resource resource: name: cpu target: type: Utilization averageUtilization: 50 # CPU 使用率超过 50% 时扩容HPA 的扩缩逻辑:
- 当前 CPU 使用率 > 50%:增加副本数
- 当前 CPU 使用率 < 50%:减少副本数
- 副本数变化有冷却期(默认 5 分钟),防止频繁抖动
# 查看 HPA 状态kubectl get hpa
# 输出示例NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGEnginx-hpa Deployment/nginx 45%/50% 2 10 3 5mHPA 需要集群中安装 Metrics Server(kubectl top pods 可用时 HPA 才能工作)。对于自定义指标(如 QPS、队列长度),需要配置 Prometheus Adapter。
总结
| 工作负载 | 设计意图 | 关键特性 | 典型场景 |
|---|---|---|---|
| Pod | 最小调度单元 | 容器共享网络/存储 | 手动调试、单次任务 |
| ReplicaSet | 副本数量管理 | 维持固定副本数 | Deployment 的底层实现 |
| Deployment | 无状态应用管理 | 滚动更新、回滚、版本管理 | Web 服务、API 服务 |
| StatefulSet | 有状态应用管理 | 稳定标识、持久化、有序部署 | 数据库、消息队列 |
| DaemonSet | 节点守护进程 | 每个 Node 一个 Pod | 日志收集、监控代理 |
| Job | 一次性任务 | 确保成功完成 | 数据迁移、批处理 |
| CronJob | 定时任务 | Cron 表达式调度 | 定时备份、报表生成 |
| HPA | 自动扩缩容 | 基于指标调整副本数 | 流量波动大的服务 |
下一章将深入 Kubernetes 的服务发现与网络基础——Service 如何为 Pod 提供稳定访问入口,Ingress 如何将外部流量引入集群。
支持与分享
如果这篇文章对你有帮助,欢迎支持作者或分享给更多人
部分信息可能已经过时






