问题描述
我正在使用operator-sdk实施操作符。
我对运营商SDK(Patch
)中的client.Client
API有一些疑问。
有两个补丁API,分别是Client.Patch
和Client.Status().Patch
。
据我所知,第一个(Client.Patch
)将充当补丁字段,但资源中的Status
除外。另一个(Client.Status().Patch
)将修补资源中的Status
字段。
在这一点上,我可以在一个协调函数中多次使用Patch
(无论是Client.Status().Patch
还是Client.Patch
)API吗?
我认为Patch
API会更改资源版本,因此当我在一个协调函数中多次调用Patch
API时,API无法正常工作,但是API(Patch
)却可以正常工作(我我观察到,实际上在一个协调函数中调用了2次。
如果我误解了一些知识,请给我建议。
谢谢。
解决方法
我找到了标题为7 Best Practices for Writing Kubernetes Operators: An SRE Perspective
的博客文章第4点是:
4:一次修改一个自定义资源
每次控制器监视自定义资源时,协调循环将再次运行。这包括用户所做的更改,还包括您在协调功能或其子例程中所做的更改。通常,您需要更新正在使用的自定义资源以添加信息。 GCP项目操作员提供的一个示例是它在GCP中创建的项目的ID。此更新将导致协调循环获取自定义资源的更新版本,并开始另一次运行协调。
您需要意识到这一点,因为更改自定义资源并继续进行处理可能会导致新创建的请求出现争用情况。如果启用了并行处理,它将立即开始运行协调功能。在这种情况下,您必须考虑到代码的每一行中可能同时有第二个请求同时处理该资源。即使不并行处理请求,当反复更新CustomResource时,协调请求也会堆积起来,从而使操作员不必要地忙碌。
为降低竞争状况的风险并避免堆积请求,请确保您不要在单次“协调”中对自定义资源或相关操作进行多次更改。每当您更新正在观看的自定义资源时,只需退出协调循环,然后继续进行下一次运行即可。您之前执行的所有幂等函数将无济于事,您可以从上次中断的地方继续。
因此,如果我理解正确,您可以在一次运行的协调功能中进行几处更改,但通常认为这是不好的做法。