EKS 从 1.32 升到 1.35 踩坑记录:cgroup v1 差点让整个集群起不来

上周接到任务——把生产环境的 EKS 集群从 1.32 升级到 1.35。

听起来就三个小版本的事,结果折腾了两天。最大的坑不是 Kubernetes 本身,而是节点 OS 和一堆"挂着没人动"的监控组件。

这篇把整个升级过程的坑都记下来,省得你们重复踩。

为什么必须升级

EKS 1.32 的标准支持期快到了。不升的后果:

  1. 进入扩展支持,每小时每集群多收 0.60 美元
  2. 安全补丁断供
  3. 越拖越难——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 控制面升级不支持就地回滚

一旦开始升了,就回不去了。所以:

  1. 升级前一定要有备份
  2. 建议保留旧版本节点组(不删),出问题时旧节点还能承载流量
  3. 测试环境先走一遍完整流程

时间估算

阶段 耗时
准备工作(AL2→AL2023、组件升级) 3-5 天
1.32→1.33 1-2 小时
1.33→1.34 1-2 小时
1.34→1.35 1-2 小时
全面验证 半天

总耗时:顺利的话一周搞定,核心升级在一天内完成。

总结

EKS 跨版本升级的核心经验:

  1. 别拖——越拖坑越多,一次跨三个版本和跨一个版本的工作量差 10 倍
  2. 先动节点 OS——AL2 迁 AL2023 是前置条件,不是可选项
  3. 先动监控组件——别让 Prometheus 在升级当天给你惊喜
  4. cluster-autoscaler 每版本同步升——不能跳
  5. 控制面升了回不了头——测试环境先跑一遍

三个最容易翻车的点:cgroup v1 节点起不来、老版本 client-go 不兼容、cluster-autoscaler 版本错配。

提前搞定这三个,升级当天就是走流程而已。


素材来源:亚马逊云科技官方博客 — 规划 Amazon EKS 从 1.32 升级到 1.35
相关文档:Amazon EKS 升级集群最佳实践

posted @ 2026-06-12 11:06  亚马逊云开发者  阅读(1)  评论(0)    收藏  举报