文档概述
本文档基于实战案例,系统梳理 Kubernetes 中常用的工作负载控制器与 Pod 调度策略,帮助开发者与运维人员快速掌握 K8s 的应用编排与调度能力。所有案例均基于 Kubernetes v1.23 版本验证,兼容当前主流稳定版本,覆盖从基础副本控制到高级亲和性调度的全流程能力。
一、核心工作负载控制器
工作负载控制器是 Kubernetes 中用来管理 Pod 生命周期的核心资源,不同的控制器针对不同的业务场景设计,用来保证 Pod 按照预期的状态运行。
1.1 副本控制器(ReplicationController, RC)
1.1.1 RC 概述
RC 全称 ReplicationController,是 Kubernetes 早期的副本控制组件,核心作用是保证指定数量的 Pod 副本始终处于运行状态。当集群中 Pod 数量少于预期时,RC 会自动创建新的 Pod;当 Pod 数量超过预期时,RC 会自动删除多余的 Pod,以此保证服务的可用性。
注意:RC 是 Kubernetes 的早期资源,目前已经逐渐被更强大的 ReplicaSet 替代,但理解 RC 的原理有助于理解 Kubernetes 副本控制的演进过程。
1.1.2 实战案例
步骤 1:编写 RC 资源清单
首先定义 RC 的资源配置,指定副本数、标签选择器与 Pod 模板:
apiVersion: v1
kind: ReplicationController
metadata:
name: myapp-rc
labels:
school: myschool
spec:
# 定义需要保证的Pod副本数量
replicas: 3
# RC关联的Pod标签,只有匹配该标签的Pod才会被RC管理
selector:
apps: xiuxian
address: shahe
# Pod模板,用来创建新的Pod
template:
metadata:
labels:
apps: xiuxian
address: shahe
class: class101
spec:
containers:
- name: c1
image: registry.cn-hangzhou.aliyuncs.com/yinzhengjie-k8s/apps:v1
步骤 2:创建 RC 资源
执行创建命令,查看资源状态:
[root@master231 replicationcontrollers]# kubectl apply -f 01-rc-xiuxian.yaml
replicationcontroller/myapp-rc created
[root@master231 replicationcontrollers]# kubectl get rc,pods -o wide --show-labels
NAME DESIRED CURRENT READY AGE CONTAINERS IMAGES SELECTOR LABELS
replicationcontroller/myapp-rc 3 3 3 10s c1 registry.cn-hangzhou.aliyuncs.com/yinzhengjie-k8s/apps:v1 address=shahe,apps=xiuxian school=myschool
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES LABELS
pod/myapp-rc-bmkgb 1/1 Running 0 10s 10.100.1.18 worker232 <none> <none> address=shahe,apps=xiuxian,class=class101
pod/myapp-rc-n9hp5 1/1 Running 0 10s 10.100.2.57 worker233 <none> <none> address=shahe,apps=xiuxian,class=class101
pod/myapp-rc-rw4xd 1/1 Running 0 10s 10.100.2.56 worker233 <none> <none> address=shahe,apps=xiuxian,class=class101
可以看到,删除 Pod 后,RC 立刻创建了 3 个新的 Pod,保证副本数始终为 3,实现了服务的自愈。
步骤 4:级联删除验证
删除 RC 资源,观察关联的 Pod 是否会被一起删除:
[root@master231 replicationcontrollers]# kubectl delete rc --all
replicationcontroller "myapp-rc" deleted
[root@master231 replicationcontrollers]# kubectl get rc,pods -o wide --show-labels
No resources found in default namespace.
删除 RC 后,其管理的所有 Pod 都会被级联删除,避免残留资源。
1.2 副本集(ReplicaSet, RS)
1.2.1 RS 概述
RS 全称 ReplicaSet,是 RC 的升级版本,核心能力和 RC 一致,都是保证 Pod 副本数稳定,但 RS 提供了更强大的功能:
- 支持更灵活的标签选择器,不仅支持精确的键值对匹配,还支持基于表达式的匹配
- 可以接管集群中已存在的 Pod,而 RC 无法做到这一点
RS 是目前 Kubernetes 中主流的副本控制底层组件,Deployment 等高级控制器都是基于 RS 实现的。
1.2.2 实战案例
案例 1:基础副本控制(替代 RC 功能)
RS 可以完全兼容 RC 的功能,通过matchLabels实现精确的标签匹配:
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: rs-xiuxian
labels:
school: myschool
spec:
replicas: 5
selector:
# 基于标签精确匹配,和RC的选择器功能一致
matchLabels:
apps: xiuxian
template:
metadata:
labels:
apps: xiuxian
address: shahe
class: class102
spec:
containers:
- name: c1
image: registry.cn-hangzhou.aliyuncs.com/yinzhengjie-k8s/apps:v1
案例 2:表达式标签匹配(RC 无法实现的能力)
RS 支持matchExpressions实现更灵活的标签匹配,可以实现一对多的标签匹配,甚至接管已存在的 Pod。
步骤 1:环境准备
先创建两个独立的 Pod,没有被任何控制器管理:
[root@master231 replicasets]# kubectl run test01 --image=registry.cn-hangzhou.aliyuncs.com/yinzhengjie-k8s/apps:v1 -l apps=v1 pod/test01 created
[root@master231 replicasets]# kubectl run test02 --image=registry.cn-hangzhou.aliyuncs.com/yinzhengjie-k8s/apps:v2 -l apps=v2 pod/test02 created
[root@master231 replicasets]# kubectl get pods -o wide --show-labels
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES LABELS
test01 1/1 Running 0 13s 10.100.2.71 worker233 <none> <none> apps=v1
test02 1/1 Running 0 7s 10.100.2.72 worker233 <none> <none> apps=v2
步骤 2:编写 RS 资源清单
定义 RS 的选择器,通过表达式匹配apps标签为xiuxian、v1、v2的所有 Pod:
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: rs-xiuxian
labels:
school: cdut
spec:
replicas: 5
selector:
# 基于标签表达式匹配Pod标签
matchExpressions:
- key: apps
values:
- xiuxian
- v1
- v2
# 匹配规则:只要Pod的apps标签的值在列表中,就会被RS管理
operator: In
template:
metadata:
labels:
apps: xiuxian
address: shahe
class: class103
spec:
containers:
- name: c1
image: registry.cn-hangzhou.aliyuncs.com/yinzhengjie-k8s/apps:v1
步骤 3:创建 RS 并验证
创建 RS 后,观察 RS 是否会接管已存在的 Pod:
[root@master231 replicasets]# kubectl apply -f 02-rs-matchExpressions-xiuxian.yaml
replicaset.apps/rs-xiuxian created
[root@master231 replicasets]# kubectl get rs,po -o wide --show-labels
NAME DESIRED CURRENT READY AGE CONTAINERS IMAGES SELECTOR LABELS
replicaset.apps/rs-xiuxian 5 5 5 24s c1 registry.cn-hangzhou.aliyuncs.com/yinzhengjie-k8s/apps:v1 apps in (v1,v2,xiuxian) school=cdut
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES LABELS
pod/rs-xiuxian-88sxz 1/1 Running 0 24s 10.100.1.27 worker232 <none> <none> address=shahe,apps=xiuxian,class=linux95
pod/rs-xiuxian-qtzrb 1/1 Running 0 24s 10.100.1.28 worker232 <none> <none> address=shahe,apps=xiuxian,class=linux95
pod/rs-xiuxian-z9d8b 1/1 Running 0 24s 10.100.2.73 worker233 <none> <none> address=shahe,apps=xiuxian,class=linux95
pod/test01 1/1 Running 0 5m47s 10.100.2.71 worker233 <none> <none> apps=v1
pod/test02 1/1 Running 0 5m41s 10.100.2.72 worker233 <none> <none> apps=v2
可以看到:
- RS 发现已经有 2 个符合条件的已存在 Pod(test01 和 test02)
- 因此 RS 只需要再创建 3 个新的 Pod,就可以凑够 5 个副本,不需要删除已有的 Pod
- 这就是 RC 无法实现的能力,RC 无法接管已存在的 Pod,只能管理自己创建的 Pod
1.3 部署(Deployment)
1.3.1 Deployment 概述
Deployment 是基于 RS 实现的高级工作负载控制器,它不仅拥有 RS 的所有副本控制能力,还提供了声明式更新能力,支持滚动升级、版本回滚、暂停 / 恢复部署等高级编排功能,是 Kubernetes 中管理无状态应用的标准组件。
1.3.2 实战案例
案例 1:基础部署(matchLabels)
Deployment 的基础用法和 RS 类似,通过matchLabels匹配 Pod:
apiVersion: apps/v1
kind: Deployment
metadata:
name: deploy-xiuxian
labels:
school: oldboyedu
spec:
replicas: 5
selector:
matchLabels:
apps: xiuxian
template:
metadata:
labels:
apps: xiuxian
address: shahe
class: linux95
spec:
containers:
- name: c1
image: registry.cn-hangzhou.aliyuncs.com/yinzhengjie-k8s/apps:v1
创建部署后,查看资源状态:
[root@master231 deployments]# kubectl apply -f 01-deploy-matchLabels-xiuxian.yaml
deployment.apps/deploy-xiuxian created
[root@master231 deployments]# kubectl get deploy,rs,pods -o wide
NAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR
deployment.apps/deploy-xiuxian 5/5 5 5 18s c1 registry.cn-hangzhou.aliyuncs.com/yinzhengjie-k8s/apps:v1 apps=xiuxian
NAME DESIRED CURRENT READY AGE CONTAINERS IMAGES SELECTOR
replicaset.apps/deploy-xiuxian-7f85995bf4 5 5 5 18s c1 registry.cn-hangzhou.aliyuncs.com/yinzhengjie-k8s/apps:v1 apps=xiuxian,pod-template-hash=7f85995bf4
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
pod/deploy-xiuxian-7f85995bf4-8ltkx 1/1 Running 0 18s 10.100.1.30 worker232 <none> <none>
pod/deploy-xiuxian-7f85995bf4-96p7r 1/1 Running 0 18s 10.100.2.75 worker233 <none> <none>
pod/deploy-xiuxian-7f85995bf4-gh8wr 1/1 Running 0 18s 10.100.2.74 worker233 <none> <none>
pod/deploy-xiuxian-7f85995bf4-rlmvn 1/1 Running 0 18s 10.100.2.76 worker233 <none> <none>
pod/deploy-xiuxian-7f85995bf4-wzqsd 1/1 Running 0 18s 10.100.1.29 worker232 <none> <none>
可以看到,Deployment 会自动创建对应的 RS,再由 RS 创建 Pod,形成Deployment -> RS -> Pod的层级管理关系。
验证 Deployment 的管理能力
手动删除 Deployment 管理的 RS,观察是否会被重建:
[root@master231 deployments]# kubectl delete rs deploy-xiuxian-7f85995bf4
replicaset.apps "deploy-xiuxian-7f85995bf4" deleted
[root@master231 deployments]# kubectl get deploy,rs,pods -o wide
NAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR
deployment.apps/deploy-xiuxian 5/5 5 5 110s c1 registry.cn-hangzhou.aliyuncs.com/yinzhengjie-k8s/apps:v1 apps=xiuxian
NAME DESIRED CURRENT READY AGE CONTAINERS IMAGES SELECTOR
replicaset.apps/deploy-xiuxian-7f85995bf4 5 5 5 5s c1 registry.cn-hangzhou.aliyuncs.com/yinzhengjie-k8s/apps:v1 apps=xiuxian,pod-template-hash=7f85995bf4
可以看到,删除 RS 后,Deployment 立刻重新创建了一个一模一样的 RS,因为 Deployment 要保证副本数稳定。这说明 RS 是 Deployment 的子资源,我们不应该直接手动管理 RS,所有操作都应该针对 Deployment 进行。
删除 Deployment 时,会级联删除其管理的所有 RS 和 Pod:
[root@master231 deployments]# kubectl delete deployments.apps deploy-xiuxian
deployment.apps "deploy-xiuxian" deleted
[root@master231 deployments]# kubectl get deploy,rs,pods -o wide
No resources found in default namespace.
案例 2:表达式标签匹配(matchExpressions)
和 RS 一样,Deployment 也支持matchExpressions实现灵活的标签匹配:
apiVersion: apps/v1
kind: Deployment
metadata:
name: rs-xiuxian
labels:
school: oldboyedu
spec:
replicas: 5
selector:
matchExpressions:
- key: apps
values:
- xiuxian
- v1
- v2
operator: In
template:
metadata:
labels:
apps: xiuxian
address: shahe
class: linux95
spec:
containers:
- name: c1
image: registry.cn-hangzhou.aliyuncs.com/yinzhengjie-k8s/apps:v1
1.4 守护进程集(DaemonSet)
1.4.1 DaemonSet 概述
DaemonSet 的核心作用是保证集群中每个(或符合条件的)节点上有且仅有一个 Pod 运行。当新节点加入集群时,DaemonSet 会自动在新节点上创建对应的 Pod;当节点从集群中移除时,对应的 Pod 会被垃圾回收。
DaemonSet 的典型适用场景:
- 日志收集 Agent:如 Fluentd、Logstash,每个节点都需要一个日志收集进程
- 节点监控 Agent:如 Prometheus Node Exporter,采集节点的监控指标
- 网络插件:如 CNI 插件,每个节点都需要运行网络组件
- 存储插件:如存储的 Agent 组件
1.4.2 实战案例
编写 DaemonSet 资源清单:
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: ds-xiuxain
labels:
school: oldboyedu
spec:
selector:
matchLabels:
apps: xiuxian
template:
metadata:
labels:
apps: xiuxian
address: shahe
class: linux95
spec:
containers:
- name: c1
image: registry.cn-hangzhou.aliyuncs.com/yinzhengjie-k8s/apps:v1
创建后查看 Pod 状态:
[root@master231 daemonsets]# kubectl apply -f 01-ds-xiuxian.yaml
daemonset.apps/ds-xiuxain created
[root@master231 daemonsets]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
ds-xiuxain-nk5mt 1/1 Running 0 3s 10.100.1.49 worker232 <none> <none>
ds-xiuxain-xvkck 1/1 Running 0 3s 10.100.2.105 worker233 <none> <none>
可以看到,集群中的两个工作节点,每个节点都运行了一个 DaemonSet 的 Pod,符合我们的预期。
1.5 任务(Job)
1.5.1 Job 概述
Job 用来运行一次性任务,任务执行完成后,Pod 就会停止运行,不会再重启。和长期运行的服务不同,Job 的 Pod 在任务完成后就会处于 Completed 状态,不会占用集群的运行资源。
Job 的典型适用场景:
- 批量数据处理
- 数据备份与导出
- 一次性的配置更新
- 视频转码、图片处理等离线任务
1.5.2 实战案例
编写 Job 资源清单,定义一个睡眠 5 秒的一次性任务:
apiVersion: batch/v1
kind: Job
metadata:
name: jobs-xiuxian
labels:
school: oldboyedu
spec:
template:
metadata:
labels:
apps: xiuxian
address: shahe
class: linux95
spec:
# 重启策略:只有任务失败的时候才重启,成功了就不重启
restartPolicy: OnFailure
containers:
- name: c1
image: registry.cn-hangzhou.aliyuncs.com/yinzhengjie-k8s/apps:v1
command:
- sleep
- "5"
创建 Job 后查看状态:
[root@master231 jobs]# kubectl apply -f 01-jobs-xiuxian.yaml
job.batch/jobs-xiuxian created
[root@master231 jobs]# kubectl get jobs,pods -o wide
NAME COMPLETIONS DURATION AGE CONTAINERS IMAGES SELECTOR
job.batch/jobs-xiuxian 1/1 8s 9s c1 registry.cn-hangzhou.aliyuncs.com/yinzhengjie-k8s/apps:v1 controller-uid=fb050d86-7c36-46fc-ae23-b76b17ad9dab
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
pod/jobs-xiuxian-2zlrn 0/1 Completed 0 9s 10.100.2.110 worker233 <none> <none>
可以看到,任务执行完成后,Pod 的状态变成了Completed,Job 的完成数也变成了1/1,表示任务已经成功执行完成。
1.6 定时任务(CronJob)
1.6.1 CronJob 概述
CronJob 是基于 Job 实现的周期性任务控制器,它可以按照指定的时间周期,自动创建 Job 来执行任务。
CronJob 的典型适用场景:
- 定时备份数据库
- 定时生成业务报表
- 定时清理日志文件
- 定期的健康检查
1.6.2 实战案例
编写 CronJob 资源清单,定义一个每分钟执行一次的定时任务:
apiVersion: batch/v1
kind: CronJob
metadata:
name: cj-xiuxian
labels:
school: oldboyedu
spec:
# Cron调度语法:* * * * * 表示每分钟执行一次
schedule: "* * * * *"
# Job模板,CronJob会根据这个模板定期创建Job
jobTemplate:
spec:
template:
metadata:
labels:
apps: xiuxian
address: shahe
class: linux95
spec:
restartPolicy: Never
containers:
- name: c1
image: registry.cn-hangzhou.aliyuncs.com/yinzhengjie-k8s/apps:v1
command:
- /bin/sh
- -c
- date -R; echo "学IT来老男孩,月薪过万不是梦~"
创建 CronJob 后,观察任务的执行情况:
[root@master231 cronjobs]# kubectl apply -f 01-cj-xiuxian.yaml
cronjob.batch/cj-xiuxian created
# 第一次任务执行完成
[root@master231 cronjobs]# kubectl get cj,jobs,pods -o wide
NAME SCHEDULE SUSPEND ACTIVE LAST SCHEDULE AGE CONTAINERS IMAGES SELECTOR
cronjob.batch/cj-xiuxian * * * * * False 0 21s 66s c1 registry.cn-hangzhou.aliyuncs.com/yinzhengjie-k8s/apps:v1 <none>
NAME COMPLETIONS DURATION AGE CONTAINERS IMAGES SELECTOR
job.batch/cj-xiuxian-28988901 1/1 3s 21s c1 registry.cn-hangzhou.aliyuncs.com/yinzhengjie-k8s/apps:v1 controller-uid=af0d20c9-f179-4296-b246-07e447313572
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
pod/cj-xiuxian-28988901-82wkt 0/1 Completed 0 21s 10.100.2.112 worker233 <none> <none>
# 查看任务的输出日志
[root@master231 cronjobs]# kubectl logs cj-xiuxian-28988901-82wkt
Wed, 12 Feb 2025 04:21:00 +0000
学IT来老男孩,月薪过万不是梦~
# 一分钟后,第二次任务执行完成
[root@master231 cronjobs]# kubectl get cj,jobs,pods -o wide
NAME SCHEDULE SUSPEND ACTIVE LAST SCHEDULE AGE CONTAINERS IMAGES SELECTOR
cronjob.batch/cj-xiuxian * * * * * False 0 17s 2m2s c1 registry.cn-hangzhou.aliyuncs.com/yinzhengjie-k8s/apps:v1 <none>
NAME COMPLETIONS DURATION AGE CONTAINERS IMAGES SELECTOR
job.batch/cj-xiuxian-28988901 1/1 3s 77s c1 registry.cn-hangzhou.aliyuncs.com/yinzhengjie-k8s/apps:v1 controller-uid=af0d20c9-f179-4296-b246-07e447313572
job.batch/cj-xiuxian-28988902 1/1 3s 17s c1 registry.cn-hangzhou.aliyuncs.com/yinzhengjie-k8s/apps:v1 controller-uid=acb89a9a-746c-4786-95d3-5b1dd07b1cbe
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
pod/cj-xiuxian-28988901-82wkt 0/1 Completed 0 77s 10.100.2.112 worker233 <none> <none>
pod/cj-xiuxian-28988902-g8p6n 0/1 Completed 0 17s 10.100.2.113 worker233 <none> <none>
可以看到,CronJob 会按照我们定义的周期,每分钟自动创建一个新的 Job 和 Pod 来执行任务,执行完成后 Pod 会保持 Completed 状态,方便我们查看任务的执行日志。
1.7 工作负载控制器对比总结
我们可以通过下表快速对比各个控制器的能力与适用场景:
| 控制器类型 | 核心能力 | 适用场景 | 标签选择器能力 |
| ReplicationController | 保证 Pod 副本数稳定 | 早期无状态应用(已逐步淘汰) | 仅支持精确键值对匹配,无法接管已有 Pod |
| ReplicaSet | 保证 Pod 副本数稳定,灵活标签 | 无状态应用的底层副本控制 | 支持表达式匹配,可接管已有 Pod |
| Deployment | 基于 RS,支持声明式更新、回滚 | 长期运行的无状态应用、微服务 | 同 RS,支持完整的应用编排管理 |
| DaemonSet | 每个节点运行一个 Pod | 节点监控、日志收集、网络插件 | 同 RS,自动适配节点变化 |
| Job | 一次性任务,执行完成即结束 | 批量计算、数据备份、离线任务 | 同 RS,任务完成后自动停止 |
| CronJob | 周期性执行任务 | 定时备份、定时报表、周期任务 | 基于 Job,支持 Cron 周期调度 |