From c7380cb5ae84afaf37e0a72e98f02b6062a025a6 Mon Sep 17 00:00:00 2001 From: Mehdy Bohlool Date: Tue, 13 Nov 2018 11:07:56 -0800 Subject: [PATCH] CR conversion --- .../custom-resource-definition-versioning.md | 122 ++++++++++++++++-- 1 file changed, 111 insertions(+), 11 deletions(-) diff --git a/content/en/docs/tasks/access-kubernetes-api/custom-resources/custom-resource-definition-versioning.md b/content/en/docs/tasks/access-kubernetes-api/custom-resources/custom-resource-definition-versioning.md index 11d22745c7251..87598024bbbee 100644 --- a/content/en/docs/tasks/access-kubernetes-api/custom-resources/custom-resource-definition-versioning.md +++ b/content/en/docs/tasks/access-kubernetes-api/custom-resources/custom-resource-definition-versioning.md @@ -11,14 +11,9 @@ weight: 30 {{% capture overview %}} This page explains how to add versioning information to [CustomResourceDefinitions](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#customresourcedefinition-v1beta1-apiextensions), to indicate the stability -level of your CustomResourceDefinitions. It also describes how to upgrade an +level of your CustomResourceDefinitions or advance your API to a new version with conversion between them. It also describes how to upgrade an object from one version to another. -{{< note >}} -**Note**: All specified versions must use the same schema. The is no schema -conversion between versions. -{{< /note >}} - {{% /capture %}} {{% capture prerequisites %}} @@ -37,9 +32,10 @@ conversion between versions. The CustomResourceDefinition API supports a `versions` field that you can use to support multiple versions of custom resources that you have developed, and -indicate the stability of a given custom resource. All versions must currently -use the same schema, so if you need to add a field, you must add it to all -versions. +indicate the stability of a given custom resource. Versions can have different +schemas and a conversion webhook can be defined to convert a version to another. +These conversion should follow API convensions (TODO link) specially They should +be round-trippable. {{< note >}} Earlier iterations included a `version` field instead of `versions`. The @@ -49,8 +45,9 @@ match the first item in the `versions` field. ## Specify multiple versions -This example shows a CustomResourceDefinition with two versions. The comments in -the YAML provide more context. +This example shows a CustomResourceDefinition with two versions. For the first +example, the assumption is all versions share the same schema with no conversion +between them. The comments in the YAML provide more context. ```yaml apiVersion: apiextensions.k8s.io/v1beta1 @@ -71,6 +68,10 @@ spec: - name: v1 served: true storage: false + conversion: + # a None strategy will asuume same schema for all versions and only set apiVersion + # field of the CRs to the proper value on conversion. + strategy: None # either Namespaced or Cluster scope: Namespaced names: @@ -144,6 +145,105 @@ version sort order is `v1`, followed by `v1beta1`. This causes the kubectl command to use `v1` as the default version unless the provided object specifies the version. +## Webhook conversion + +The above example assumed a None converter between versions which only set apiVersion field +on conversion to the proper value and do not change the rest of the object. API server supports +webhook conversion to call an external service on CR conversions. These conversion calls happens +whenever a different version is requested from the stored version or when the provided object is +not in the sotre version. + +### Write a conversion webhook server + +Please refer to the implementation of the [CR conversion webhook +server](https://github.com/kubernetes/kubernetes/blob/v1.13.0-beta.1/test/images/crd-conversion-webhook/main.go) +that is validated in a Kubernetes e2e test. The webhook handles the +`conversionReview` requests sent by the apiservers, and sends back its decision +wrapped in `conversionResponse`. + +The example conversion webhook server leaves the `ClientAuth` field +[empty](https://github.com/kubernetes/kubernetes/blob/v1.10.0-beta.1/test/images/crd-conversion-webhook/config.go#L48-L49), +which defaults to `NoClientCert`. This means that the webhook server does not +authenticate the identity of the clients, supposedly apiservers. If you need +mutual TLS or other ways to authenticate the clients, see +how to [authenticate apiservers](/docs/reference/access-authn-authz/extensible-admission-controllers/#authenticate-apiservers). +The example server is organized in a way to be reused for other conversions. Most of the common codes are located in the [framework file]((https://github.com/kubernetes/kubernetes/blob/v1.10.0-beta.1/test/images/crd-conversion-webhook/converter/framework.go)) leaving only [one function]((https://github.com/kubernetes/kubernetes/blob/v1.10.0-beta.1/test/images/crd-conversion-webhook/converter/example-converter.go#L29-L80)) to be implemented for different conversion. + +### Deploy the admission webhook service + +To deploy example conversion webhook, refer to [admission webhook example service](/docs/reference/access-authn-authz/extensible-admission-controllers/#deploy_the_admission_webhook_service). +The assumption for next sections is the conversion webhook server is deployed to a service named `exampleConversionWebhookServer` in `default` namespace. + +{{< note >}} +**Note:** When the webhook server is deployed into the Kubernetes cluster as a +service, it has to expose its service on the 443 port. The communication +between the API server and the webhook service may fail if a different port +is used. +{{< /note >}} + +### Configure CustomResourceDefinition to use conversion webhooks + +The example above can be extended to use the conversion webhook by modifying `conversion` +section of the `spec`: + +```yaml +apiVersion: apiextensions.k8s.io/v1beta1 +kind: CustomResourceDefinition +metadata: + # name must match the spec fields below, and be in the form: . + name: crontabs.example.com +spec: + # group name to use for REST API: /apis// + group: example.com + # list of versions supported by this CustomResourceDefinition + versions: + - name: v1beta1 + # 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 + - name: v1 + served: true + storage: false + conversion: + # a Webhook strategy instruct API server to call an external webhook for any conversion between CRs. + strategy: None + webhookClientConfig: + service: + namespace: default + name: exampleConversionWebhookServer + caBundle: + # either Namespaced or Cluster + scope: Namespaced + names: + # plural name to be used in the URL: /apis/// + plural: crontabs + # singular name to be used as an alias on the CLI and for display + singular: crontab + # kind is normally the CamelCased singular type. Your resource manifests use this. + kind: CronTab + # shortNames allow shorter string to match your resource on the CLI + shortNames: + - ct +``` + +{{< note >}} +**Note:** When using `clientConfig.service`, the server cert must be valid for +`..svc`. +{{< /note >}} + +You can save the CustomResourceDefinition in a YAML file, then use +`kubectl apply` to apply it. + +```shell +kubectl create -f my-versioned-crontab-with-conversion.yaml +``` + +Make sure the conversion servie is up and running before applying new changes. +When an apiserver receives a request for a CR the needs conversion (e.g. read CRs +with different version than storage version), the apiserver sends an +`conversionReview` request to webhook as specified in the `webhookClientConfig`. + ## Writing, reading, and updating versioned CustomResourceDefinition objects When an object is written, it is persisted at the version designated as the