How versioning works in Kubernetes, especially with CustomResourceDefinitions, is a common source of confusion.

The documentation is pretty comprehensive but a bit complicated. This post aims to give a simple description of how versioning works and dispel some misunderstandings.

There is only one primary version

Consider a CRD with versions alpha and beta. A user can create and view either resource version.

Intuitively, they must be distinct things -- they are not.

Each resource has a primary version (declared by stored in the CRD). Any read or writes against the resource is just a view of the same resource. You can see this with a simple query:

$ kubectl apply -f virtual-service.yaml
virtualservice.networking.istio.io/route created
$ kubectl get virtualservices.v1beta1.networking.istio.io
NAME      AGE
route     7s
$ kubectl get virtualservices.v1alpha3.networking.istio.io
NAME      AGE
route     10s

Here we can see that even though we created a single VirtualService object (it was v1beta1, in this case), we can query either version and get the same object.

Version conversion

If we look at the objects returned in the above queries, we can see something even more interesting:

$ kubectl get virtualservices.v1alpha3.networking.istio.io route -oyaml | grep 'apiVersion:'
apiVersion: networking.istio.io/v1alpha3
$ kubectl get virtualservices.v1beta1.networking.istio.io route -oyaml | grep 'apiVersion:'
apiVersion: networking.istio.io/v1beta1

Even though we are returning the same object, we see a different version-specific object returned.

This conversion can be done by either ensuring the schemas of the versions are identical (making the conversion trivial - just swap the version), or using a conversion webhook. All versions must be able to convert to and from other versions without data loss.

Istio does not use conversion webhooks, so all versions are identical.

"CRD" Naming

A common misnomer is to refer to resources defined by CRDs as "CRDs". For example, "I created a VirtualService CRD named my-virtual-service".

CRD stands for CustomResourceDefinition, and defines the schema for a resource. The instances of that resource are not CRDs.

I am not sure the instances have a formal name, but I commonly see "custom resource objects" or "CRs".

Removing versions and changing storage version

It's complicated.

Istio gets around this by never doing this.