[Kubernetes] Practical combat of kubebuilder in Operator development (2)

1 Solve the resource deletion problem in (1)

At the end ofOperator Development kubebuilder Practical Combat (1) mentioned the issue of Demo and Pod deletion:

  • Since DemoController only monitors changes in Demo resources, when deleting a Pod, the DemoController will not create a Pod. At the same time, when deleting a Demo, the corresponding Pod will not be deleted because there is no Demo at this time, and k8s does not know it. Which Pods does this demo manage?

First of all, DemoController needs to monitor changes in Pod resources. Kubebuilder provides two mechanisms for monitoring changes in additional resources, one is simple and crudeWatchs:

func (r *DemoReconciler) SetupWithManager(mgr ctrl.Manager) error {
	return ctrl.NewControllerManagedBy(mgr).
		For(&batchv1.Demo{}).
		Watches(&corev1.Pod{}, &handler.EnqueueRequestForObject{}).
		Complete(r)
}

This method can directly access the ListAndWatch Pod resource. The problem with this method is that it can receive所有命名空间的Pod的变化. However, in our scenario, we hope to only listen to the resources that Demo is responsible for creating. Pod.

另一种认为Owns

func (r *DemoReconciler) SetupWithManager(mgr ctrl.Manager) error {
	return ctrl.NewControllerManagedBy(mgr).
		For(&batchv1.Demo{}).
		Owns(&corev1.Pod{}).
		Complete(r)
}

This method will only monitor the Pod that Demo is responsible for creating. However, using this method also requires adding the ownerReferences attribute when creating the Pod. This method is similar to ReplicaSet: when ReplicaSet creates a Pod, it will write its own information. Go to the ownerReferences field of the Pod. When the Pod changes, the associated ReplicaSet will be found based on the Pod, and then the Pod changes will be pushed to the ReplicaSet. This method allows DemoController to receive necessary messages without implementing filtering logic.

Add ownerReferences to the metadata section when creating a Pod:

        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(),
		}

The effect can be achieved by combining these two changes:

  • By monitoring changes in Pods, we can determine the current number of Pods and the required number of Pods when a Pod is deleted, thus ensuring that the Pod is rebuilt when the Pod is deleted.
  • By setting the ownerReferences attribute for the Pod, the Pod can be associated with the Demo. On the one hand, when the Pod is changed, the associated Demo can be found and the changes are pushed to the Demo. On the other hand, when the Demo is deleted, the Pod can be deleted in cascade.

have to be aware of is:

  • InSetupWithManager, the Pod is monitored, but the tuning function receives the changes to the Demo associated with the Pod, unlike some articles where it is necessary to judge the received ones. Change whether it is Demo or Pod
  • When Demo is deleted, Pods will be deleted in cascade

About级联删除: When deleting a resource, how to delete the resources managed by this resource. When using kubectl delete to delete resources, there is a cascade deletion option--cascade, which has three values:

  • background: Background cascade deletion is the default deletion strategy. k8s deletes the current resource immediately, and then cleans up other resources created by the current resource in the background (that is, ownerReferences is the resource of the current resource)
  • foreground: Foreground cascade deletion, kubectl will do it, k8s will add the deletionTimestamp attribute and finalizers attribute to the Demo, where the finalizers are set to foregroundDeletion, set deletionTimestamp to the Pod, and then delete the Pod , when the cleanup operation is completed, remove the finalizers attribute and delete the Pod
  • orphan: Delete the current resource directly without performing cascade deletion, that is, regardless of other resources created by the current resource, the effect is the same as if we did not use ownerReferences

This explains why adding the ownerReferences attribute to the Pod can automatically delete the Pod when the Demo is deleted.

Two attributes need to be mentioned during the resource deletion process: BlockOwnerDeletion and Finalizers:

  • BlockOwnerDeletion: When this option is set in ownerReferences, it means that when deleting the current resource, you need to ensure that the parent resource is also deleted.
  • Finalizers: When Finalizers are set for a resource, when k8s receives a deletion request, it will not delete the resource directly. Instead, it will add the deletionTimestamp attribute of the resource and then return Accepted. Afterwards, the FinalizersController will monitor the resource. When the conditions of the resource are met, will be deleted from Finalizers and the resource will be deleted

2 Develop Webhook

2.1 What is a webhook?

Webhook is a mechanism that can send the request to another web service for processing during the request process. For example, Webhook in GitLab. When submitting code to the GitLab repository, GitLab will generate some events, which can be sent by GitLab. Let our web program handle it so that the process can be automated. Similar to the Webhook in GitLabe, the Webhook in k8s can also send the request to other web services for processing when the apiserver processes the request. The difference is that the Webhook in k8s can not only receive the request, but also intercept and reject the request.

After k8s apiserver receives a request, it needs to perform access control on the request, that is, to determine whether the request is legal. There are two special access controls that allow developers to add their own access rules:

  • MutatingAdmissionWebhook: Changing access, you can modify resources. For example, when the user does not set a certain field, you can set a default value for the field.
  • ValidatingAdmissionWebhook: Verify access, you can verify the fields of resources, for example, verify whether a field is within the allowed range
2.2 Develop Webhook based on kubebuilder

Here we create a Webhook with the functions of changing access and verifying access:

  • Change access: When demo.spec does not provide the replicas field, demo.spec.replics is set to 1
  • Verify access: The range of demo.spec.replicas can only be between [1,10]. If the set range is not within this range, the request will be rejected.

Create webhook:

// 创建默认和验证的webhook
kubebuilder create webhook --group batch --version v1 --kind Demo --defaulting --programmatic-validation

The above commands add the following files to api/v1 and config respectively:

  • api/v1:demo_webhook.go、webhook_suit_test.go
  • config/:default/manager_webhook_patch.yaml、default/webhookcainjection_patch.yaml、webhook/service.yaml、

The code logic is located in demo_webhook.go, where Default() can set default values ​​for fields that do not provide values. ValidateCreate() is used to verify when creating resources, ValidateUpdate() is used to verify when updating resources, and ValidateDelete() is used to verify resources. Validate when deleting resources.

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 Summary

Here the problem of deletion of current resources and sub-resources is solved, cascade deletion is explained, and the development of Webhook is briefly explained.

Guess you like

Origin blog.csdn.net/ILOVEYOUXIAOWANGZI/article/details/134105243