我在CCE被调度和探针连坑三次

举报
yd_272744321 发表于 2026/10/27 10:27:46 2026/10/27
【摘要】 我把一个内部回调服务从ECS迁到华为云CCE,本以为半小时能收工,结果先卡在Pod调度,再被探针打成CrashLoopBackOff,又被反亲和规则卡住副本。文里是我当晚的真实排查过程,包含命令、事件日志、YAML改动、耗时和算下来的节点成本。

线上背景和调度卡住

上周三 19:34,我把内部回调服务 notify-gateway 从一台 ECS 迁到华为云 CCE,区域 cn-south-1,集群版本 v1.25.6-r0,kubectl 客户端 v1.27.4,Helm v3.12.3。服务是 Java 17 + Spring Boot 3.1.2,镜像 624MB,启动时会从 OBS 拉一份 78MB 的 rules.json,然后预热 32 条 Redis 连接。集群只有 2 个工作节点,规格 c6.large.2(2 vCPU / 4GiB),系统盘 40GB 高IO,单价 0.39 元/小时,两台合计 0.78 元/小时。迁移前老 ECS 是 4C8G,单机跑了半年,P95 一直在 300ms 左右徘徊,我才决定拆到 K8s。

我给自己排了 30 分钟发布窗口,实际从 19:34 折腾到 22:52 才稳定,整整 3 小时 18 分钟,期间看了 4 次 helm history,release revision 从 17 滚到 23。

第一次发布命令是 helm upgrade --install notify-gateway ./chart -n biz -f values-prod.yaml --history-max 5 --timeout 10m。当时偷懒直接复用了另一个服务的 values,原始配置是下面这样:

replicaCount: 3
resources:
  requests:
    cpu: 1500m
    memory: 2Gi
  limits:
    cpu: 2
    memory: 2Gi

apply 后 6 分钟,3 个 Pod 全是 Pending,describe 里反复刷这条:

Warning  FailedScheduling  5m   default-scheduler  0/2 nodes are available: 2 Insufficient memory.

我又跑了 kubectl top node 和 kubectl describe node 10.0.3.21,节点 Allocatable 内存只有 3922Mi,kube-system 里的 coredns、everest-csi、log-agent、icagent 这些 DaemonSet 常驻后,单节点能给业务 Pod 的空间只剩 1.1Gi 到 1.3Gi。2Gi 的 requests 根本不可能调度成功,这不是调度器挑剔,是我填错了数量级。

我不是“改了一下”就结束,而是按启动阶段的真实占用重算:JVM -Xms256m -Xmx512m,本地缓存峰值 120Mi,Netty + 线程栈约 90Mi,再给 15% 抖动余量。Deployment 改成 requests cpu: 300m、memory: 512Mi,limits 改成 cpu: 1、memory: 1Gi,副本先保留 3,不动。命令是:

kubectl -n biz set resources deploy/notify-gateway \
--requests=cpu=300m,memory=512Mi \
--limits=cpu=1,memory=1Gi

40 秒内有两个 Pod 落在不同节点,第三个继续 Pending。我那会儿被旧事件误导,以为还是内存不够,临时把 limits 内存从 1Gi 降到 768Mi 试了一次,还手动触发 kubectl -n biz rollout restart deploy/notify-gateway,结果 11 分钟过去状态没有任何变化,这次尝试是纯失败,白白多等一轮镜像拉起。

那一刻我真想直接回滚到 ECS。

探针和反亲和返工

两个已调度 Pod 也没稳住,12 分钟里重启 19 次,状态在 Running 和 CrashLoopBackOff 之间来回跳。Events 里两类报错轮着来:

Readiness probe failed: Get "http://10.0.23.17:8080/health": dial tcp 10.0.23.17:8080: connect: connection refused
Liveness probe failed: HTTP probe failed with statuscode: 500
Container notify-gateway failed liveness probe, will be restarted

容器日志也很直白,我截了三行最关键的时间点:

2026-06-12 19:58:11.204 INFO  RuleLoader : download obs://notify-prod/rules.json size=78MB cost=48721ms
2026-06-12 19:58:17.991 ERROR RedisHealthIndicator : RedisConnectionFailureException: Unable to connect to redis-master.biz.svc:6379
2026-06-12 19:58:18.002 INFO  TomcatWebServer : Tomcat initialized with port 8080

我原来的探针配置是 initialDelaySeconds: 5、timeoutSeconds: 1,liveness/readiness 都打 /health。问题在于这个接口挂了 Redis 检查和规则加载状态,冷启动最慢能到 68 秒,5 秒就开始探测,kubelet 连续拿到 500 就重启,形成死循环。我还用 kubectl logs -f 对过一次,Pod 刚把 rules 下载到 60% 就被上一轮 liveness 杀掉了。

这个返工没有技术含量,纯粗心。

我先试过一次半吊子修法,只改 liveness 参数,不改路径:initialDelay 5 拉到 30,timeout 1 改 3。命令是:

kubectl -n biz patch deploy notify-gateway --type merge -p '{"spec":{"template":{"spec":{"containers":[{"name":"notify-gateway","livenessProbe":{"httpGet":{"path":"/health","port":8080},"initialDelaySeconds":30,"timeoutSeconds":3,"periodSeconds":10,"failureThreshold":3}}]}}}}'

结果重启次数从 19 次降到 7 次,但还是会死,原因没变:启动慢批次接近 68 秒,30 秒不够;而且 /health 依赖 Redis,Redis 抖一下就判死。21:02 我放弃这版,回到 Deployment 重配探针,具体做了三件事:加 startupProbe 兜启动窗口;readiness 改成 /ready;liveness 改成只看进程存活的 /live。配置如下:

startupProbe:
  httpGet:
    path: /live
    port: 8080
  failureThreshold: 30
  periodSeconds: 3
readinessProbe:
  httpGet:
    path: /ready
    port: 8080
  initialDelaySeconds: 10
  periodSeconds: 5
  timeoutSeconds: 2
  failureThreshold: 6
livenessProbe:
  httpGet:
    path: /live
    port: 8080
  initialDelaySeconds: 60
  periodSeconds: 10
  timeoutSeconds: 2
  failureThreshold: 3

改完我跑了 kubectl rollout status deploy/notify-gateway -n biz --timeout=180s,然后盯监控 25 分钟,重启计数停在 0。单个 Pod 从 ContainerCreating 到 Ready 的耗时在 61 到 66 秒,中位数 64 秒,比我预估慢 8 秒,但已经能稳定接流量。

第三个副本迟迟起不来,21:36 我才看到真正原因不是资源,而是反亲和规则:

Warning  FailedScheduling  22s (x14 over 9m)  default-scheduler  0/2 nodes are available: 2 node(s) didn't match pod anti-affinity rules.

我在 values 里写的是 requiredDuringSchedulingIgnoredDuringExecution,selector 是 app=notify-gateway,topologyKey 是 kubernetes.io/hostname。2 节点放 3 副本时,这条规则天然不可满足。测试环境一直是 2 副本,所以之前没暴露。我把 required 改成 preferred,weight 100,selector 不动,再跑一次 helm upgrade。22:04 第三个副本落地到 node-21,和一个旧副本同节点,这个取舍我接受。

22:52 我把流量切到 100%,观察到次日 10:00,4xx 在 0.18% 到 0.24%,5xx 没超过 0.03%,Pod 重启次数 0,P95 从发布前 312ms 降到 118ms。那晚多花的节点成本按 0.78 元/小时算,3.3 小时是 2.57 元;OBS 拉规则文件流量 0.41GB,内网计费几乎可以忽略。

还没解决的是 /ready 仍然依赖 Redis,昨天凌晨 03:17 Redis 主从切换 11 秒,3 个 Pod 同时变成 Unready。下周我会把就绪检查拆两层,/ready 只看进程和本地规则可服务,Redis 可用性移到独立告警指标里,不再直接参与摘流。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。