我使用 informer 监听 k8s 资源,当用户更新 k8s 资源时,我发现有更新操作就去更新一遍资源以达到覆盖用户更新的目的,但是这样会使更新请求一次又一次进入队列,成了一个循环,如何解决呢?
1
lozzow 2023-06-21 15:29:44 +08:00
我不会,但是是不是可以加一个标签下次监听到直接放行
|
2
KaynW 2023-06-21 15:44:16 +08:00
要有出队条件, 比如发现已经有了你期望的 label 就把这个事件从队列里丢出去而不是再次更新
|
3
bigpigB 2023-06-21 16:36:08 +08:00
您可以通过在更新资源之前进行一些判断和比较来避免循环更新的问题。以下是几种可能的解决方法:
使用资源版本( Resource Version )或修改时间戳:在监听到资源更新时,获取当前资源的版本或修改时间戳,并与上次处理的版本或时间戳进行比较。只有当它们不相等时,才执行更新操作。这样可以确保只有真正发生变化的资源才会被更新。 使用标记字段( Annotation )或标签( Label ):为每个资源添加一个特定的标记字段或标签,在触发更新操作时检查该字段或标签是否已设置。如果已设置,则跳过更新;否则,进行更新并设置标记字段或标签。 使用状态字段:为每个资源添加一个表示状态的字段,例如“已更新”。当接收到资源更新事件时,先检查该字段的值,如果已经标记为“已更新”,则跳过更新操作;否则,进行更新并将字段值更新为“已更新”。 延迟更新或批量更新:在监听到资源更新后,不立即执行更新操作,而是延迟一段时间或等待一定数量的更新事件积累后进行批量更新。这样可以避免频繁的单个更新请求。 根据您的具体需求和代码实现,选择适合的方法来避免循环更新问题。 |
4
bigpigB 2023-06-21 16:36:33 +08:00
以下是一个使用资源版本( Resource Version )进行判断的示例代码片段,以避免循环更新问题:
go import ( "fmt" "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/client-go/kubernetes" "k8s.io/client-go/tools/cache" ) // 在 Informer 的事件处理函数中调用此方法进行更新操作 func updateResource(clientSet *kubernetes.Clientset, obj interface{}) { resource, ok := obj.(cache.Resource) if !ok { fmt.Println("Invalid resource object") return } // 获取当前资源的版本 currentVersion := resource.GetObjectMeta().GetResourceVersion() // TODO: 根据自己的需求,获取上次处理的版本或时间戳 lastVersion := "some_last_version" // 比较当前版本与上次处理的版本 if currentVersion != lastVersion { // 执行更新操作 // 更新完后,更新上次处理的版本为当前版本 lastVersion = currentVersion // TODO: 在这里执行你的更新逻辑 } } |
5
idblife 2023-06-21 16:51:33 +08:00 via iPhone
argocd 了解一下
|
6
Frankcox 2023-06-21 16:53:05 +08:00
client-go 的 Update 方法会返回更新后的信息,获取到 ResourceVersion ,比较下 ResourceVersion 来看该更新操作是否已处理。
另外,不清楚你覆盖更新的具体操作,不过这个情景下可以考虑写个 Admission Control 。利用 Mutate 处理资源的 Update 的操作。 |
7
Tinet 2023-06-21 17:00:09 +08:00
当用户更新 k8s 资源时,我发现有更新操作就去更新一遍资源以达到覆盖用户更新的目的。
这个不就是 Admission Control 做的事吗,感觉你技术选型错了 |
8
birdhk OP 谢谢各位。我是在写一个同步功能,用户在 host 集群创建了资源,我就把资源同步创建到 member 集群,但是不允许用户在 member 集群修改和删除。所以用户要修改只能修改 host 集群上的资源,然后我去 member 集群修改。所以用户修改的时候我会用 host 集群的资源覆盖掉用户的更新。
|
9
feedcode 2023-06-21 19:13:51 +08:00
正如 7 楼所说,你应该用 MutatingWebhookConfiguration , 更新的时候返回 patch 后的 object
|
10
feedcode 2023-06-21 19:18:16 +08:00
如果你自己实现 go 代码困难,可以看下 kyverno 或者 Open Policy Agent , 然后写 patch 逻辑
|