Kubernetes 系列【10】控制器:ReplicaSet(副本集)
文章目录
- 1. 概述
- 2. 工作原理
- 2.1 配置必填字段
- 2.2 调谐循环逻辑(控制器持续执行)
- 2.3 Pod 归属与接管规则
- 3. 资源清单编写规范
- 3.1 通用顶层基础规范
- 3.2 Pod 模板硬性约束
- 3.3 标签选择器规则
- 3.4 副本数字段规则
- 4. 使用示例
- 4.1 部署、查看、调试
- 4.2 删除
- 4.3 脱离 RS 管控
- 4.4 缩容 Pod 删除优先级
- 示例 1:删除成本注解使用
- 示例2:缩容演示
- 4.5 Pod 终止机制
- 4.6 HPA 自动扩缩容
- 5. 替代方案对比
1. 概述
ReplicaSet(副本集,简称RS),核心能力是持续维持集群内指定数量、配置一致的Pod正常运行。
唯一目标:集群里一直保持replicas指定数量的可用Pod,不关心版本更新、灰度发布,只做「数量对齐」。
ReplicaSet仅负责保证固定数量Pod持续运行;而Deployment是更高层级的控制器,内置管理ReplicaSet的能力,支持声明式滚动更新、版本回滚等大量生产必备特性。
2. 工作原理
2.1 配置必填字段
三大必填字段各自作用:
spec.selector:标签选择器,匹配接管对应标签Pod。spec.replicas:期望Pod副本数,默认1。spec.template:Pod模板,数量不足时按此新建Pod。
2.2 调谐循环逻辑(控制器持续执行)
控制器不停做对比运算:
- 统计集群内所有匹配
selector的Pod; - 区分两类
Pod:- 自有
Pod:带有ownerReferences指向当前RS; - 裸
Pod:无归属、仅标签匹配;
- 自有
- 分三种情况处理:
- 总数 <
replicas:按template创建新Pod,自动给新Pod打上ownerReferences; - 总数 >
replicas:删除多余Pod,优先按内置删除策略清理; Pod正常运行但进程崩溃 / 节点失联:视为失效Pod,标记销毁,再新建补齐数量。
- 总数 <
2.3 Pod 归属与接管规则
每个Pod的metadata.ownerReferences是一段资源标记,记录这个Pod是哪个ReplicaSet创建的。
ownerReferences归属绑定规则:
RS通过这个字段识别自己创建的Pod;RS新建Pod时,自动写入该字段,记录父资源为当前RS;- 多
RS场景下,每个RS只信任带有自己归属标记的Pod,互不混淆; - 裸
Pod没有此字段,属于无主资源。
RS会自动捞走匹配标签的裸Pod,判断条件同时满足就接管:
Pod没有ownerReferences(无控制器)Pod标签和RS的spec.selector完全对上
场景1,RS期望副本数replicas=3,但RS已有3个正常Pod,手动新建2个同标签裸Pod。
此时:
总 Pod=3(RS 亲生)+2(裸 Pod)=5,超过目标数量RS调谐逻辑:多出来的要删掉 → 直接销毁2个裸Pod,维持总数3。
场景2,先手动建2个同标签裸Pod,再创建replicas=3的RS,RS启动扫描到2个匹配裸Pod,直接接管(给Pod打上归属标记)。当前总数2< 期望3,RS再按模板新建1个Pod,凑够3个。
RS认两件事:
- 归属标记区分亲生
Pod; - 标签匹配就抢无主
Pod,只保证数量达标,不统一Pod内部配置。
3. 资源清单编写规范
最简合规RS模板(对照规范):
apiVersion:apps/v1kind:ReplicaSetmetadata:name:demo-rs# DNS标签规范命名spec:replicas:3# 可选,不写默认1selector:matchLabels:app:demotemplate:metadata:labels:app:demo# 和selector标签完全一致spec:restartPolicy:Always# 仅允许该值containers:-name:demoimage:nginx3.1 通用顶层基础规范
- 强制三要素缺一不可:
apiVersion、kind、metadata RS专属固定值:apiVersion: apps/v1kind: ReplicaSet,不可修改
metadata.name约束:- 遵循
DNS标签命名规范,控制平面会用RS名称作为Pod名称前缀; - 命名不规范会导致
Pod主机名解析异常。
- 遵循
3.2 Pod 模板硬性约束
- 标签强一致性校验:模板内
metadata.labels必须和spec.selector.matchLabels完全相同,API服务端会做校验,不一致直接拒绝创建RS。 - 重启策略限制:
spec.template.spec.restartPolicy仅允许 Always,不支持OnFailure/Never;- 原因:RS 的职责是长期常驻副本,Pod 退出后必须自动重建,一次性任务由
Job/CronJob负责。
3.3 标签选择器规则
spec.selector:
- 作用:筛选集群内可纳入统计的
Pod范围; - 多
RS同selector隔离机制:- 多个
RS配置一模一样的选择器、但Pod模板不同时,不会争抢Pod。 - 区分逻辑:依靠
Pod的ownerReferences归属标记,每个RS只管理自己创建、带自身归属标记的Pod; - 裸
Pod才会被最先匹配到的RS接管。
- 多个
3.4 副本数字段规则
spec.replicas:
- 功能:定义集群需要维持的目标
Pod数量; - 默认值:字段省略时自动填充
replicas: 1; - 控制器行为:持续对比实际
Pod总数与期望值,自动增删Pod对齐数量。
4. 使用示例
4.1 部署、查看、调试
- 创建
RS资源清单nginx-rs.yaml:
# K8s API 版本,ReplicaSet 归属 apps/v1 组apiVersion:apps/v1# 资源类型:副本集 ReplicaSetkind:ReplicaSet# 元数据:资源名称、标签标识metadata:# ReplicaSet 名称,遵循DNS标签规范,用于生成Pod前缀name:nginx-rs# RS自身标签,用于筛选、分组管理资源labels:app:nginx# ReplicaSet 核心业务配置段spec:# replicas:期望运行的Pod副本数量,省略默认值1replicas:3# 标签选择器,筛选本RS管控的Podselector:matchLabels:# 匹配Pod模板内定义的标签,必须与template.labels完全一致app:nginx# Pod模板:副本不足时,以此模板新建Podtemplate:metadata:# Pod标签,和上方selector.matchLabels保持统一,API强制校验labels:app:nginxspec:# Pod容器列表containers:# 容器名称,Pod内唯一标识-name:nginx# 官方Nginx轻量镜像image:nginx:1.24-alpine# 容器暴露端口ports:-containerPort:80- 应用清单创建
RS:
kubectl apply-fnginx-rs.yaml- 查看集群所有副本集:
kubectl get rs输出示例:
NAME DESIRED CURRENT READY AGE nginx-rs 3 3 3 6s
字段解释:
DESIRED:期望副本数CURRENT:当前运行总实例数READY:就绪可用实例数AGE:资源创建时长
- 查看
RS详细信息:
kubectl describe rs/nginx-rs输出关键信息解读:
Selector:匹配标签app=nginxReplicas:当前3个 / 期望3个Pods Status:运行中/等待/执行成功/失败Pod数量Pod Template:创建Pod使用的Nginx镜像、容器端口配置Events:控制器创建Pod的操作日志
- 查看
RS管理的Pod:
kubectl get pods输出类似:
NAME READY STATUS RESTARTS AGE nginx-rs-xxxxxx 1/1 Running 0 20s nginx-rs-yyyyyy 1/1 Running 0 20s nginx-rs-zzzzzz 1/1 Running 0 20s- 验证
Pod的归属引用ownerReferences:
# 替换为实际Pod名称kubectl get pods nginx-rs-xxxxxx-oyamlPod元数据中ownerReferences会记录所属ReplicaSet,标识该Pod由RS全权管理。
4.2 删除
删除RS连带删除Pod(默认):
kubectl delete rs nginx-rs- 只删
RS、保留Pod(孤儿Pod):
kubectl delete rs nginx-rs--cascade=orphan4.3 脱离 RS 管控
现有Nginx RS,replicas:3,标签app:nginx,3个Pod正常运行。
- 查看
Pod:
kubectl get pods --show-labels输出:
nginx-rs-7x9sf 1/1 Running 0 20m app=nginx nginx-rs-2dfvj 1/1 Running 0 20m app=nginx nginx-rs-5tn8g 1/1 Running 0 20m app=nginx- 修改其中一个
Pod标签,脱离RS管控:
kubectl label pod nginx-rs-7x9sfapp=nginx-test--overwrite- 现象:
- 该
Pod标签变为app=nginx-test,不再匹配RS selector,脱离RS管理; RS检测当前匹配Pod只剩2个,不足3副本,立刻新建一个nginx-rs-xxxx补齐至3个;- 现在集群一共
4个Pod:1个脱离管控的旧Pod + RS管理的3个标准Pod。
- 该
4.4 缩容 Pod 删除优先级
示例 1:删除成本注解使用
给Pod打上低数值注解,缩容时优先删掉它:
# 给Pod设置删除成本-100,优先销毁kubectl annotate pod nginx-rs-2dfvj controller.kubernetes.io/pod-deletion-cost=-100其他Pod无注解默认0,缩容时会先删-100的Pod。
示例2:缩容演示
RS副本3个,执行缩容到2个:
kubectl scale rs nginx-rs--replicas=2控制器判断删除顺序:
- 如果有
Pending未调度Pod,优先删; - 有
-100注解的Pod第二个删; - 同一节点
Pod更多的实例次之; - 刚创建不久的新
Pod; - 全部条件一致随机删。
4.5 Pod 终止机制
终止机制:
- 缩容、删除时
Pod进入终止状态,销毁耗时较长,期间集群总Pod数量会临时超过replicas; - 可通过
RS的status.terminatingReplicas查看正在销毁的实例。 - 开启方式:
API Server、kube-controller-manager配置特性门控DeploymentReplicaSetTerminatingReplicas。
- 缩容命令:
kubectl scale rs nginx-rs--replicas=1- 观察现象:
kubectl get pods会看到2个Pod状态为Terminating,此时集群总Pod数量=3,大于目标replicas=1;
- 查看终止中副本数量:
kubectl get rs nginx-rs-oyaml在status.terminatingReplicas字段能看到正在销毁的Pod个数,等待优雅停止完成后数量回归1。
4.6 HPA 自动扩缩容
RS可作为HPA伸缩目标,自动调整副本数:
apiVersion:autoscaling/v1kind:HorizontalPodAutoscalerspec:scaleTargetRef:apiVersion:apps/v1kind:ReplicaSetname:frontend minReplicas:3maxReplicas:10targetCPUUtilizationPercentage:50快捷命令:
kubectl autoscale rs frontend--min=3--max=10--cpu=50%5. 替代方案对比
| 控制器 | 核心能力 | 使用场景 |
|---|---|---|
| 裸 Pod(无控制器) | 无自愈,故障不重建 | 本地临时测试,禁止线上使用 |
| ReplicaSet | 仅保证固定Pod数量,无发布更新 | 几乎不用,仅底层支撑Deployment |
| Deployment | 复用RS能力,支持滚动更新、回滚、版本管理 | 无状态业务(Web、API服务)首选 |
| StatefulSet | 稳定网络标识、有序创建/删除、专属持久存储,有状态实例 | MySQL、Redis集群、Zookeeper、Elasticsearch等有状态中间件 |
| DaemonSet | 每节点运行1个Pod | 日志、监控、节点代理 |
| Job/CronJob | 一次性任务,执行完成即退出 | 离线批处理、定时任务 |
| ReplicationController | RS前身,仅等值标签选择器,已淘汰 | 新项目不使用 |
官方建议:优先使用 Deployment,不直接操作 ReplicaSet。
