CustomResourceDefinition API 的versions字段可用于支持您自定义资源的多个版本已经开发的。版本可以具有不同的架构,并且转换 Webhooks 可以在版本之间转换自定义资源。
在适用的情况下,Webhook 转换应遵循 Kubernetes API。
注意: In apiextensions.k8s.io/v1beta1, there was a version field instead of versions. The
version field is deprecated and optional, but if it is not empty, it must
match the first item in the versions field.
apiVersion:apiextensions.k8s.io/v1beta1kind:CustomResourceDefinitionmetadata:# name must match the spec fields below, and be in the form: <plural>.<group>name:crontabs.example.comspec:# group name to use for REST API: /apis/<group>/<version>group:example.com# list of versions supported by this CustomResourceDefinitionversions:-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# A schema is requiredschema:openAPIV3Schema:type:objectproperties:host:type:stringport:type:string-name:v1served:truestorage:falseschema:openAPIV3Schema:type:objectproperties:host:type:stringport:type:string# The conversion section is introduced in Kubernetes 1.13+ with a default value of# None conversion (strategy sub-field set to None).conversion:# None conversion assumes the same schema for all versions and only sets the apiVersion# field of custom resources to the proper valuestrategy:None# either Namespaced or Clusterscope:Namespacednames:# plural name to be used in the URL: /apis/<group>/<version>/<plural>plural:crontabs# singular name to be used as an alias on the CLI and for displaysingular: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 CLIshortNames:-ct
# Deprecated in v1.16 in favor of apiextensions.k8s.io/v1apiVersion:apiextensions.k8s.io/v1beta1kind:CustomResourceDefinitionmetadata:# name must match the spec fields below, and be in the form: <plural>.<group>name:crontabs.example.comspec:# group name to use for REST API: /apis/<group>/<version>group:example.com# list of versions supported by this CustomResourceDefinitionversions:-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:v1served:truestorage:falsevalidation:openAPIV3Schema:type:objectproperties:host:type:stringport:type:string# The conversion section is introduced in Kubernetes 1.13+ with a default value of# None conversion (strategy sub-field set to None).conversion:# None conversion assumes the same schema for all versions and only sets the apiVersion# field of custom resources to the proper valuestrategy:None# either Namespaced or Clusterscope:Namespacednames:# plural name to be used in the URL: /apis/<group>/<version>/<plural>plural:crontabs# singular name to be used as an alias on the CLI and for displaysingular: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 CLIshortNames:-ct
apiVersion:apiextensions.k8s.io/v1kind:CustomResourceDefinitionmetadata:# name must match the spec fields below, and be in the form: <plural>.<group>name:crontabs.example.comspec:# group name to use for REST API: /apis/<group>/<version>group:example.com# list of versions supported by this CustomResourceDefinitionversions:-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# Each version can define it's own schema when there is no top-level# schema is defined.schema:openAPIV3Schema:type:objectproperties:hostPort:type:string-name:v1served:truestorage:falseschema:openAPIV3Schema:type:objectproperties:host:type:stringport:type:stringconversion:# a Webhook strategy instruct API server to call an external webhook for any conversion between custom resources.strategy:Webhook# webhook is required when strategy is `Webhook` and it configures the webhook endpoint to be called by API server.webhook:# conversionReviewVersions indicates what ConversionReview versions are understood/preferred by the webhook.# The first version in the list understood by the API server is sent to the webhook.# The webhook must respond with a ConversionReview object in the same version it received.conversionReviewVersions:["v1","v1beta1"]clientConfig:service:namespace:defaultname:example-conversion-webhook-serverpath:/crdconvertcaBundle:"Ci0tLS0tQk...<base64-encoded PEM bundle>...tLS0K"# either Namespaced or Clusterscope:Namespacednames:# plural name to be used in the URL: /apis/<group>/<version>/<plural>plural:crontabs# singular name to be used as an alias on the CLI and for displaysingular: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 CLIshortNames:-ct
# Deprecated in v1.16 in favor of apiextensions.k8s.io/v1apiVersion:apiextensions.k8s.io/v1beta1kind:CustomResourceDefinitionmetadata:# name must match the spec fields below, and be in the form: <plural>.<group>name:crontabs.example.comspec:# group name to use for REST API: /apis/<group>/<version>group:example.com# prunes object fields that are not specified in OpenAPI schemas below.preserveUnknownFields:false# list of versions supported by this CustomResourceDefinitionversions:-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# Each version can define it's own schema when there is no top-level# schema is defined.schema:openAPIV3Schema:type:objectproperties:hostPort:type:string-name:v1served:truestorage:falseschema:openAPIV3Schema:type:objectproperties:host:type:stringport:type:stringconversion:# a Webhook strategy instruct API server to call an external webhook for any conversion between custom resources.strategy:Webhook# webhookClientConfig is required when strategy is `Webhook` and it configures the webhook endpoint to be called by API server.webhookClientConfig:service:namespace:defaultname:example-conversion-webhook-serverpath:/crdconvertcaBundle:"Ci0tLS0tQk...<base64-encoded PEM bundle>...tLS0K"# either Namespaced or Clusterscope:Namespacednames:# plural name to be used in the URL: /apis/<group>/<version>/<plural>plural:crontabs# singular name to be used as an alias on the CLI and for displaysingular: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 CLIshortNames:-ct
# Deprecated in v1.16 in favor of apiextensions.k8s.io/v1apiVersion:apiextensions.k8s.io/v1beta1kind:CustomResourceDefinition...spec:...conversion:strategy:WebhookwebhookClientConfig:url:"https://my-webhook.example.com:9443/my-webhook-path"...
# Deprecated in v1.16 in favor of apiextensions.k8s.io/v1apiVersion:apiextensions.k8s.io/v1beta1kind:CustomResourceDefinition...spec:...conversion:strategy:WebhookwebhookClientConfig:service:namespace:my-service-namespacename:my-service-namepath:/my-pathport:1234caBundle:"Ci0tLS0tQk...<base64-encoded PEM bundle>...tLS0K"...
Webhook-请求和响应
请求
向 Webhooks 发送 POST 请求,请求的内容类型为:application/json,与 APIapitensions.k8s.io API 组中的 ConversionReview API 对象一起使用序列化为 JSON 作为主体。
# Deprecated in v1.16 in favor of apiextensions.k8s.io/v1apiVersion:apiextensions.k8s.io/v1beta1kind:CustomResourceDefinition...spec:...conversion:strategy:WebhookconversionReviewVersions:["v1","v1beta1"]...
API servers send the first ConversionReview version in the conversionReviewVersions list they support.
If none of the versions in the list are supported by the API server, the custom resource definition will not be allowed to be created.
If an API server encounters a conversion webhook configuration that was previously created and does not support any of the ConversionReview
versions the API server knows how to send, attempts to call to the webhook will fail.
{"apiVersion":"apiextensions.k8s.io/v1","kind":"ConversionReview","request":{# Random uid uniquely identifying this conversion call"uid":"705ab4f5-6393-11e8-b7cc-42010a800002",# The API group and version the objects should be converted to"desiredAPIVersion":"example.com/v1",# The list of objects to convert.# May contain one or more objects, in one or more versions."objects":[{"kind":"CronTab","apiVersion":"example.com/v1beta1","metadata":{"creationTimestamp":"2019-09-04T14:03:02Z","name":"local-crontab","namespace":"default","resourceVersion":"143","uid":"3415a7fc-162b-4300-b5da-fd6083580d66"},"hostPort":"localhost:1234"},{"kind":"CronTab","apiVersion":"example.com/v1beta1","metadata":{"creationTimestamp":"2019-09-03T13:02:01Z","name":"remote-crontab","resourceVersion":"12893","uid":"359a83ec-b575-460d-b553-d859cedde8a0"},"hostPort":"example.com:2345"}]}}
{# Deprecated in v1.16 in favor of apiextensions.k8s.io/v1"apiVersion":"apiextensions.k8s.io/v1beta1","kind":"ConversionReview","request":{# Random uid uniquely identifying this conversion call"uid":"705ab4f5-6393-11e8-b7cc-42010a800002",# The API group and version the objects should be converted to"desiredAPIVersion":"example.com/v1",# The list of objects to convert.# May contain one or more objects, in one or more versions."objects":[{"kind":"CronTab","apiVersion":"example.com/v1beta1","metadata":{"creationTimestamp":"2019-09-04T14:03:02Z","name":"local-crontab","namespace":"default","resourceVersion":"143","uid":"3415a7fc-162b-4300-b5da-fd6083580d66"},"hostPort":"localhost:1234"},{"kind":"CronTab","apiVersion":"example.com/v1beta1","metadata":{"creationTimestamp":"2019-09-03T13:02:01Z","name":"remote-crontab","resourceVersion":"12893","uid":"359a83ec-b575-460d-b553-d859cedde8a0"},"hostPort":"example.com:2345"}]}}
{"apiVersion":"apiextensions.k8s.io/v1","kind":"ConversionReview","response":{# must match <request.uid>"uid":"705ab4f5-6393-11e8-b7cc-42010a800002","result":{"status":"Success"},# Objects must match the order of request.objects, and have apiVersion set to <request.desiredAPIVersion>.# kind, metadata.uid, metadata.name, and metadata.namespace fields must not be changed by the webhook.# metadata.labels and metadata.annotations fields may be changed by the webhook.# All other changes to metadata fields by the webhook are ignored."convertedObjects":[{"kind":"CronTab","apiVersion":"example.com/v1","metadata":{"creationTimestamp":"2019-09-04T14:03:02Z","name":"local-crontab","namespace":"default","resourceVersion":"143","uid":"3415a7fc-162b-4300-b5da-fd6083580d66"},"host":"localhost","port":"1234"},{"kind":"CronTab","apiVersion":"example.com/v1","metadata":{"creationTimestamp":"2019-09-03T13:02:01Z","name":"remote-crontab","resourceVersion":"12893","uid":"359a83ec-b575-460d-b553-d859cedde8a0"},"host":"example.com","port":"2345"}]}}
{# Deprecated in v1.16 in favor of apiextensions.k8s.io/v1"apiVersion":"apiextensions.k8s.io/v1beta1","kind":"ConversionReview","response":{# must match <request.uid>"uid":"705ab4f5-6393-11e8-b7cc-42010a800002","result":{"status":"Failed"},# Objects must match the order of request.objects, and have apiVersion set to <request.desiredAPIVersion>.# kind, metadata.uid, metadata.name, and metadata.namespace fields must not be changed by the webhook.# metadata.labels and metadata.annotations fields may be changed by the webhook.# All other changes to metadata fields by the webhook are ignored."convertedObjects":[{"kind":"CronTab","apiVersion":"example.com/v1","metadata":{"creationTimestamp":"2019-09-04T14:03:02Z","name":"local-crontab","namespace":"default","resourceVersion":"143","uid":"3415a7fc-162b-4300-b5da-fd6083580d66"},"host":"localhost","port":"1234"},{"kind":"CronTab","apiVersion":"example.com/v1","metadata":{"creationTimestamp":"2019-09-03T13:02:01Z","name":"remote-crontab","resourceVersion":"12893","uid":"359a83ec-b575-460d-b553-d859cedde8a0"},"host":"example.com","port":"2345"}]}}
{"apiVersion":"apiextensions.k8s.io/v1","kind":"ConversionReview","response":{"uid":"<value from request.uid>","result":{"status":"Failed","message":"hostPort could not be parsed into a separate host and port"}}}
{# Deprecated in v1.16 in favor of apiextensions.k8s.io/v1"apiVersion":"apiextensions.k8s.io/v1beta1","kind":"ConversionReview","response":{"uid":"<value from request.uid>","result":{"status":"Failed","message":"hostPort could not be parsed into a separate host and port"}}}