本页介绍了如何添加版本信息到CustomResourceDefinitions,如何表示 CustomResourceDefinitions 的稳定水平或者用 API 之间的表征的转换提高您的 API 到一个新的版本。它还描述了如何将对象从一个版本升级到另一个版本。
你必须拥有一个 Kubernetes 的集群,同时你的 Kubernetes 集群必须带有 kubectl 命令行工具。 如果你还没有集群,你可以通过 Minikube 构建一 个你自己的集群,或者你可以使用下面任意一个 Kubernetes 工具构建:
为了检查版本, 输入 kubectl version
.
CustomResourceDefinition API 支持您使用versions
字段来开发多个版本的自定义资源。
版本可以有不同的模式与转换 webhook 在版本之间转换自定义资源。
Webhook 转换应遵循适用的Kubernetes API 约定。
具体来说,请参阅 API 更改文档以获取一组有用的问题和建议。
Note: 早期的迭代包括version
字段而不是versions
。version
字段已弃用且可选,但如果它不为空,则必须必配versions
字段中的第一项。
此示例显示了两个版本的 CustomResourceDefinition。第一个例子,假设所有的版本共享相同的模式而它们之间没有转换。YAML 中的评论提供了更多背景信息。
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
# name must match the spec fields below, and be in the form: <plural>.<group>
name: crontabs.example.com
spec:
# group name to use for REST API: /apis/<group>/<version>
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
# 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 value
strategy: None
# either Namespaced or Cluster
scope: Namespaced
names:
# 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 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
你可以将 CustomResourceDefinition 存储在 YAML 文件中,然后使用kubectl apply
来创建它。
kubectl apply -f my-versioned-crontab.yaml
在创建之后,API 服务器开始在 HTTP REST 端点上为每个启用的版本提供服务。在上面的示例中,API 版本可以在/apis/example.com/v1beta1
和 /apis/example.com/v1
中获得。
不考虑 CustomResourceDefinition 中版本被定义的顺序,kubectl 使用具有最高优先级的版本作为访问对象的默认版本。 通过解析_name_字段确定优先级来决定版本号,稳定性(GA, Beta, 或者 Alpha),以及该稳定性水平内的序列。
用于对版本进行排序的算法被设计成与 Kubernetes 项目对 Kubernetes 版本进行排序的方式相同。
版本以v
开头跟一个数字,一个可选的beta
或者 alpha
命名,和一个可选的附加的数字型的版本信息。
从广义上讲,版本字符串可能看起来像v2
或者v2beta1
。
使用以下算法对版本进行排序:
beta
或 alpha
跟随第一数字部分,它们按顺序排序,在没有beta
或 alpha
后缀(假定为 GA 版本)的等效字符串后面。beta
或alpha
之后,那么这些数字也是从最大到最小排序。foo1
在 foo10
上方排序。这与遵循 Kubernetes 版本模式的条目的数字部分排序不同。如果查看以下排序版本列表可以明白:
- v10
- v2
- v1
- v11beta2
- v10beta3
- v3beta1
- v12alpha1
- v11alpha2
- foo1
- foo10
对于 指定多个版本中的示例,版本排序顺序为v1
,后跟着v1beta1
。
这导致了 kubectl 命令使用v1
作为默认版本,除非提供对象指定版本。
Note: Webhook 转换在 Kubernetes 1.13中作为 alpha 功能引入。要使用它,应启用CustomResourceWebhookConversion
功能。 请参阅 feature gate 文档以获得更多信息。
上面的例子在版本之间有一个 None 转换,它只在转换时设置apiVersion
字段而不改变对象的其余部分。API 服务器还支持在需要转换时调用外部服务的 webhook 转换。例如:
为了涵盖所有这些情况并通过 API 服务器优化转换,转换对象可能包含多个对象,以便最大限度地减少外部调用。webhook 应该独立执行这些转换。
请参考自定义资源转换 webhook
服务器的实施,这在Kubernetes e2e测试中得到验证。
webhook 处理由 API 服务器发送的ConversionReview
请求,并发送回包含在ConversionResponse
中的转换结果。
请注意,请求包含需要独立转换不改变对象顺序的自定义资源列表。
示例服务器的组织方式使其可以重用于其他转换。
大多数常见代码都位于框架文件中,只留下一个功能用于实施不同的转换。
Note: 示例转换 webhook 服务器留下ClientAuth
字段empty,默认为NoClientCert
。 这意味着 webhook 服务器没有验证客户端的身份,据称是 API 服务器。 如果您需要相互 TLS 或者其他方式来验证客户端,请参阅如何验证 API 服务器。
用于部署转换 webhook 的文档与准入 webhook 示例服务。
下一节的假设是转换 webhook 服务器部署到default
命名空间中名为example-conversion-webhook-server
的服务器上,并在路径/crdconvert
上提供流量。
Note: 当 webhook 服务器作为一个部署到 Kubernetes 集群中的服务器时,它必须通过端口443上的服务器公开(服务器本身可以有一个任意端口,但是服务器对象应该将它映射到端口443)。 如果为服务器使用不同的端口,则 API 服务器和 webhook 服务器之间的通信可能会失败。
通过修改spec
中的conversion
部分,可以扩展None
转换示例来使用转换 webhook。
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
# name must match the spec fields below, and be in the form: <plural>.<group>
name: crontabs.example.com
spec:
# group name to use for REST API: /apis/<group>/<version>
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
# Each version can define it's own schema when there is no top-level
# schema is defined.
schema:
openAPIV3Schema:
properties:
hostPort:
type: string
- name: v1
served: true
storage: false
schema:
openAPIV3Schema:
properties:
host:
type: string
port:
type: string
conversion:
# 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 configure the webhook endpoint to be
# called by API server.
webhookClientConfig:
service:
namespace: default
name: example-conversion-webhook-server
# path is the url the API server will call. It should match what the webhook is serving at. The default is '/'.
path: /crdconvert
caBundle: <pem encoded ca cert that signs the server cert used by the webhook>
# either Namespaced or Cluster
scope: Namespaced
names:
# 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 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: 当使用clientConfig.service
时,服务器证书必须对<svc_name>.<svc_namespace>.svc
有效。
您可以将 CustomResourceDefinition 保存在 YAML 文件中,然后使用kubectl apply
来应用它。
kubectl apply -f my-versioned-crontab-with-conversion.yaml
在应用新更改之前,请确保转换服务器已启动并正在运行。
写入对象时,它将保留在写入时指定为存储版本的版本中。 如果存储版本发生变化,现有对象永远不会自动转换。 然而,新创建或更新的对象将在新的存储版本中编写。 对象可能已在不再被服务的版本中编写。
当读取对象时,将版本指定为路径的一部分。
如果指定的版本与对象的持久版本不同, Kubernetes 会在您请求的版本里将对象返还给您,但是在提供请求时,持久化对象既不会在磁盘上更改,也不会以任何方式进行转换(除了更改apiVersion
字符串)。
您可以在当前提供的任何版本中请求对象。
如果您更新了一个现有对象,它将在现在的存储版本中被重写。 这是对象可以从一个版本改到另一个版本的唯一办法。
为了说明这一点,请考虑以下假设的一系列事件:
v1beta1
。
它保存在版本v1beta1
的存储中。v1
添加到 CustomResourceDefinition 中,并将其指定为存储版本。v1beta1
中读取您的对象,然后您再次在版本v1
中读取对象。
除了 apiVersion 字段之外,两个返回的对象都是相同的。v1
的存储中。
您现在有两个对象,其中一个位于v1beta1
,另一个位于v1
。v1
中,因为那是当前的存储版本。API 服务器在状态字段storedVersions
中记录曾被标记为存储版本的每个版本。
对象可能已被保留在任何曾被指定为存储版本的版本中。
从未成为存储版本的版本的存储中不能存在任何对象。
弃用版本并删除支持时,请设计存储升级过程。
以下是从v1beta1
升级到v1
的示例过程。
v1
设置为 CustomResourceDefinition 文件中的存储,并使用 kubectl 应用它。
storedVersions
现在是v1beta1、 v1
。v1
。storedVersions
字段中删除v1beta1
来更新 CustomResourceDefinitionStatus
。此页是否对您有帮助?
Thanks for the feedback. If you have a specific, answerable question about how to use Kubernetes, ask it on Stack Overflow. Open an issue in the GitHub repo if you want to report a problem or suggest an improvement.