一、rc控制器和rs控制器
1.1rc控制器(ReplicationController)
bash
# ============================================================
# ReplicationController(RC)控制器配置
# 作用:确保集群中始终运行指定数量的 Pod 副本
# 注意:RC 是较老版本的控制器,新版本推荐使用 ReplicaSet 或 Deployment
# ============================================================
apiVersion: v1 # RC 使用 v1 版本的 API(不是 apps/v1)
kind: ReplicationController # 资源类型:ReplicationController
metadata:
name: rc-demo # RC 自身名称,全局唯一
spec:
# ----- 副本数量配置 -----
replicas: 3 # 期望运行的 Pod 数量(集群会始终维持 3 个)
# ----- 选择器(重要!) -----
# 作用:定义 RC 管理哪些 Pod(通过标签筛选)
# 注意:与 ReplicaSet 不同,RC 的 selector 只支持简单的标签匹配,不支持 matchLabels/matchExpressions
# 这里的标签必须与 template.metadata.labels 完全一致
selector:
app: rc-demo # 筛选出所有标签为 app=rc-demo 的 Pod
# ----- Pod 模板(蓝图) -----
# 作用:当需要创建新 Pod 时,就按照这个模板生成
template:
metadata:
labels: # 为 Pod 打上标签(必须覆盖 selector 中的标签)
app: rc-demo # 这行就是 selector 要找的标签
spec: # Pod 内部规格定义
containers:
- name: rc-demo-container # 容器名称
image: wangyanglinux/myapp:v1.0 # 容器镜像
# ----- 环境变量(注入到容器内部) -----
# 作用:将配置信息以 key-value 形式注入容器,应用可通过 process.env 读取
env:
- name: GET_HOSTS_FROM # 环境变量名 ①
value: "dns" # 取值:dns 表示服务发现优先使用 DNS
- name: zhangsan # 环境变量名 ②(示例:自定义变量)
value: "123" # 取值:字符串 "123"
# ----- 容器端口声明 -----
# 作用:声明容器监听哪个端口(仅起文档/可视化作用,不影响实际网络通信)
ports:
- containerPort: 80 # 应用监听 80 端口(如 myapp 的 Web 服务)
1.2、rs控制器(ReplicaSet)
bash
# ============================================================
# ReplicaSet 控制器配置
# 作用:确保集群中始终运行指定数量的 Pod 副本
# ============================================================
apiVersion: apps/v1 # 使用 apps 组 v1 版本的 API
kind: ReplicaSet # 资源类型:副本集控制器
metadata:
name: rs-ml-demo # ReplicaSet 自身名称,全局唯一
spec:
# ----- 副本数量配置 -----
replicas: 3 # 期望运行的 Pod 数量(集群会始终维持 3 个)
# ----- 选择器(重要!) -----
# 作用:定义 ReplicaSet 管理哪些 Pod(通过标签筛选)
# 注意:此处的 labels 必须与 template 中定义的 labels 完全一致
selector:
matchLabels: # 匹配标签规则(只能使用 matchLabels,不支持复杂的 matchExpressions)
app: rs-ml-demo # 筛选出所有标签为 app=rs-ml-demo 的 Pod
# ----- Pod 模板(蓝图) -----
# 作用:当需要创建新 Pod 时,就按照这个模板生成
template:
metadata:
labels: # 为 Pod 打上标签(必须覆盖 selector 中的标签)
app: rs-ml-demo # 这行就是 selector 要找的标签
spec: # Pod 内部规格定义
containers:
- name: rs-ml-demo-container # 容器名称
image: wangyanglinux/myapp:v1.0 # 容器镜像
# ----- 环境变量(注入到容器内部) -----
# 作用:将配置信息以 key-value 形式注入容器,应用可通过 process.env 读取
env:
- name: GET_HOSTS_FROM # 环境变量名
value: "dns" # 取值:dns 表示服务发现优先使用 DNS(常见于旧版 k8s 示例)
# 备注:此变量在较新版本的 Kubernetes 中已非必需,属于历史遗留配置
# ----- 容器端口声明 -----
# 作用:声明容器监听哪个端口(仅起文档/可视化作用,不影响实际网络通信)
ports:
- containerPort: 80 # 应用监听 80 端口(如 myapp 的 Web 服务)
1.3、两者差别
官方推荐使用rs控制器
| 对比维度 | ReplicationController(旧) | ReplicaSet(新) |
|---|---|---|
| API 版本 | apiVersion: v1 |
apiVersion: apps/v1 |
| 标签选择器能力 | ❌ 仅支持等值匹配 (key=value) |
✅ 支持等值匹配 + 集合式匹配 |
| selector 写法 | 直接写 app: rc-demo |
支持 matchLabels 和 matchExpressions 两种方式 |
| 官方推荐 | ❌ 已弃用,不建议使用 | ✅ 推荐使用(但通常由 Deployment 自动管理) |
| 实际用途 | 历史遗留,仅用于理解旧版概念 | 作为 Deployment 的底层组件,不单独使用 |
1.4、rs控制器优势
RS 除了支持 matchLabels(等值匹配)外,还支持 matchExpressions,提供更灵活的标签筛选能力。支持的 4 种操作符:
| 操作符 | 含义 | 示例 |
|---|---|---|
In |
标签的值在指定的列表中 | 筛选 env 为 prod 或 test 的 Pod |
NotIn |
标签的值不在指定的列表中 | 筛选 env 不为 prod 或 test 的 Pod |
Exists |
只要标签存在就匹配(不关心值) | 筛选所有带有 disktype 标签的 Pod |
DoesNotExist |
标签不存在才匹配 | 筛选所有不带 disktype 标签的 Pod |
下面是rs的特性演示:


举例:
bash
# ============================================================
# ReplicaSet 示例 1:使用 Exists 操作符
# 作用:匹配所有带有 app 标签的 Pod(不管值是什么)
# ============================================================
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: rs-me-exists-demo
spec:
selector:
matchExpressions:
- key: app
operator: Exists
template:
metadata:
labels:
app: spring-k8s
spec:
containers:
- name: rs-me-exists-demo-container
image: wangyanglinux/myapp:v1.0
ports:
- containerPort: 80
---
# ============================================================
# ReplicaSet 示例 2:使用 In 操作符
# 作用:匹配 app 标签值在 [spring-k8s, hahahah] 列表中的 Pod
# 注意:当前 template 中 labels 为 app: sg-k8s,不在 values 列表中,
# 因此该 RS 实际无法匹配任何 Pod(内容未改,保持原样)
# ============================================================
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: rs-me-in-demo
spec:
selector:
matchExpressions:
- key: app
operator: In
values:
- spring-k8s
- hahahah
template:
metadata:
labels:
app: spring-k8s
spec:
containers:
- name: rs-me-in-demo-container
image: wangyanglinux/myapp:v1.0
ports:
- containerPort: 80
所以问题来了,为什么pod有标签了,还需要使用控制器的标签
因为:
| 现实角色 | K8s 组件 | 它关心什么 | 标签的作用 | 不匹配的后果 |
|---|---|---|---|---|
| 前台 | Service | 哪些员工能接待客户 | 用标签找到"能接客"的 Pod,把流量导给它 | Pod 收不到任何流量,但容器仍在运行 |
| 人事经理 | ReplicaSet | 我负责的岗位有没有招满 3 个人 | 用标签找到"归我管"的 Pod,少一个就补一个 | RS 认为自己没有 Pod,会不断创建新的 Pod |
| 员工 | Pod | 自己是什么身份 | 用标签(template.labels)表明"我是谁" | 没有标签的 Pod 就是"孤儿",没人管 |
二、Deployment控制器
Deployment 为 Pod 和 ReplicaSet 提供了一个声明式定义(declarative)方法,用来替代以前的 ReplicationController 来方便的管理应用。典型的应用场景包括:
➢ 定义 Deployment 来创建 Pod 和 ReplicaSet(deployment管理rs)
➢ 滚动升级和回滚应用
➢ 扩容和缩容
➢ 暂停和继续 Deployment
声明式和命令式是对立的:
-
声明性的东西是对终结果的陈述,表明意图而不是实现它的过程。在Kubernetes中,这就是说"应该有一个包含三个 Pod 的 ReplicaSet"。
-
命令式充当命令。声明式是被动的,而命令式是主动且直接的:"创建一个包含三个 Pod 的 ReplicaSet"。
|-------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| # 1. 命令式:强制替换(不推荐) # 作用:用 YAML 里的内容,直接强制替换集群中现有的 Deployment。 # 特点:如果资源不存在会报错。它会直接删除旧对象并创建新对象,容易导致服务短暂中断。 kubectl replace -f deployment.yaml |
| # 2. 声明式:计算差异并更新(最推荐,企业生产标准) # 作用:对比 YAML 期望状态与集群实际状态,只更新有差异的部分。 # 特点:如果不存在则创建,如果存在则平滑更新(触发滚动更新)。这是你之前遇到"警告"时用的命令,补全了配置后就能正常用。 kubectl apply -f deployment.yaml |
| # 3. 辅助命令:查看差异(安全预检) # 作用:只显示 YAML 文件和集群中实际运行的资源有哪些区别,不执行真正的修改。 # 特点:相当于"预演"一下 apply,方便你确认无误后再执行真正的应用。 $ kubectl diff -f deployment.yaml |
命令式和声明式区别:
# ============================================================
# 实验:kubectl apply vs kubectl replace
# 演示:apply 保留未在 YAML 中声明的注解,replace 会删除它
# ============================================================
# 1. 初始创建(用 apply,让它记录 last-applied-configuration)
kubectl apply -f 1.dplmt.yaml
# 2. 手动给 Deployment 加一个额外注解(模拟"YAML 中未声明的字段")
kubectl annotate deployment myapp-deploy test-annotation="hello" --overwrite
# 3. 修改 YAML 中的镜像为 v2.0
sed -i 's/v1.0/v2.0/' 1.dplmt.yaml
# 4. 用 apply 更新,并检查注解是否存在
kubectl apply -f 1.dplmt.yaml
echo "===== apply 之后的注解情况 ====="
kubectl get deployment myapp-deploy -o jsonpath='{.metadata.annotations}'
echo ""
# 5. 重新加上注解,修改 YAML 镜像为 v3.0,再用 replace 更新
kubectl annotate deployment myapp-deploy test-annotation="hello" --overwrite
sed -i 's/v2.0/v3.0/' 1.dplmt.yaml
kubectl replace -f 1.dplmt.yaml
echo "===== replace 之后的注解情况 ====="
kubectl get deployment myapp-deploy -o jsonpath='{.metadata.annotations}'
echo ""
# 6. 结论:
# apply 之后注解仍然存在(保留未声明字段)
# replace 之后注解消失(YAML 中没有就删除)
diff对比命令
通过diff对比pod实体与yaml的区别
[root@k8s-master01 deployment]# kubectl diff -f 1.dplmt.yaml
diff -u -N /tmp/LIVE-3445901412/apps.v1.Deployment.default.myapp-deploy /tmp/MERGED-604905406/apps.v1.Deployment.default.myapp-deploy
--- /tmp/LIVE-3445901412/apps.v1.Deployment.default.myapp-deploy 2026-09-14 10:27:15.676236826 +0800
+++ /tmp/MERGED-604905406/apps.v1.Deployment.default.myapp-deploy 2026-09-14 10:27:15.678236825 +0800
@@ -4,7 +4,7 @@
annotations:
deployment.kubernetes.io/revision: "3"
creationTimestamp: "2026-09-14T02:01:49Z"
- generation: 4
+ generation: 5
labels:
app: myapp-deploy
name: myapp-deploy
@@ -30,7 +30,7 @@
app: myapp-deploy
spec:
containers:
- - image: wangyanglinux/myapp:v3.0
+ - image: wangyanglinux/myapp:v4.0
imagePullPolicy: IfNotPresent
name: myapp
resources: {}
[root@k8s-master01 deployment]#
deployment更新策略
分为两种:
-
RollingUpdate(滚动更新) :默认策略。先起新 Pod,Ready 后删旧 Pod,逐步替换,服务不中断。 -
Recreate(重建) :先删掉所有旧 Pod,再创建新 Pod,服务会短暂中断。适合无法同时运行新旧版本的应用(如数据库变更)。
Deployment 在升级时,为了保证服务不中断(零宕机),会采用"滚动更新"的方式,确保在升级过程中,总是有一定数量的 Pod 保持可用。
rollingUpdate的核心参数
| 数 | 含义 | 通俗解释 |
|---|---|---|
maxSurge |
指定超出期望副本数的 Pod 最大数量。支持数字 和百分比。 | "多出来"的 Pod:升级时最多允许比期望数量多启动几个新 Pod。 |
maxUnavailable |
指定最多有几个 Pod 不可用。 | "少掉"的 Pod:升级时最多允许同时停掉几个旧 Pod。 |
案例:
案例1:
#不写 strategy 字段时,默认就是 RollingUpdate,maxSurge: 25%,maxUnavailable: 25%。
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp-deploy
spec:
replicas: 10
selector:
matchLabels:
app: myapp-deploy
template:
metadata:
labels:
app: myapp-deploy
spec:
containers:
- image: wangyanglinux/myapp:v3.0
name: myapp
案例2:
# 每次最多多起 1 个新 Pod,保证服务绝对不中断
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp-deploy
spec:
replicas: 10
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1 # 每次最多多起 1 个新 Pod
maxUnavailable: 0 # 保证服务绝对不中断
selector:
matchLabels:
app: myapp-deploy
template:
metadata:
labels:
app: myapp-deploy
spec:
containers:
- image: wangyanglinux/myapp:v2.0
name: myapp
案例3:指定重建策略,服务会中断
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp-deploy
spec:
replicas: 10
strategy:
type: Recreate # 指定重建策略
selector:
matchLabels:
app: myapp-deploy
template:
metadata:
labels:
app: myapp-deploy
spec:
containers:
- image: wangyanglinux/myapp:v1.0
name: myapp
~
deployment常用命令
bash
创建 Deployment,record是记录更新操作的
kubectl create -f deployment.yaml --record
手动扩缩容
kubectl scale deployment nginx-deployment --replicas 10
自动扩缩容 (HPA)
kubectl autoscale deployment nginx-deployment --min=10 --max=15 --cpu-percent=80
--min=10:指定 Pod 副本数的最小值为 10。
--max=15:指定 Pod 副本数的最大值为 15。
--cpu-percent=80:设置目标 CPU 使用率阈值为 80%。当deployment的所有pod使用率超过 80% 时触发扩容,低于时触发缩容。
更新镜像 (滚动更新)
kubectl set image deployment/nginx-deployment nginx-deployment-container=wangyanglinux/myapp:v2.0
版本回滚
kubectl rollout undo deployment/nginx-deployment
构建过程中的命令
bash
# 1. 创建 Deployment
kubectl apply -f 1.dplmt.yaml
# 2. 查看初始状态(1 个 RS,10 个 Pod)
kubectl get rs
kubectl get pod
# 3. 修改 YAML:把镜像 v1.0 改成 v2.0
sed -i 's/v1.0/v2.0/' 1.dplmt.yaml
# 4. 应用更新(触发滚动更新)
kubectl apply -f 1.dplmt.yaml
# 5. 实时观察滚动更新过程
kubectl rollout status deployment/myapp-deploy
# 6. 查看 RS 变化(会出现两个 RS:旧的 v1.0 和新的 v2.0)
kubectl get rs
# 7. 查看 Pod 变化(旧 Pod 逐个减少,新 Pod 逐个增加)
kubectl get pod -w
# 8. 查看滚动更新历史
kubectl rollout history deployment/myapp-deploy
# 9. 验证新 Pod 的镜像版本
kubectl get pod -o jsonpath='{.items[*].spec.containers[*].image}'
金丝雀更新策略
金丝雀部署是"把新版本先给 1% 的人用,如果没问题,再逐步扩大给 100% 的人用"
bash
#1.0版本
apiVersion: apps/v1
kind: Deployment
metadata:
name: deployment-demo
spec:
replicas: 10
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1 # 每次最多多起 1 个新 Pod
maxUnavailable: 0 # 保证服务绝对不中断
selector:
matchLabels:
app: myapp-deploy
template:
metadata:
labels:
app: myapp-deploy
spec:
containers:
- image: wangyanglinux/myapp:v1.0
name: myapp
#apply启动
kubectl apply -f 3.deployment.yaml
#金丝雀更新,本来是10个老pod,新增一个2.0的新pod,然后停止(意思就是:新增一个2.0pod后就停止)
#如果更新策略是默认的25%:25%,需要设置一下更新策略为1:0
kubectl patch deployment deployment-demo -p '{"spec":{"strategy":{"rollingUpdate":{"maxSurge":1,"maxUnavailable":0}}}}'
#开始金丝雀部署,部署完会发现多一个2.0
kubectl patch deployment deployment-demo --patch '{"spec":{"template":{"spec":{"containers":[{"name":"myapp","image":"wangyanglinux/myapp:v2.0"}]}}}}' && kubectl rollout pause deploy deployment-demo
#如果2.0没问题,我就可以批量把那10个都设置为2.0了
kubectl rollout resume deploy deployment-demo
#现在我有10个2.0,我现在再弄个10个2.0,1个3。0
#然后发现3.0有问题,必须全部升级到3.0才可以回滚,感觉这一块好傻
kubectl rollout resume deployment deployment-demo
#回滚到2.0
kubectl rollout undo deployment deployment-demo --to-revision=2 # 直接回到 v2.0
kubectl rollout undo deployment deployment-demo --to-revision=1 # 直接回到 v1.0
注意:
1、2、是 Deployment 的历史版本序号,不是镜像1.0和2.0编号。
如果不指定 --to-revision,kubectl rollout undo 默认只会回滚到当前版本的前一个 Revision,并不会自动一路退到最早的 1.0。
三、DaemonSet控制器
DaemonSet 确保全部(或者一些)Node 上运行一个 Pod 的副本。当有 Node 加入集群时,也会为他们新增一个 Pod。当有 Node 从集群移除时,这些 Pod 也会被回收。删除 DaemonSet 将会删除它创建的所有 Pod。
使用 DaemonSet 的一些典型用法:
-
运行集群存储 daemon,例如在每个 Node 上运行
glusterd、ceph -
在每个 Node 上运行日志收集 daemon,例如
fluentd、logstash -
在每个 Node 上运行监控 daemon,例如 Prometheus Node Exporter、
collectd、Datadog 代理、New Relic 代理,或 Gangliagmond#DaemonSet就是让每个node节点有一个pod
指定 K8s API 版本,DaemonSet 属于 apps/v1 组
apiVersion: apps/v1
资源类型:DaemonSet(守护进程集)
kind: DaemonSet
元数据:描述 DaemonSet 自身的信息
metadata:
name: daemonset-demo # DaemonSet 的名字(正确拼写)
labels: # 给 DaemonSet 自己打的标签(用于管理分类)
app: daemonset-demo规格:定义 DaemonSet 的行为
spec:
# 选择器:定义 DaemonSet 要管理哪些 Pod
selector:
matchLabels:
name: deamonset-demo #这里必须与下面 template 里的 labels 完全一致!
# 模板:定义要在每个节点上创建的 Pod 长什么样
template:
metadata:
labels:
name: deamonset-demo # 必须与上面的 selector 保持一致
spec:
containers:
- name: daemonset-demo-container # 容器的名字
image: wangyanglinux/myapp:v1.0 # 容器使用的镜像#生成pod
[root@k8s-master01 daemonSet]# kubectl apply -f 1.DaemonSet.yaml
daemonset.apps/daemonset-demo created
[root@k8s-master01 daemonSet]##查看每个机器上有一个pod
[root@k8s-master01 daemonSet]# kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
daemonset-demo-5q7t2 1/1 Running 0 11s 10.244.85.206 k8s-node01
daemonset-demo-n76h4 1/1 Running 0 11s 10.244.58.222 k8s-node02
四、Job 控制器
Job 是 Kubernetes 中用于运行一次性任务 的控制器。它确保指定数量的 Pod 成功完成,而不是像 Deployment 那样持续保持运行。
核心特点:
-
Pod 执行完任务后正常退出 (状态变为
Completed),Job 不会重新创建它。 -
如果 Pod 失败,Job 会根据
restartPolicy决定是否重试。 -
适用于批处理、数据迁移、备份、报表生成等一次性的工作。
特殊说明:
spec.template 格式同 Pod
RestartPolicy 仅支持 Never(永不重启) 或 OnFailure(重启,直到成功返回0)
单个 Pod 时,默认 Pod 成功运行后 Job 即结束
spec.completions 标志 Job 结束需要成功运行的 Pod 个数,默认为 1
spec.parallelism 标志并行运行的 Pod 的个数,默认为 1
spec.activeDeadlineSeconds 标志失败 Pod 的重试最大时间,超过这个时间不会继续重试
五、cronjob控制器
CronJob
周期性的创建Job,典型的场景:数据库的周期性备份.·
apiVersion: batch/v1
kind: CronJob
metadata:
name: cronjob-demo
spec:
schedule: "*/1 * * * *"
jobTemplate:
spec:
template:
spec:
containers:
- name: cronjob-demo-container
image: busybox
args:
- /bin/sh
- -c
- date; echo Hello from the kubernetes cluster
restartPolicy: OnFailure
六、控制器区别
守护进程类型控制器
-
RC 控制器
- 保障当前的 Pod 数量与期望值一致
-
RS 控制器
- 功能与 RC 控制器类似,但是多了标签选择的运算方式
-
Deployment
-
支持了声明式表达
-
支持滚动更新和回滚
-
原理:deployment > RS > pod
-
-
DaemonSet
- 保障每个节点有且只有一个 Pod 的运行,动态
批处理任务的类型
Job
保障批处理任务一个或多个成功为止
CronJob
周期性的创建Job,典型的场景:数据库的周期性备份.·
| 控制器 | 核心职责(干什么的) | 理发店系统中的对应场景 |
|---|---|---|
| ReplicaSet (RS) | 只保证 Pod 数量够,不管更新 | 基本不用,被 Deployment 替代 |
| Deployment | 管无状态应用(Web、API),支持滚动更新/回滚 | 前端、后端 API 服务 |
| DaemonSet | 保证每个节点跑一个 Pod | 日志收集、监控 Agent、网络插件 |
| Job / CronJob | 一次性任务、定时任务 | 每日销售报表、数据库备份 |