Kubernetes v1.21에서 가져온 보안 Server Side Apply

16599 단어 GoKubernetestech
2021/07/16 보충: Server Side Apply를 작성할 때 Client에서 허용되는 차이점을 감지하여 불필요한 요구 사항이 발생하지 않도록 하는 방법입니다.여기 기사.도 보세요.
저번 보도에서는 Reconceile 처리에서 쓸모없는 업데이트 처리가 발생하지 않는 여러 가지 실시 방법을 소개했다.
여기서 Server Side Apply 방식에서는 필요없는 필드를 업데이트해야 하므로 쓰기 및 삭제 프로세스가 필요합니다.
머지않아 발표될 Kubernetes1.21에서 Server Side Apply가 이 문제를 해결하는 기능을 가져왔습니다.
  • Apply for client-go's typed clients
  • 이 새 기능은 자원별로 애플과 애플 스테이츠 등의 방법을 추가했다.
    예를 들어 Deployment용 애플 방법는 다음과 같은 정의이다.
    func (c *deployments) Apply(ctx context.Context, deployment *appsv1.DeploymentApplyConfiguration, opts metav1.ApplyOptions) (result *v1.Deployment, err error)
    
    에서 특징이 있는 것은 매개 변수k8s.io/api/apps/v1Deployment가 아니라 이용k8s.io/client-go/applyconfigurations/apps/v1DeploymentApplyConfiguration이다.
    이 구조체의 정의를 보면 모든 필드는 바늘이고omitempty 라벨이 붙어 있습니다.
    type DeploymentSpecApplyConfiguration struct {
    	Replicas                *int32                                    `json:"replicas,omitempty"`
    	Selector                *v1.LabelSelectorApplyConfiguration       `json:"selector,omitempty"`
    	Template                *corev1.PodTemplateSpecApplyConfiguration `json:"template,omitempty"`
    	Strategy                *DeploymentStrategyApplyConfiguration     `json:"strategy,omitempty"`
    	MinReadySeconds         *int32                                    `json:"minReadySeconds,omitempty"`
    	RevisionHistoryLimit    *int32                                    `json:"revisionHistoryLimit,omitempty"`
    	Paused                  *bool                                     `json:"paused,omitempty"`
    	ProgressDeadlineSeconds *int32                                    `json:"progressDeadlineSeconds,omitempty"`
    }
    
    이 특징으로 인해 고객측이 지정하지 않은 필드는nil이기 때문에 애플은 필요하지 않은 필드를 업데이트하지 않습니다.
    그럼저번 보도에 소개된 Reconcile 처리는 Apply Configuuration으로 다시 작성해 보세요.
    코드는 여기. 위에 놓으세요.
    func (r *MyAppReconciler) reconcileDeploymentByTypesafeSSA(ctx context.Context, myapp *samplev1.MyApp) error {
    	dep := appsv1apply.Deployment(myapp.Name+"-nginx", myapp.Namespace).
    		WithLabels(map[string]string{"component": "nginx"}).
    		WithSpec(appsv1apply.DeploymentSpec().
    			WithReplicas(1).
    			WithSelector(metav1apply.LabelSelector().WithMatchLabels(map[string]string{"component": "nginx"})))
    
    	var podTemplate *corev1apply.PodTemplateSpecApplyConfiguration
    	if myapp.Spec.PodTemplate != nil {
    		podTemplate = myapp.Spec.PodTemplate.Template
    	} else {
    		podTemplate = corev1apply.PodTemplateSpec()
    	}
    	podTemplate.WithLabels(map[string]string{"component": "nginx"})
    
    	if podTemplate.Spec == nil {
    		podTemplate.WithSpec(corev1apply.PodSpec())
    	}
    	hasNginxContainer := false
    	for _, c := range podTemplate.Spec.Containers {
    		if *c.Name == "nginx" {
    			hasNginxContainer = true
    		}
    	}
    	if !hasNginxContainer {
    		podTemplate.Spec.WithContainers(
    			corev1apply.Container().WithName("nginx").WithImage("nginx:latest"))
    	}
    	dep.Spec.WithTemplate(podTemplate)
    
    	err := setControllerReference(myapp, dep, r.Scheme)
    	if err != nil {
    		return err
    	}
    
    	obj, err := runtime.DefaultUnstructuredConverter.ToUnstructured(dep)
    	if err != nil {
    		return err
    	}
    	patch := &unstructured.Unstructured{
    		Object: obj,
    	}
    
    	return r.Patch(ctx, patch, client.Apply, &client.PatchOptions{
    		FieldManager: "myapp-operator",
    		Force: pointer.Bool(true),
    	})
    }
    
    다른 방식에 비해 시원한 느낌이 든다.
    그러나 주의해야 할 것은 매번kube-appiserver에 요구를 해야 한다는 것이다.
    CRD의 정의도 이전의 struct가 아닌 ApplyConfiguration을 사용합니다.
     import (
    -       corev1 "k8s.io/api/core/v1"
    +       corev1apply "k8s.io/client-go/applyconfigurations/core/v1"
     )
    
     type MyAppSpec struct {
    -       PodTemplate *corev1.PodTemplate `json:"podTemplate"`
    +       PodTemplate *corev1apply.PodTemplateApplyConfiguration `json:"podTemplate"`
     }
    
    또한, Kubbernetes1.21은 발매 전이기 때문에 현재의 controller runtime(v0.8.3)는 이 새로운 방식에 정식으로 대응하지 않습니다.
    이번 코드는 강제 이동을 위해 자동으로 생성된 DeepCopy 함수를 덮어썼습니다.
    발매 기대하세요.

    좋은 웹페이지 즐겨찾기