K8s 集群升级后 API 废弃导致资源无法更新的排查与处理
2026-08-11 00:53:03 # Kubernetes

问题现象与背景原因

将集群从 1.21 升级到 1.24 后,部分旧 Deployment 无法更新,Ingress 全部失效,controller 日志报 no matches for kind "Ingress" in version "networking.k8s.io/v1beta1"

根因是 Kubernetes 版本升级会移除已废弃(Deprecated)的 API 版本。例如:

  • networking.k8s.io/v1beta1 Ingress 在 1.22 移除;
  • extensions/v1beta1 Ingress / Deployment 早已废弃;
  • batch/v1beta1 CronJob 在 1.25 移除;
  • policy/v1beta1 PodSecurityPolicy 在 1.25 移除。

升级后 apiserver 不再识别这些旧版本,资源无法被读取 / 更新。

排查过程(思路与定位方法)

升级前用 kube-no-trouble(kubent)扫描集群里所有废弃 API:

1
2
3
# 下载 kubent 后运行
./kubent
# 输出会列出:哪个资源、当前用的 API 版本、将在哪个 K8s 版本被移除

升级后定位报错资源:

1
2
3
4
kubectl get ingress -A            # 可能报错或为空
kubectl apply -f old-ingress.yaml # 报错 "no matches for kind Ingress in version v1beta1"
# 看 apiserver 废弃告警
kubectl get events -A --sort-by=.lastTimestamp | grep -i deprecat

确认目标版本支持的新 API:

1
kubectl api-versions | grep networking.k8s.io   # 确认 v1 存在

解决方法

将 YAML 迁移到新版本 API,以 Ingress 为例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# 旧(v1beta1,已移除)
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
spec:
rules:
- host: app.example.com
http:
paths:
- path: /
backend:
serviceName: app
servicePort: 80
---
# 新(v1,必须显式写 ingressClassName 与 pathType)
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: app
spec:
ingressClassName: nginx
rules:
- host: app.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: app
port:
number: 80

批量转换(兼容场景):

1
kubectl convert -f old.yaml --output-version networking.k8s.io/v1

升级策略:采用蓝绿升级或金丝雀升级,先在小规模节点验证,再全量;升级前务必 kubent 扫描并修完所有废弃 API。

操作命令速查

1
2
3
4
./kubent                              # 升级前扫描废弃 API
kubectl api-versions | grep <group> # 确认新版本可用
kubectl convert -f old.yaml --output-version <group>/v1
kubectl explain ingress.spec.rules # 查新版字段结构

经验总结

  • 升级前必做 kubent 扫描,把废弃 API 全部改完再升,能省下 80% 的升级事故。
  • 废弃 API 移除是”硬断裂”,不像弃用期有兼容,升级后直接不可用。
  • 优先用蓝绿 / 金丝雀升级,保留回滚能力。
  • 写 YAML 时尽量用当前稳定 v1 版本,减少未来升级负担。