Skip to content

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
Key Errors
bash
no matches for kind "HorizontalPodAutoscaler" in version "autoscaling/v2beta1"

Helm 在升级的时候(包括卸载旧版本)找不到 HorizontalPodAutoscaler 资源。

原因分析

  • Kubernetes 版本太新,不再支持 autoscaling/v2beta1
    • 从 Kubernetes 1.26 开始,autoscaling/v2beta1 被移除。
    • 推荐使用 autoscaling/v2autoscaling/v1
  • Chart 中使用了老版本 API
    • 你的 Helm Chart foo.tgz 里声明了 autoscaling/v2beta1,而你的集群不支持这个版本。

查看支持的 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/v2beta1autoscaling/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 状态。

第 51 次卸载失败
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

这是因为 HorizontalPodAutoscalerautoscaling/v2beta1 在集群中已不可用,Helm 无法删除它。 这个时候,需要手动删除 helmsecret

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 的内部实现);

这就造成了一种“僵尸资源”的状态 —— 存在但不可管理。