deployment的replicas字段不生效,主因是pod被其他控制器接管:残留replicaset、ownerreferences冲突或selector与template标签不一致;需检查并清理旧资源,确保标签完全匹配。

Deployment.yaml里replicas字段不生效?检查Pod是否被其他控制器接管
常见现象是修改了replicas: 5但kubectl get pods始终只看到1个或固定数量的Pod。根本原因往往是该Pod已带有被ReplicaSet、StatefulSet或旧Deployment创建的标签,导致新Deployment的selector匹配到了“别人的孩子”。
实操建议:
- 用
kubectl get rs -l app=go-app确认是否存在残留的ReplicaSet - 检查Pod的
ownerReferences:kubectl get pod <pod-name> -o yaml | grep -A 5 ownerReferences</pod-name> - 确保新Deployment的
selector.matchLabels与Pod模板中template.metadata.labels完全一致——一个字母都不能差 - 若需强制接管,先删除旧资源:
kubectl delete rs -l app=go-app,再apply新Deployment
滚动更新时副本数异常波动?理解maxSurge和maxUnavailable的作用
默认滚动更新策略下,你可能观察到Pod总数短暂超过replicas值(比如设为3却出现5个Pod),或服务短暂不可用。这不是bug,而是RollingUpdate策略的两个关键参数在起作用。
它们控制更新节奏:
-
maxSurge:允许超出期望副本数的Pod数量(可为数字或百分比),默认25%。设为1即最多临时多启1个新Pod -
maxUnavailable:允许不可用的Pod数量(可为数字或百分比),默认25%。设为0表示“零停机”,但会拉长更新时间 - 必须至少有一个为非零值,否则更新卡住
- 在生产环境建议显式声明:
strategy:<br> type: RollingUpdate<br> rollingUpdate:<br> maxSurge: 1<br> maxUnavailable: 0
Pod反复重启或无法就绪?检查容器端口与探针路径是否对齐
Go服务监听:8080,但Deployment里写containerPort: 80,或健康接口/health没实现却在livenessProbe里调用——这类错位会导致Pod卡在CrashLoopBackOff或NotReady状态。
关键点:
-
containerPort只是声明,不影响实际监听;Go代码里http.ListenAndServe(":8080", nil)才是真实端口,两者必须一致 -
livenessProbe和readinessProbe的port字段应填容器端口(如8080),不是Service端口 - 探针
path对应Go路由必须返回HTTP 200,且不能有重定向(302)或超时逻辑 - 若用
exec探针,确保容器内存在对应二进制(Alpine镜像里curl默认不带,得apk add curl)
为什么kubectl scale不推荐用于生产环境?它绕过了GitOps流程
执行kubectl scale deployment/go-app --replicas=6确实能立刻扩容,但这个变更不会写回你的deployment.yaml文件,下次apply会覆盖掉它。CI/CD流水线或Argo CD这类工具也无法感知这次手动调整。
更稳妥的做法:
- 直接改YAML里的
replicas字段,提交到Git,再apply - 若需动态扩缩,用
HorizontalPodAutoscaler(HPA),基于CPU或自定义指标自动调节 - 紧急扩容时,可用
kubectl patch并加--record留痕:kubectl patch deployment/go-app -p '{"spec":{"replicas":6}}' --record
副本管理真正的复杂点不在数字本身,而在于它如何与探针、更新策略、配置注入联动——漏掉任意一环,都可能让“3个副本”变成“3个半死不活的进程”。











