零基础升级修复K8s Ingress
K8s Ingress Nginx高危漏洞(如CVE-2023-5043)可导致攻击者绕过鉴权或执行任意代码,修复的核心方案是将Ingress-Nginx Controller升级到官方已修复的版本(例如≥1.9.6)。
本文基于Helm和kubectl两种部署方式,给出从检查当前版本到完成升级并验证的完整操作流程,适合使用云服务器(如泽御云)自建集群的用户或企业运维人员直接执行。
第一步:确认当前版本与漏洞影响
在执行修复前,先确定你的Ingress-Nginx是否是受影响的版本。
通过kubectl查看当前Controller的镜像标签:
kubectl get pods -n ingress-nginx -o yaml | grep image: | head -1
返回类似 registry.k8s.io/ingress-nginx/controller:v1.8.1 的内容,版本号低于v1.9.0的均为高危漏洞影响版本。
如果是通过Helm安装的,也可以看Helm release信息:
helm list -n ingress-nginx
helm get values ingress-nginx -n ingress-nginx | grep controller.image.tag
第二步:备份当前配置(避坑关键)
无论使用哪种升级方式,务必先备份现有ConfigMap、Service和Ingress资源,防止升级后配置丢失。
kubectl get configmap -n ingress-nginx -o yaml > ingress-nginx-configmap-backup.yaml
kubectl get service -n ingress-nginx -o yaml > ingress-nginx-svc-backup.yaml
kubectl get ingress --all-namespaces -o yaml > ingress-backup.yaml
注意: 如果自定义了annotation或tcp-services,最好用kubectl describe记录关键参数。
第三步:选择升级方式并执行
方式A:Helm方式(推荐,适合Helm管理的集群)
添加或更新官方Helm仓库并升级release(以ingress-nginx为例):
helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
helm repo update
helm upgrade ingress-nginx ingress-nginx/ingress-nginx \
-n ingress-nginx \
--set controller.image.tag=v1.9.6 \
--reuse-values
--reuse-values保留原有自定义值,但如果版本跨度大(如v1.8→v1.9),建议去除该参数并手动合并配置。- 强烈建议先运行
helm upgrade加上--dry-run测试:--dry-run --debug。
方式B:kubectl直接替换镜像(适合非Helm部署)
编辑DaemonSet或Deployment(取决于你的部署方式):
kubectl edit deployment ingress-nginx-controller -n ingress-nginx
找到 spec.template.spec.containers[0].image,将值改为安全版本镜像(如 registry.k8s.io/ingress-nginx/controller:v1.9.6),保存退出。
Pod会自动滚动更新。
如果使用的是老版本nginx-ingress-controller(镜像名不同),请先改为registry.k8s.io/ingress-nginx/controller。
第四步:验证修复是否生效
升级后执行以下检查:
- Pod状态:确保所有Controller Pod处于
Running且READY为1/1。
kubectl get pods -n ingress-nginx -w
- 镜像版本:确认新Pod使用了目标版本。
kubectl get pods -n ingress-nginx -o jsonpath='{range .items[*]}{.spec.containers[0].image}{"\n"}{end}'
- Ingress规则正常:访问一个测试服务,确认路由仍然工作。
- 漏洞扫描:可以用
kubectl run临时启动一个curl容器,验证Ingress的HTTP头或443端口是否正常响应。
常见问题与避坑(FAQ)
问题1:升级后Ingress突然无法访问,怎么办?
可能原因:
Service type从LoadBalancer变成了ClusterIP(因为--reuse-values未保留service类型)。先检查Service:kubectl get svc -n ingress-nginx,
如果type不对,
执行kubectl edit svc ingress-nginx-controller -n ingress-nginx手动调整。
问题2:我用的是Helm,但升级后自定义的注解(annotations)丢失了?
因为--reuse-values只保留之前helm install时的值,
不包含后来手动编辑的annotation。建议将自定义配置写在values.yaml中,
通过-f values.yaml应用。
问题3:版本跨度大(例如v1.0→v1.9)需要注意什么?
部分API资源(如v1beta1 Ingress)已废弃。
升级前先确认集群版本(≥v1.22),必要时先迁移Ingress到networking.k8s.io/v1。
问题4:如何确认漏洞已经修复?
除了镜像版本≥修复版本外,还可以运行官方测试工具(如kubectl ingress-nginx validate)或参考CVE详情页的POC测试。
最后提醒
升级后建议观察24小时,确认监控指标正常后再下线旧Pod。
如果集群有多个Ingress实例(多节点),滚动升级期间应保留一定冗余副本以防流量中断。
对于生产环境,建议先在测试集群演练,再执行正式升级。
若遇到其他异常,可回退到备份的镜像版本并查阅官方变更日志。