<p>There is a field in the CRD called 'storage'</p>
<pre><code>apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
spec:
      ...
      versions:
      - name: v1
        # Each version can be enabled/disabled by Served flag.
        served: true
        # One and only one version must be marked as the storage version.
        storage: true
      ...
</code></pre>
<p>What does this mean? <br>
All the documentation says is the above comment:</p>
<pre><code> One and only one version must be marked as the storage version.
</code></pre>
<p>It just doesn't help at all.</p>

<p>A k8s resource (including custom resource) can have support for multiple API versions (say <code>v1beta1</code>, <code>v1</code>, etc.) at once. It's there for various reasons such as API stability and backward compatibility.</p>
<p>As you know, on the creation of a resource's object, the k8s store it on persistent storage such as <code>etcd</code>.     The version with <code>storage: true</code> indicates that this version should be used when persisting the resources to storage. It's inconvenient to store multiple copies of an object. That's why <code>One and only one version must be marked as the storage version</code>. On-demand of other versions with <code>storage: false</code> a conversion webhook should be used to toggle in-between versions with recommended schema changes and custom logic.</p>
<p>Ref:</p>
<ul>
<li><a href="https://kubernetes.io/docs/tasks/extend-kubernetes/custom-resources/custom-resource-definition-versioning/#overview" rel="nofollow noreferrer">custom-resource-definition-versioning</a></li>
</ul>
