Kubernetes Pod副本数控制器
ReplicaSet 的职责非常单一:保证集群中任意时刻都存在指定数量的、匹配其选择器的 Pod。它通过 spec.replicas 声明期望副本数,并不断对比实际状态,少则补、多则删。
ReplicaSet 通过 spec.selector(支持 matchLabels 与 matchExpressions)识别自己该管哪些 Pod,这些 Pod 的 metadata.ownerReferences 会指向该 ReplicaSet。当 Pod 被删除、节点故障或人为扩缩容时,ReplicaSet 控制器会立即创建或删除 Pod 来回到期望状态。
在绝大多数场景下,不应该直接创建 ReplicaSet。 Deployment 才是面向用户的抽象层:Deployment 在每次修改 Pod 模板时创建一个新的 ReplicaSet,再由新旧 ReplicaSet 的副本数此消彼长完成滚动更新。旧 ReplicaSet 被保留下来,这就是 kubectl rollout undo 能回滚的原理。ReplicaSet 本身不具备滚动更新能力 —— 直接修改它的 Pod 模板不会触发任何自动更新,旧 Pod 必须手动删除才会以新模板重建。
kubectl [command] replicaset [flags]
ReplicaSet 的常用简写为 rs:
kubectl get rs
kubectl describe rs nginx-7d9c8f5b6c
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: nginx-rs
labels:
app: nginx
tier: frontend
spec:
replicas: 3
selector:
matchLabels:
app: nginx
matchExpressions:
- key: tier
operator: In
values: ["frontend"]
template:
metadata:
labels:
app: nginx
tier: frontend
spec:
containers:
- name: nginx
image: nginx:1.27
ports:
- containerPort: 80
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
cpu: 500m
memory: 256Mi
创建与查看:
kubectl apply -f replicaset.yaml
kubectl get rs
kubectl get rs -o wide
kubectl describe rs nginx-rs
kubectl get pods -l app=nginx
# matchLabels:精确匹配,写法最简单
selector:
matchLabels:
app: nginx
tier: frontend
# matchExpressions:支持 In / NotIn / Exists / DoesNotExist
selector:
matchExpressions:
- key: app
operator: In
values: ["nginx", "apache"]
- key: tier
operator: Exists
- key: debug
operator: DoesNotExist
两种写法可以混用,条件是与关系。ReplicaSet 的选择器通常是 Deployment 选择器加上 pod-template-hash 标签,以此保证不同版本的 ReplicaSet 不会互相抢 Pod:
kubectl get pods --show-labels
# app=nginx,pod-template-hash=7d9c8f5b6c
# 手动扩缩容
kubectl scale rs nginx-rs --replicas=5
# 缩到 0 但保留对象(便于快速恢复)
kubectl scale rs nginx-rs --replicas=0
# 直接编辑
kubectl edit rs nginx-rs
# 局部修改
kubectl patch rs nginx-rs -p '{"spec":{"replicas":2}}'
对裸 ReplicaSet 而言,修改 spec.replicas 后不会自动更新 Pod 内容,新副本才会使用新的 template。要让已有 Pod 也用上新模板,必须手动删除旧 Pod:
# 分批重建(注意:裸 ReplicaSet 没有滚动更新保障,会造成短暂容量下降)
kubectl delete pod -l app=nginx --wait=false
# Deployment 拥有若干 ReplicaSet,每个对应一次 Pod 模板变更
kubectl get deploy nginx
kubectl get rs -l app=nginx
# 查看每个 ReplicaSet 的版本注解
kubectl get rs -l app=nginx \
-o custom-columns=NAME:.metadata.name,REVISION:.metadata.annotations.deployment\\.kubernetes\\.io/revision,DESIRED:.spec.replicas
# 查看 Pod 属于哪个 ReplicaSet
kubectl get pod nginx-7d9c8f5b6c-abcde -o jsonpath='{.metadata.ownerReferences[0].name}'
# 回滚本质上是把流量还给了某个旧 ReplicaSet
kubectl rollout undo deployment/nginx
# 删除 ReplicaSet,默认级联删除它管理的 Pod
kubectl delete rs nginx-rs
# 只删除 ReplicaSet,保留 Pod(--cascade=orphan)
kubectl delete rs nginx-rs --cascade=orphan
# 删除 Deployment 时保留 ReplicaSet 与 Pod
kubectl delete deploy nginx --cascade=orphan
--cascade=orphan 常用于「想接管已有 Pod」的场景:先解除控制器的归属关系,Pod 便成了裸 Pod,之后可以由新的控制器通过标签收养。
revisionHistoryLimit 之外的 ReplicaSet 由 Deployment 自动清理,无需人工介入。spec.selector 创建后不可变更,写错选择器只能删除重建。spec.template.metadata.labels 匹配,否则 API Server 拒绝创建。--cascade=orphan 删除后 Pod 仍在运行,但失去自愈能力,节点故障不会重建,记得尽快用新的控制器接管。<rs-name>-<5 位随机串>,过长的名字可能触碰 63 字符的标签/名称长度限制。kubectl — Kubernetes集群管理工具deployment — 无状态工作负载控制器statefulset — 有状态工作负载控制器daemonset — 每节点守护进程pod — 最小调度单元