0

I’m trying to purposefully create K8S resources with deprecated apiVersion for test purposes, but keep ending up with a converted resource to the non-deprecated apiVersion. I don’t understand why it’s happening and can’t find any discussion/topic on how to force K8S API to respect my resource manifest.

Does anyone know how it could be done? Or even why it’s acting like that?

Here is the resource I’m trying to create:

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: deprecated-ingress
spec:
  rules:
    - host: example.com
      http:
        paths:
          - path: /*
            pathType: ImplementationSpecific
            backend:
              serviceName: test
              servicePort: 80

I tried to create this resource on several clusters with the following versions:

  • 1.16
  • 1.21
  • 1.23

For each cluster, I was using the corresponding kubectl version. This is an indicator that the « conversion » is not happening client-side.

This is the created resource on cluster, as you can see, the apiVersion is not the same…

apiVersion: networking.k8s.io/v1                                                                                                                                                                                
kind: Ingress                                                                                                                                                                                                   
metadata:                                                                                                                                                                                                       
  annotations:                                                                                                                                                                                                  
    kubectl.kubernetes.io/last-applied-configuration: |                                                                                                                                                         
      {"apiVersion":"networking.k8s.io/v1beta1","kind":"Ingress","metadata":{"annotations":{},"name":"deprecated-ingress","namespace":"test1"},"spec":{"rules":[{"host":"example.com","http":{"paths":[{"backen
d":{"serviceName":"test","servicePort":80},"path":"/*","pathType":"ImplementationSpecific"}]}}]}}                                                                                                           
  creationTimestamp: "2022-06-02T12:06:04Z"                                                                                                                                                                     
  finalizers:                                                                                                                                                                                                   
  - networking.gke.io/ingress-finalizer-V2                                                                                                                                                                      
  generation: 1                                                                                                                                                                                                 
  managedFields:                                                                                                                                                                                                
  - apiVersion: networking.k8s.io/v1beta1                                                                                                                                                                       
    fieldsType: FieldsV1                                                                                                                                                                                        
    fieldsV1:                                                                                                                                                                                                   
      f:metadata:                                                                                                                                                                                               
        f:finalizers:                                                                                                                                                                                           
          .: {}                                                                                                                                                                                                 
          v:"networking.gke.io/ingress-finalizer-V2": {}
    manager: glbc
    operation: Update
    time: "2022-06-02T12:06:04Z"
  - apiVersion: networking.k8s.io/v1beta1
    fieldsType: FieldsV1
    fieldsV1:
      f:metadata:
        f:annotations:
          .: {}
          f:kubectl.kubernetes.io/last-applied-configuration: {}
      f:spec:
        f:rules: {}
    manager: kubectl
    operation: Update
    time: "2022-06-02T12:06:04Z"
  name: deprecated-ingress
  namespace: test1
  resourceVersion: "489457660"
  selfLink: /apis/networking.k8s.io/v1/namespaces/test1/ingresses/deprecated-ingress
  uid: c8c80e6f-3e72-45b7-aca7-d17ab4a49f19
spec:
  rules:
  - host: example.com
    http:
      paths:
      - backend:
          service:
            name: test
            port:
              number: 80
        path: /*
        pathType: ImplementationSpecific
status:
  loadBalancer: {}

I also tried with CronJob and version batch/v1beta1 and I ended up with the batch/v1 version.

1 Answers1

0

When you use the Kubernetes API to submit an object to the API server, you can then access that resource using any version of the same API that that your cluster knows how to serve.

This is part of how Kubernetes API versioning works. If you submit an Ingress to https://cluster.example/apis/networking.k8s.io/v1beta1/namespaces/example/ingresses then your request is treated as using the v1beta1 Ingress API, and you can then read that object back using a GET to https://cluster.example/apis/networking.k8s.io/v1/namespaces/example/ingresses/deprecated-ingress

The client selects which API to use. Try running kubectl get ingresses.v1beta1.networking.k8s.io deprecated-ingress and you can read that object back via the v1beta1 API. If you are using a client that's not kubectl, check what mechanism your client provides to select which API version to request.

There is also an implementation detail, which covers how that object is serialized into etcd. Unless you know that this matters to you, ignore what the serialized data look like and rely on Kubernetes' ability to automatically convert objects to any stable API version, regardless of how they are stored.

BTW: if you make CustomResourceDefinitions, the conversion is not automatic. You are expected to implement your own conversion code and configure the CustomResourceDefinition to call that as required, as an HTTP request/response RPC.

Tim B
  • 36
  • 2