<p>I've created a deployment which exposes a custom metric through an endpoint and an APIService that registers this custom metric, so I can use it in an HPA to autoscale the deployment. To achieve this, I've followed <a href="https://medium.com/swlh/building-your-own-custom-metrics-api-for-kubernetes-horizontal-pod-autoscaler-277473dea2c1" rel="nofollow noreferrer">this tutorial</a>.</p>
<p>It worked well while using an apiregistration.k8s.io/<strong>v1beta1</strong> APIService. The metric was exposed correctly and the HPA could read it and scale accordingly. I've tried to update the APIService to version apiregistration.k8s.io/<strong>v1</strong> (as v1beta1 is deprecated and removed in Kubernetes v1.22), but then the HPA couldn't pick the metric anymore, with this message:</p>
<pre><code>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)
</code></pre>
<p>If I manually request the metric, it exists though:</p>
<pre class="lang-sh prettyprint-override"><code>kubectl get --raw /apis/custom.metrics.k8s.io/v1/namespaces/test/services/services-metrics-service/threatmessages |jq .
{
  &quot;kind&quot;: &quot;MetricValueList&quot;,
  &quot;apiVersion&quot;: &quot;custom.metrics.k8s.io/v1&quot;,
  &quot;metadata&quot;: {
    &quot;selfLink&quot;: &quot;custom.metrics.k8s.io/v1&quot;
  },
  &quot;items&quot;: [
    {
      &quot;metricName&quot;: &quot;threatmessages&quot;,
      &quot;timestamp&quot;: &quot;2021-02-09T14:43:39.321Z&quot;,
      &quot;value&quot;: &quot;0&quot;,
      &quot;describedObject&quot;: {
        &quot;kind&quot;: &quot;Service&quot;,
        &quot;namespace&quot;: &quot;test&quot;,
        &quot;name&quot;: &quot;services-metrics-service&quot;,
        &quot;apiVersion&quot;: &quot;/v1&quot;
      }
    }
  ]
}
</code></pre>
<p>Here are my APIService and HPA resources:</p>
<pre class="lang-yaml prettyprint-override"><code>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
</code></pre>
<p>What am I doing wrong? Or are these 2 versions just not compatible for some reason?</p>

<p>According to <a href="https://kubernetes.io/docs/reference/using-api/deprecation-guide/#apiservice-v122" rel="nofollow noreferrer">APIService 1.22</a> documentation you can find information:</p>
<blockquote>
<ul>
<li>Migrate manifests and API clients to use the apiregistration.k8s.io/v1 API version, available since v1.10.</li>
<li>All existing persisted objects are accessible via the new API</li>
<li>No notable changes</li>
</ul>
</blockquote>
<p>First of all, <code>v1</code> is available for the version you are using (v.1.19).</p>
<p>Secondly, and more important, <code>All existing persisted objects are accessible via the new API</code> and <code>No notable changes</code>. This means that the objects created using <code>v1beta1</code> don't need to be updated or modified. They will be available and working even if they were created using <code>v1beta1</code>. That is, after upgrading to version <code>v 1.22</code>, you should have no issue, the same objects will simply be accessible (and, I would think, accessed by <code>HPA</code>) as if they had been created using <code>v1</code>. What is more, they may already (in version <code>1.19</code>) be accessible as <code>v1</code>, as I will explain next, so you can check now if everything is fine.</p>
<p>I have run some quick tests on a <code>v 1.19</code> <code>GKE cluster</code> and found if something contains <code>apiVersion: apiregistration.k8s.io/v1beta1</code> (in fact, using exactly what the OP provided in in question:</p>
<pre><code>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
</code></pre>
<p>except using <code>v1beta1</code> as <code>apiVersion</code>) is applied, and then a get command is used to obtain what was created <code> $ kubectl get apiservices/v1.custom.metrics.k8s.io --output=json</code>, an object marked with apiVersion <code>v1</code>, not <code>v1beta1</code>, will be obtained (<code>&quot;apiVersion&quot;: &quot;apiregistration.k8s.io/v1&quot;</code>). And if, intead, <code>apiVersion .../v1</code> is used during the creation instead of <code>apiVersion: apiregistration.k8s.io/v1beta1</code>, the same is obtained. If either of those is deleted, the other one is gone. It is the same object behind the scenes. Yet it is marked as <code>v1</code>.</p>
<p>As a result of all the above, you should simply revert back to what you were doing when you deployed using <code>v1beta1</code>, given it worked and will keep on working according to <a href="https://kubernetes.io/docs/reference/using-api/deprecation-guide/#apiservice-v122" rel="nofollow noreferrer">APIService 1.22</a> documentation. You can also run <code>$ kubectl get apiservices/v1.custom.metrics.k8s.io --output=json</code> command, either <code>$ kubectl get APIService --output=json</code> or <code>$ kubectl get APIService.apiregistration.k8s.io --output=json</code> once deployed <code>v1beta1</code> version, to understand if object is already marked as using <code>v1</code> behind the scenes despite having created the object with <code>v1beta1</code> - like is happening in my case.</p>
<p>Creating objects with <code>v1</code> is not necessary if they were already created with <code>v1beta1</code>.</p>
