K8s CRD Versioning¶
Updating a CRD in Kubernetes involves adding a new version to the CRD, and then doing a "dance", which many often skip.
What would you need to know about K8s CRD Versions?¶
- Each version has these two fields:
served(boolean): is this version is served by the API server? (e.g. accessible for k8s clients)storage(boolean): if this version is how the resources of this CRD (across all versions) are stored in etcd?- There has to be x1 of these set to
true, and only x1. All other versions have to have this field set tofalse.
- There has to be x1 of these set to
- The CRD versions follow a1
hub(the version withstorageset totrue) andspokes (all versions withservedset totrue) model
So how does this relate to a conversion webhook?¶
When using the https://kubebuilder.io's controller-runtime, which we leverage in the NAIS platform's liberator, a conversion webhook2:
- will always convert from the
storage == trueversion - must be able to convert to any of the
served == trueversions
So, what are the general steps to follow?¶
- Design/spec out the new CRD version
- Write the conversion webhook that satisfies the list in how does this relate to a
conversion webhook? - Install to the cluster/add a new version to the CRD + the required
spec.conversionfield which configures the conversion webhook - Verify that you can
kubectl get <resource kind>.<new resource version>.<resource apiVersion without the '/<version>'>for your custom resorces - Update all clients leveraging this CRD to make use of/reference
apiVersionof this CRD with the new version - Update the CRD's new version to
storage == true, and thus also setstorage == falsein any other version- Remember to also update
conversion webhooknow, if necessary
- Remember to also update
- If you don't want to remove the old version(s), you can stop now.
- If you want to remove the old version(s), proceed with the remaining steps
- Update the CRD to have
served == falsefor all versions you want to remove - Use the prometheus metric
apiserver_storage_objectsto ensure all of the resources are stored in the newstorage == trueversion3 - Delete the version(s) you want to remove from the CRD
- If there's only 1x version of the CRD left, you can delete the
conversion webhookand its config too - Remember to delete any code that handle multiple versions from step 6.
- If there's only 1x version of the CRD left, you can delete the
Just give me a damn nais-specific checklist¶
- Add new CRD version +
conversion webhookconfig to liberator/nais-crds's fasit-feature- !!! DON'T DEPLOY !!! -
Eg. don't merge/push to
mainyet!
- !!! DON'T DEPLOY !!! -
Eg. don't merge/push to
- Turn off reconciliation in
fasitfor all envs/tenants fornais-crdsyou don't want to test in - Now you can deploy
nais-crds, ref step 1. - When happy, deploy to all envs/tenants
- without having changed which CRD version has
storage == true
- without having changed which CRD version has
- Update all clients that leverage this CRD to use the new version, eg:
- operators
- controllers
- tools generating k8s yamls that get
kubectl applyed
- Set
storage == trueto the new version- Remember to update the
conversion webhookif necessary, ref the notes onconversion webhooks
- Remember to update the
- Set
served == falsefor the old version(s), and/or delete them from the CRD - If other versions (besides the one that has
served == true && storage == true) have been removed- You can now delete the
conversion webhookand its config.
- You can now delete the
- Remember to clean up all solutions that support the old/removed versions from step 5.