上海手机网站建设,吉林市网站创意与建设,旅行社网站设计方案,什么是网站改版1 解决#xff08;一#xff09;中的资源删除问题
在Operator开发之kubebuilder实战#xff08;一#xff09;的最后提到了Demo和Pod删除的问题#xff1a;
由于DemoController只监听了Demo资源的变化#xff0c;因此#xff0c;删除Pod时#xff0c;DemoController不…1 解决一中的资源删除问题
在Operator开发之kubebuilder实战一的最后提到了Demo和Pod删除的问题
由于DemoController只监听了Demo资源的变化因此删除Pod时DemoController不会创建Pod同时在删除Demo时也不会删除对应的Pod因为此时已经没有Demo了而且k8s也不知道该Demo管理了哪些Pod
首先DemoController需要监听Pod资源的变化kubebuilder提供了两种监听额外资源的变化的机制一种是简单粗暴的Watchs
func (r *DemoReconciler) SetupWithManager(mgr ctrl.Manager) error {return ctrl.NewControllerManagedBy(mgr).For(batchv1.Demo{}).Watches(corev1.Pod{}, handler.EnqueueRequestForObject{}).Complete(r)
}这种方式就可以直接ListAndWatch Pod资源这种方式的问题是可以接收到所有命名空间的Pod的变化但是在我们的场景中希望只监听Demo负责创建的Pod。
另一种就是Owns
func (r *DemoReconciler) SetupWithManager(mgr ctrl.Manager) error {return ctrl.NewControllerManagedBy(mgr).For(batchv1.Demo{}).Owns(corev1.Pod{}).Complete(r)
}这种方式就只会监听Demo负责创建的Pod不过使用这种方式还需要在创建Pod时增加ownerReferences属性这种方式就跟ReplicaSet类似当ReplicaSet在创建Pod时会将自身的信息写入到Pod的ownerReferences字段当Pod变化时会根据Pod找到关联的ReplicaSet然后向ReplicaSet推送Pod变更。这种方式可以让DemoController接收必要的消息而不需要实现过滤逻辑。
创建Pod时在metadata部分加入ownerReferences pod : corev1.Pod{ObjectMeta: metav1.ObjectMeta{Labels: make(map[string]string),Annotations: make(map[string]string),Name: name,Namespace: req.Namespace,OwnerReferences: []metav1.OwnerReference{{APIVersion: demo.APIVersion,Kind: demo.Kind,Name: demo.Name,UID: demo.UID,Controller: pointer.Bool(true), // 为true表示该资源是控制器},},},Spec: *demo.Spec.Template.Spec.DeepCopy(),}通过这两个改动的结合就可以达到效果
通过监控Pod的变化能够在Pod被删除时去判断当前的Pod数量和需要的Pod数量就可以保证在Pod删除时进行Pod的重建通过给Pod设置ownerReferences属性能够将Pod与Demo关联起来一方面在Pod变更时能够找到关联的Demo并给Demo推送变更另一方面在删除Demo时可以级联删除Pod
需要注意的是
在SetupWithManager里面监听的是Pod但是调谐函数收到的是Pod关联的Demo的变更而不像有些文章写的在这里还需要判断收到的变更是Demo还是Pod删除Demo时会级联删除Pod
关于级联删除当删除一个资源时该如何删除这个资源管理的资源。当使用kubectl delete删除资源时有个级联删除的选项--cascade该选项有三个值
background后台级联删除是默认的删除策略k8s立即删除当前资源然后在后台清理当前资源创建的其他资源也就是ownerReferences是当前资源的资源foreground前台级联删除kubectl会k8s会给Demo加上deletionTimestamp属性和finalizers属性其中finalizers设置为foregroundDeletion给Pod设置deletionTimestamp然后去删除Pod当清理操作完成时再移除finalizers属性并删除Podorphan不进行级联删除直接删除当前资源也就是不管当前资源创建的其他资源跟我们没有用ownerReferences效果一样
这就解释了为什么给Pod加上ownerReferences属性就可以在删除Demo时自动删除Pod。
资源删除过程中还需要提到两个属性BlockOwnerDeletion和Finalizers
BlockOwnerDeletion当在ownerReferences中设置了该选项说明当删除当前资源时需要确保父资源也在删除Finalizers当资源设置了Finalizers时k8s收到删除请求时不会直接删除资源而是会添加资源的deletionTimestamp属性然后返回Accepted之后FinalizersController会监听该资源当该资源的条件满足时就会从Finalizers中删除资源就会被删除
2 开发Webhook
2.1 什么是Webhook
Webhook是一种可以在请求过程中将请求发送给另一个web服务进行处理的机制例如GitLab中的Webhook当向GitLabe仓库提交代码时GitLab会产生一些事件可以让GitLab将这些事件发送给我们的Web程序处理从而可以实现流程的自动化。与GitLabe中的Webhook类似k8s中的Webhook也是可以在apiserver处理请求时将请求发送给其他的web服务处理区别是k8s中的Webhook不仅可以收到请求还能够拦截和拒绝请求。
k8s apiserver在收到请求后需要对请求进行准入控制也就是判断请求是否合法这里面有两种特殊的准入控制可以让开发人员增加自己的准入规则
MutatingAdmissionWebhook变更准入可以对资源进行修改例如当用户没有设置某个字段时可以给该字段设置默认值ValidatingAdmissionWebhook验证准入可以对资源的字段进行验证例如验证某个字段是否在允许的范围内
2.2 基于kubebuilder开发Webhook
在这里我们创建Webhook且带有变更准入和验证准入的功能
变更准入当demo.spec未提供replicas字段时则将demo.spec.replics设置为1验证准入demo.spec.replicas的范围只能在[1,10]之间如果设置的范围不在这个范围则拒绝请求
创建Webhook
// 创建默认和验证的webhook
kubebuilder create webhook --group batch --version v1 --kind Demo --defaulting --programmatic-validation上述命令分别在api/v1和config增加了以下文件
api/v1demo_webhook.go、webhook_suit_test.goconfig/default/manager_webhook_patch.yaml、default/webhookcainjection_patch.yaml、webhook/service.yaml、
代码逻辑位于demo_webhook.go其中Default()里面可以对未提供值的字段设置默认值ValidateCreate()是对创建资源时进行验证ValidateUpdate()是对更新资源时进行验证ValidateDelete()是对删除资源时进行验证。
func (r *Demo) Default() {demolog.Info(default, name, r.Name)// 设置replicas的默认值if r.Spec.Replicas nil {r.Spec.Replicas new(int64)*r.Spec.Replicas 1}
}func (r *Demo) ValidateCreate() (admission.Warnings, error) {demolog.Info(validate create, name, r.Name)// 创建资源时对replicas的范围进行判断if *r.Spec.Replicas 1 || *r.Spec.Replicas 10 {return admission.Warnings{replicas must greater than 1 and less than 11}, errors.New(replicas must greater than 1 and less than 11)}return nil, nil
}3 总结
这里解决了当前资源和子资源的删除问题并说明了级联删除并简单讲解了Webhook的开发。