Kubernetes:验证自定义资源的更新请求

6

我在我的集群中创建了一个自定义资源定义(CRD)及其控制器,现在我可以创建自定义资源,但是如何验证对CR的更新请求?例如,只能更新特定字段。

1个回答

3
Kubernetes文档中的自定义资源部分有一个高级功能和灵活性的章节(不要介意,验证请求应该被认为是相当基本的特性)。对于CRD的验证,它说:
大多数验证可以在CRD中使用OpenAPI v3.0验证进行指定。通过添加验证Webhook支持的任何其他验证。
OpenAPI v3.0验证不能帮助您实现您想要的内容,即确保自定义资源上某些字段的不可变性,它仅适用于无状态验证,其中您正在查看一个对象的一个实例,并确定它是否有效,您无法将其与先前版本的资源进行比较并验证是否有更改。
你可以使用验证 Webhooks。这感觉像是一个重量级的解决方案,因为你需要实现一个符合验证 Webhook 合同的服务器(响应特定类型的请求,并返回特定类型的响应),但你至少会有所需的数据来进行所需的判断,例如知道它是一个更新请求并知道旧对象的样子。更多细节请参见此处。我实际上还没有尝试过验证 Webhooks,但感觉它可能可行。
我使用的另一种方法是将用户提供的数据存储在自定义资源的Status子资源中,第一次创建时,并始终查看那里的数据。虽然可以忽略Spec的任何更改,但您的控制器可以注意到SpecStatus之间的差异,并在Status中嵌入警告,告诉用户他们以无效的方式突变了对象并且正在忽略其指定的值。您可以在此处此处看到该方法的示例。根据该链接存储库的相关自述文件部分,这会导致以下行为:

The AVAILABLE column will show false if the UAA client for the team has not been successfully created. The WARNING column will display a warning if you have mutated the Team spec after initial creation. The DIRECTOR column displays the originally provided value for spec.director and this is the value that this team will continue to use. If you do attempt to mutate the Team resource, you can see your (ignored) user-provided value with the -o wide flag:

$ kubectl get team --all-namespaces -owide
NAMESPACE   NAME   DIRECTOR     AVAILABLE   WARNING   USER-PROVIDED DIRECTOR
test        test   vbox-admin   true                  vbox-admin

If we attempt to mutate the spec.director property, here's what we will see:

$ kubectl get team --all-namespaces -owide
NAMESPACE   NAME   DIRECTOR     AVAILABLE   WARNING                                              USER-PROVIDED DIRECTOR
test        test   vbox-admin   true        API resource has been mutated; all changes ignored   bad-new-director-name

谢谢,但是如何实现“规范的任何更改都被忽略”?我假设当您的验证逻辑被调用时(可能由观察API调用),规范已经被更新。 - Dagang
在我的控制器逻辑中,我忽略了 Spec 中的值。当我的控制器处理请求时,它会检查状态子资源中是否有相关值。如果没有,它就知道这是初始创建,并将不可变值从 Spec 复制到 Status,并持久化自定义资源。从那时起,对于它处理的任何请求,它都会从状态子资源中提取这些值,而不是从 Spec 中提取。Spec 仍然会被更改(唯一防止这种情况的方法是使用验证 Webhook),但我的控制器会忽略这些值。 - Amit Kumar Gupta

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接