Horizontal Pod Autoscaler Version Not Found
Errors
bash
helm upgrade foo foo.tgz -f values.yaml
bash
Error: UPGRADE FAILED: resource mapping not found for name: "foo" namespace: "" from "":
no matches for kind "HorizontalPodAutoscaler" in version "autoscaling/v2beta1"
ensure CRDs are installed first
bash
no matches for kind "HorizontalPodAutoscaler" in version "autoscaling/v2beta1"
Helm 在升级的时候(包括卸载旧版本)找不到 HorizontalPodAutoscaler
资源。
原因分析
- Kubernetes 版本太新,不再支持
autoscaling/v2beta1
:- 从 Kubernetes 1.26 开始,
autoscaling/v2beta1
被移除。 - 推荐使用
autoscaling/v2
或autoscaling/v1
。
- 从 Kubernetes 1.26 开始,
- Chart 中使用了老版本 API:
- 你的 Helm Chart
foo.tgz
里声明了autoscaling/v2beta1
,而你的集群不支持这个版本。
- 你的 Helm Chart
查看支持的 API
bash
kubectl api-versions | grep autoscaling
bash
autoscaling/v1
autoscaling/v2
bash
kubectl api-resources | awk 'NR==1 || /autoscaling/'
bash
NAME SHORTNAMES APIGROUP NAMESPACED KIND
horizontalpodautoscalers hpa autoscaling true HorizontalPodAutoscaler
解决方法
修改 API 版本
在 Chart 包中查找包含 v2veta1
的文件,修改文件中的 apiVersion: autoscaling/v2beta1
为 autoscaling/v2
。
bash
grep -ir v2beta1 .
检查结果
bash
helm template foo . -f values.yaml > rendered.yaml
查看 rendered.yaml
是否含有 autoscaling/v2beta1
仍然失败
Helm upgrade 会调用 Kubernetes API 删除旧资源,如果资源所用的 API version 在 Kubernetes 中已彻底移除,就会导致删除失败,无法升级。 虽然新的资源已经不包含 v2beta1
,但升级的时候需要卸载旧资源,旧资源还包含 v2beta1
,可以使用下面的命令检查。
bash
helm get manifest <release-name> | grep -C 5 v2beta1
还可以查看 hpa
bash
kubectl get hpa
这个时候需要使用 helm
手动删除旧的资源,但删除的时候会发现一直处于 uninstalling
状态。
bash
code-search-server cmb-gitaly 51 2025-04-10 15:53:40.557116 +0800 CST uninstalling search-server-0.1.9 1.16.0
这是因为 HorizontalPodAutoscaler
的 autoscaling/v2beta1
在集群中已不可用,Helm 无法删除它。 这个时候,需要手动删除 helm
的 secret
。
bash
kubectl get secret -l "owner=helm" | grep foo | awk '{print $1}' | xargs -I {} kubectl delete secret {}
卸载成功后便可以再次安装新资源。
Questions
TIP
为什么这个集群能运行已经不支持的 api-versions
因为已经部署在集群中的旧资源,只要没有被删除,就会继续存在,即使它们使用的 apiVersion
(如 autoscaling/v2beta1
)在当前 Kubernetes 版本中已被移除。
Kubernetes 对资源的支持分两个方面:
内容 | 说明 |
---|---|
api-versions (接口支持) | 控制你是否能创建 / 修改 / 删除某个 API 版本的资源 |
etcd 中的对象存储(持久数据) | Kubernetes 永远不会自动删除已经存储在 etcd 中的对象,即使它的 API 被移除了 |
HorizontalPodAutoscaler
对象是之前用autoscaling/v2beta1
创建的;- 现在你升级了 Kubernetes,
v2beta1
的 API 被移除; - 你 无法再通过 kubectl 或 Helm 访问、删除、修改这些旧对象,因为 API Server 不识别
v2beta1
; - 但这些对象 仍然存在于 etcd 中,Kube Controller 仍然“部分地”在运行它们(尤其如果它已经升级为
v2
的内部实现);
这就造成了一种“僵尸资源”的状态 —— 存在但不可管理。