EKS 从 1.32 升到 1.35 踩坑记录:cgroup v1 差点让整个集群起不来
上周接到任务——把生产环境的 EKS 集群从 1.32 升级到 1.35。
听起来就三个小版本的事,结果折腾了两天。最大的坑不是 Kubernetes 本身,而是节点 OS 和一堆"挂着没人动"的监控组件。
这篇把整个升级过程的坑都记下来,省得你们重复踩。
为什么必须升级
EKS 1.32 的标准支持期快到了。不升的后果:
- 进入扩展支持,每小时每集群多收 0.60 美元
- 安全补丁断供
- 越拖越难——EKS 不支持跨版本升级,必须 1.32 → 1.33 → 1.34 → 1.35 逐步走
拖了三个月不升的同事最后花了一整周。早升早解脱。
升级前的集群现状
我们集群跑了这些东西:
- 业务微服务(十几个 Deployment)
- 自管理监控栈:Prometheus v2.28、Thanos v0.27、node-exporter v1.0.1
- cluster-autoscaler v1.32.0
- aws-load-balancer-controller v2.10.1
- EKS 托管 Add-on:VPC CNI、kube-proxy、CoreDNS、EBS CSI、EFS CSI
注意那个 Prometheus v2.28——2021 年的版本。node-exporter v1.0.1 更离谱,2020 年的。
"没出问题就不升级"这种心态,最终会在 K8s 升级那天集中爆发。
三个版本的关键变更
先搞清楚 1.33、1.34、1.35 分别改了什么:
| 版本 | 关键变更 |
|---|---|
| 1.33 | Endpoints API 废弃(需迁移到 EndpointSlices);Sidecar Containers GA |
| 1.34 | containerd 升到 2.1;AL2 AMI 停发(必须迁移 AL2023) |
| 1.35 | cgroup v1 弃用(kubelet 默认拒绝在 cgroup v1 节点启动);IPVS 模式废弃 |
1.34 是节点 OS 的分水岭,1.35 是基础设施的分水岭。
第一个大坑:cgroup v1
这是整个升级最凶险的一个——EKS 1.35 的 kubelet 默认拒绝在 cgroup v1 节点上启动。
什么意思?如果你的节点还在跑 AL2(Amazon Linux 2),它默认用的是 cgroup v1。升到 1.35 后滚动节点,新节点直接起不来。
而且这不是能回滚解决的问题——控制面已经升到 1.35 了,回不去。
解法:必须在升 1.34 之前,把所有节点从 AL2 迁移到 AL2023(默认 cgroup v2)。
检查当前节点用的是 v1 还是 v2:
# SSH 到节点执行
stat -fc %T /sys/fs/cgroup/
# 输出 cgroup2fs = v2,tmpfs = v1
或者批量检查:
kubectl get nodes -o json | jq -r '.items[] | .status.nodeInfo.osImage'
看到 "Amazon Linux 2" 就是 v1,"Amazon Linux 2023" 就是 v2。
第二个大坑:监控组件版本太老
升级 K8s 1.35 后,Prometheus v2.28 直接不工作了。
原因:它内置的 client-go 库是 1.30 版的,跟 K8s 1.35 的 API 不兼容。kube-state-metrics 也是同样的问题。
必须升级的组件清单:
| 组件 | 老版本 | 问题 | 目标版本 |
|---|---|---|---|
| kube-state-metrics | v2.12.0 | client-go 不兼容 1.35 | v2.18.0+ |
| Prometheus | v2.28.0 | 2021年版本,缺安全补丁 | v2.55.0+ |
| Thanos | v0.27.0 | 需配合 Prometheus 升级 | v0.36.0+ |
| node-exporter | v1.0.1 | 2020年版本 | v1.10.0+ |
| cluster-autoscaler | v1.32.0 | 版本号必须匹配 K8s 大版本 | v1.35.x |
cluster-autoscaler 特别坑——它的版本号必须跟 K8s 大版本一致。也就是说,每升一个版本就要同步升一次,不能最后统一升。
第三个大坑:Ingress NGINX 退役
如果你还在用社区维护的 ingress-nginx(注意不是 NGINX 公司的商业版),它在 2026 年 3 月已经正式退役了。
1.35 之后继续用不会立刻挂,但不再有安全补丁。长期看必须迁移。
可选方案:
- Gateway API(社区主推方向)
- AWS Load Balancer Controller + ALB
- NGINX 商业版
我们选了 Gateway API,但没在升级窗口内做,单独安排了一周迁移。
正确的升级顺序
踩完坑总结出来的四阶段路径:
阶段 0:升级前准备(提前 1-2 周)
# 1. 检查节点 OS
kubectl get nodes -o json | jq -r '.items[] | "\(.metadata.name) \(.status.nodeInfo.osImage)"'
# 2. 检查哪些组件还在调用废弃的 Endpoints API
kubectl get --raw /metrics | grep apiserver_request_total | grep endpoints
# 3. 备份集群配置
kubectl get all --all-namespaces -o yaml > cluster-backup.yaml
关键动作:
- AL2 节点全部迁移到 AL2023
- 监控组件(Prometheus、Thanos、node-exporter)升级到最新 LTS
- cluster-autoscaler 升级到 v1.32.x(先确认当前版本能跑)
阶段 1:升级到 1.33
# 升级控制面
aws eks update-cluster-version \
--name my-cluster \
--kubernetes-version 1.33
# 等控制面就绪后,升级托管 addon
aws eks update-addon --cluster-name my-cluster \
--addon-name vpc-cni \
--resolve-conflicts OVERWRITE
aws eks update-addon --cluster-name my-cluster \
--addon-name kube-proxy \
--resolve-conflicts OVERWRITE
aws eks update-addon --cluster-name my-cluster \
--addon-name coredns \
--resolve-conflicts OVERWRITE
# 升级 cluster-autoscaler
helm upgrade cluster-autoscaler autoscaler/cluster-autoscaler \
--set image.tag=v1.33.0
# 滚动节点组
aws eks update-nodegroup-version \
--cluster-name my-cluster \
--nodegroup-name my-nodes
验证:
kubectl get nodes
kubectl get pods -A | grep -v Running
阶段 2:升级到 1.34
1.34 的重点是 containerd 2.1。如果你有自定义 OCI hook 或私有 registry mirror 配置,先在测试环境验证。
aws eks update-cluster-version \
--name my-cluster \
--kubernetes-version 1.34
# 同步升级 cluster-autoscaler
helm upgrade cluster-autoscaler autoscaler/cluster-autoscaler \
--set image.tag=v1.34.0
阶段 3:升级到 1.35
到这一步,如果前面的准备工作做了,应该比较顺利:
aws eks update-cluster-version \
--name my-cluster \
--kubernetes-version 1.35
# 最后一次升级 cluster-autoscaler
helm upgrade cluster-autoscaler autoscaler/cluster-autoscaler \
--set image.tag=v1.35.0
升完后全面验证:
# 确认所有节点 Ready
kubectl get nodes
# 确认所有 Pod 正常
kubectl get pods -A --field-selector status.phase!=Running,status.phase!=Succeeded
# 确认监控正常采集
kubectl port-forward -n monitoring svc/prometheus 9090:9090
# 打开 http://localhost:9090 检查 targets
IPVS 模式迁移
如果你的 kube-proxy 用的是 IPVS 模式,1.35 标记废弃,1.36 会移除。
集群规模在几千 Pod 以下,切回 iptables 基本无感:
kubectl edit configmap kube-proxy-config -n kube-system
# 把 mode: "ipvs" 改成 mode: "iptables"
# 然后重启 kube-proxy DaemonSet
kubectl rollout restart ds kube-proxy -n kube-system
规模更大的直接上 nftables 模式。
升级失败怎么办
说个残酷的事实:EKS 控制面升级不支持就地回滚。
一旦开始升了,就回不去了。所以:
- 升级前一定要有备份
- 建议保留旧版本节点组(不删),出问题时旧节点还能承载流量
- 测试环境先走一遍完整流程
时间估算
| 阶段 | 耗时 |
|---|---|
| 准备工作(AL2→AL2023、组件升级) | 3-5 天 |
| 1.32→1.33 | 1-2 小时 |
| 1.33→1.34 | 1-2 小时 |
| 1.34→1.35 | 1-2 小时 |
| 全面验证 | 半天 |
总耗时:顺利的话一周搞定,核心升级在一天内完成。
总结
EKS 跨版本升级的核心经验:
- 别拖——越拖坑越多,一次跨三个版本和跨一个版本的工作量差 10 倍
- 先动节点 OS——AL2 迁 AL2023 是前置条件,不是可选项
- 先动监控组件——别让 Prometheus 在升级当天给你惊喜
- cluster-autoscaler 每版本同步升——不能跳
- 控制面升了回不了头——测试环境先跑一遍
三个最容易翻车的点:cgroup v1 节点起不来、老版本 client-go 不兼容、cluster-autoscaler 版本错配。
提前搞定这三个,升级当天就是走流程而已。
素材来源:亚马逊云科技官方博客 — 规划 Amazon EKS 从 1.32 升级到 1.35
相关文档:Amazon EKS 升级集群最佳实践

浙公网安备 33010602011771号