Must CRD version migration work both ways?

11/23/2021

I develop a component that utilises CRDs and is available in two versions - v1 and v2. It is possible to create a v2 resource based on v1 definition but it cannot be done the opposite way. V2 just drops some fields since they are not required anymore. I've developed a web hook to automatically convert existing resources. Conversion is defined as follows in crd definition:

conversion:
  strategy: Webhook
  webhook:
    conversionReviewVersions: ["v1", "v2"]
    clientConfig:
      service:
        namespace: fancy-project
        name: conversion-webhook
        path: /crdconvert

v2 version is defined as served and storage whereas v1 only as served. My conversion webhook returns with success when it is queried about conversion from v1 to v2 but fails when a request of conversion from v2 to v1 is made. When I try to create a new resource using v1 definition I see an error stating that from server for: "v1resource.yml": conversion webhook for component/v2, Kind=Proponent failed: Incompatible conversion. In logs I saw that Kubernetes queried my hook in order to convert from v2 to v1 and before that it requested conversion from v1 to v2. When I issue creation of v2 resource directly everything works fine. Why Kubernetes converts a resource to v2 first and then tries to downgrade it? Do versions of crds must be compatible with each other?

Note that when I allow the conversion from v2 to v1 and use some dummy fields to fill the definition everything starts to work as expected. It means that a v1 resource is created and then migrated to v2

Version:

Client Version: 4.6.32
Server Version: 4.6.32
Kubernetes Version: v1.19.0+d670f74
-- Mateusz Stompór
kubernetes
kubernetes-custom-resources
openshift

0 Answers