kubebuilder如何Watch由Pod产生的Event的创建,触发控制器Reconcile方法的执行

原创 吴就业 165 0 2024-04-18

本文为博主原创文章,未经博主允许不得转载。

本文链接:https://wujiuye.com/article/380b2e457ca841f983971cb75f43fceb

作者:吴就业
链接:https://wujiuye.com/article/380b2e457ca841f983971cb75f43fceb
来源:吴就业的网络日记
本文为博主原创文章,未经博主允许不得转载。

自定义资源的Controller创建出来的子资源,子资源创建的子资源(子子资源),如何Watch子子资源的事件?我们以MyDeployment->创建Pod->创建Event,想要watch Pod创建的Event的Create事件为例。

自定义的MyDeployment资源可以通过Controller Manager的Builder的Owns方法订阅Pod的增删改事件,因为Pod是我们创建出来的,并且指定了Pod的ownerReference为自定义资源MyDeployment的对象。

假如现在我们想要订阅由Pod产生的Event的创建呢?

由于Pod产生的Event其ownerReference也不是自定义资源MyDeployment的对象,所以无法通过Owns方法订阅。(其实Event资源也没有ownerReference,只有involvedObject,不过其它类型资源有,只是以此举例。虽然Event资源没有ownerReference,但此案例确实也生效。)

好在kubebuilder提供了Owns的底层实现,即Watches方法。使用Watches方法同样可以达到调用Owns方法的效果。只是使用Owns方法我们无法指定ownerReference,而Watches方法可以。

因此,我们可以使用Watches方法来订阅由Pod产生的Event事件,案例代码如下:

func (r *MyDeploymentReconciler) SetupWithManager(mgr ctrl.Manager) error {
	return ctrl.NewControllerManagedBy(mgr).
		For(&v1beta1.MyDeployment{}).
                Watches(&source.Kind{Type: &v1.Event{}}, // watch Event资源
			&handler.EnqueueRequestForOwner{
				IsController: false,
				OwnerType:    &v1.Pod{},
			}, // 入controller事件队列的过滤条件, Event的Owner(involvedObject)类型是Pod,然后IsController是false
			builder.WithPredicates(predicate.Funcs{
				CreateFunc: func(createEvent event.CreateEvent) bool {
					obj := createEvent.Object
					eventObj, ok := obj.(*v1.Event)
					if !ok {
						return false
					}
					if eventObj.InvolvedObject.Kind != "Pod" {
						return false
					}
                                        // 其它自定义的过滤条件
				},
			})).
            Complete(r)
}
#云原生

声明:公众号、CSDN、掘金的曾用名:“Java艺术”,因此您可能看到一些早期的文章的图片有“Java艺术”的水印。

文章推荐

如何自己部署autoscaler实现节点的自动扩缩容(二):支持自定义调度器触发的扩容

想要让autoscaler支持自定义调度器触发节点扩展,有两种方案。一是autoscaler支持自定义调度器的过滤器插件,二是autoscaler取消check逻辑。

如何自己部署autoscaler实现节点的自动扩缩容(一):本地debug运行autoscaler

在google cloud上使用gke集群,gke已经集成autoscaler,通过在控制台创建节点池点击开启自动扩缩容就可以,那么为什么还要自己部署呢?怎么本地让autoscaler成功跑起来呢?

Helm chart在values文件中声明为字符串的变量,部署替换占位符后却变成了数字类型

helm在获取values.yaml文件中配置的值时,由于没有对应一个结构体来反序列化yaml,只能使用map来接收,例如map[string]interface{}。可能是将interface{}尝试转成数字,能够转换成功helm就误以为我们需要的是数字了。

Kubebuilder控制器配置Owns然而监听到事件却不触发Reconcile方法

我们在CreateFunc、DeleteFunc、UpdateFunc方法中添加日记,发现这些方法被调用了,但却没有触发控制器的Reconcile方法执行。

满足Autoscaler触发自定扩容Node的条件是什么?

我们使用自定义的调度器来调度pod,有自定义的Filter插件。Autoscaler在执行扩容之前,会调用Filter插件,尝试是不是真的没有node满足调度这个pod再去扩容。而默认情况下,Autoscaler拿的是默认的Filter插件,拿不到我们自定义的Filter插件,所以没有走我们的Filter逻辑,所以不会扩容。

如何实现一个简单的K8s apiserver

apiserver是k8s的另一种扩展机制,相比CRD,它更为灵活。本篇以实战为主,介绍如何实现一个简单的apiserver。