https://pkg.go.dev/k8s.io/client-go/kubernetes/typed/batch/v1 中的 patch、apply 和 update 有什么区别
我正在使用 Kubernetes client-go 并管理 Job 对象。我遇到过三种更新资源的方法:patch()、apply() 和 update()。
但是,我并不完全清楚它们的差异和最佳用例。
我了解 patch 和 apply 的不同之处在于它们是否执行就地修改。
与这些相比,更新的行为如何? 有人可以解释何时使用补丁、应用或更新吗?最好用实际例子来解释?
此外,在这种情况下使用作业资源时,是否有我应该注意的任何注意事项或最佳实践?
client-go
Update(ctx context.Context, job *batchv1.Job, opts metav1.UpdateOptions)
// ^^^^^^^^^^^^^^^^ entire object
Patch(ctx context.Context, name string, pt types.PatchType,
data []byte, opts metav1.PatchOptions, subresources ...string)
// ^^^^^^^^^^^ arbitrary patch
Apply(ctx context.Context, job *applyconfigurationsbatchv1.JobApplyConfiguration, opts metav1.ApplyOptions)
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// like batchv1.Job but every field is a pointer
这三个中,Update()
最容易使用。 您可以 Get()
一个对象,在控制器代码中修改它,然后
Update()
使用更改后的对象。 如果您的系统中有多个参与者,那么您可能会遇到版本冲突。
retry.RetryOnConflict()
可能会有所帮助,如果这些发生变化,请重复主循环。Apply()
是一项较新的 Kubernetes 功能(需要 Kubernetes 1.22;截至撰写本文时,当前版本为 1.32,所有现代集群都应该支持它),使用起来需要稍微多一些的工作。 在 metav1.ApplyOptions
中,您必须提供 FieldManager
说明您是谁,并且您必须将 JobApplyConfiguration
作为单独的对象填写,而不是改变您拥有的对象。
Patch()
要求您构建差异。
如果您使用
controller-runtime
库(可能通过 Kubebuilder),则其操作会有所不同。 在
client.Writer
接口中, Patch()
方法处理“patch”和“apply”动词。 您需要构造一个 client.Patch
对象,但有一些辅助方法可以做到这一点。 对于服务器端应用,似乎没有管理各个字段的选项。var job batchv1.Job
err := client.Get(ctx, ..., &job)
// Client-side apply: mutate the object, create a diff with the original,
// and Patch()
newJob := job.deepCopy()
modifyJob(newJob)
err = client.Patch(ctx, newJob, client.MergeFrom(job))
// Server-side apply: you don't control the field list
err = client.Patch(ctx, newJob, client.Apply, client.FieldOwner("my-controller"))
在我最近编写的控制器中,我只使用Update()
。 它工作正常,控制器运行时会在错误时重试,但这意味着我确实在日志中看到频繁的难看的冲突错误。 我也许应该更新它以使用 Patch()
机制之一,如果您关心其他控制器不修改您的字段,则服务器端应用,如果这对您来说不重要,则应使用计划补丁。在这种情况下使用职位资源时,我应该注意哪些注意事项或最佳实践?
中被明确标记为不可变,但是如果您创建了一个 Job 并且它创建了它的 Pod,则您无法有效地更改 Pod 模板。由于默认情况下作业仅运行一次,因此您实际上无法修改作业中的大多数字段。 只有几个字段在
API 文档