是否可以在 apiregistration.k8s.io/v1 APIService 中使用自动缩放/v2beta2 HPA?

问题描述

我创建了一个部署,它通过端点和注册自定义指标的 APIService 公开自定义指标,因此我可以在 HPA 中使用它来自动扩展部署。为了实现这一目标,我遵循了this tutorial

它在使用 apiregistration.k8s.io/v1beta1 APIService 时运行良好。该指标已正确公开,HPA 可以读取它并相应地进行缩放。我尝试将 APIService 更新到版本 apiregistration.k8s.io/v1(因为 v1beta1 在 Kubernetes v1.22 中已弃用并删除),但随后 HPA 无法再选择该指标,带有此消息:

Message
-------
unable to get metric threatmessages: Service on test services-metrics-service/unable to fetch 
metrics from custom metrics API: the server is currently unable to handle the request 
(get services.custom.metrics.k8s.io services-metrics-service)

如果我手动请求指标,它仍然存在:

kubectl get --raw /apis/custom.metrics.k8s.io/v1/namespaces/test/services/services-metrics-service/threatmessages |jq .
{
  "kind": "MetricValueList","apiVersion": "custom.metrics.k8s.io/v1","Metadata": {
    "selfLink": "custom.metrics.k8s.io/v1"
  },"items": [
    {
      "metricName": "threatmessages","timestamp": "2021-02-09T14:43:39.321Z","value": "0","describedobject": {
        "kind": "Service","namespace": "test","name": "services-metrics-service","apiVersion": "/v1"
      }
    }
  ]
}

这是我的 APIService 和 HPA 资源:

apiVersion: apiregistration.k8s.io/v1
kind: APIService
Metadata:
  name: v1.custom.metrics.k8s.io
spec:
  insecureSkipTLsverify: true
  group: custom.metrics.k8s.io
  groupPriorityMinimum: 1000
  versionPriority: 5
  service:
    name: services-metrics-service
    namespace: test
    port: 443
  version: v1
---
apiVersion: autoscaling/v2beta2
kind: HorizontalPodAutoscaler
Metadata:
  name: services-parallel-hpa
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: services-parallel-deployment
  minReplicas: 1
  maxReplicas: 10
  metrics:
  - type: Object
    object:
      describedobject:
        kind: Service
        name: services-metrics-service
      metric:
        name: threatmessages
      target:
        type: AverageValue
        averageValue: 4k
  behavior:
    scaleDown:
      stabilizationWindowSeconds: 30
      policies:
      - type: Pods
        value: 1
        periodSeconds: 30

我做错了什么?还是这两个版本因为某种原因不兼容?

解决方法

根据 APIService 1.22 文档,您可以找到信息:

  • 迁移清单和 API 客户端以使用自 v1.10 起可用的 apiregistration.k8s.io/v1 API 版本。
  • 所有现有的持久化对象都可以通过新的 API 访问
  • 无明显变化

首先,v1 可用于您使用的版本 (v.1.19)。

其次,也是更重要的,All existing persisted objects are accessible via the new APINo notable changes。这意味着使用 v1beta1 创建的对象不需要更新或修改。即使它们是使用 v1beta1 创建的,它们也将可用并正常工作。也就是说,升级到版本 v 1.22 后,您应该没有问题,相同的对象将可以简单地访问(并且,我认为,由 HPA 访问),就好像它们是使用 {{ 创建的一样1}}。此外,它们可能已经(在版本 v1 中)可以作为 1.19 访问,我将在接下来解释,因此您现在可以检查是否一切正常。

我对 v1 v 1.19 进行了一些快速测试,发现是否包含 GKE cluster(实际上,正是使用了有问题的 OP 提供的内容:

apiVersion: apiregistration.k8s.io/v1beta1

除了使用 apiVersion: apiregistration.k8s.io/v1 kind: APIService metadata: name: v1.custom.metrics.k8s.io spec: insecureSkipTLSVerify: true group: custom.metrics.k8s.io groupPriorityMinimum: 1000 versionPriority: 5 service: name: services-metrics-service namespace: test port: 443 version: v1 as v1beta1) 之外,然后使用 get 命令获取创建的内容 apiVersion,一个标有 apiVersion $ kubectl get apiservices/v1.custom.metrics.k8s.io --output=json 的对象,而不是v1,将获得 (v1beta1)。并且,如果在创建期间使用 "apiVersion": "apiregistration.k8s.io/v1" 而不是 apiVersion .../v1,则获得相同的结果。如果其中任何一个被删除,另一个就会消失。它是幕后的同一个对象。但它被标记为 apiVersion: apiregistration.k8s.io/v1beta1

由于上述所有原因,您应该简单地恢复到使用 v1 进行部署时所做的工作,因为它可以正常工作并将根据 APIService 1.22 文档继续工作。您还可以运行 v1beta1 命令,$ kubectl get apiservices/v1.custom.metrics.k8s.io --output=json$ kubectl get APIService --output=json 一旦部署了 $ kubectl get APIService.apiregistration.k8s.io --output=json 版本,以了解对象是否已经在幕后标记为使用 v1beta1使用 v1 创建了对象 - 就像我的情况一样。

如果对象已经使用 v1beta1 创建,则不需要使用 v1 创建。