본문 바로가기
사이드 프로젝트

[CI/CD 프로젝트] Gatekeeper를 통한 K8S 정책 관리

by 간장공장공차장 2024. 11. 20.
반응형

Gatekeeper

Gatekeeper는 Kubernetes 클러스터 내에서 정책을 감사하고 시행할 수 있는 도구이다. Open Policy Agent(OPA)와 Rego 언어를 기반으로 하여, Kubernetes 리소스의 표준화된 생성 및 업데이트를 지원한다. Gatekeeper는 정책을 통해 클러스터의 일관성과 보안을 유지하며, 다양한 팀이 리소스를 관리하는 데 있어 통합된 기준을 제공한다.

Gatekeeper의 필요성

Kubernetes 환경에서 많은 팀이 리소스를 작성할 때, 구성 방식에 차이가 발생할 수 있다. 이러한 차이를 관리하고 일관성을 유지하기 위해 Gatekeeper는 다음과 같은 기능을 제공한다:

  • 정책 집행: Gatekeeper는 클러스터 내에서 정책을 준수하지 않는 리소스의 생성 또는 업데이트를 거부하여 표준을 유지한다.
  • 감사 기능: 리소스의 상태를 검증하여 정책 위반을 사전에 탐지할 수 있는 기능을 제공한다.
  • 변경 기능: 리소스의 상태를 자동으로 조정하여 정책에 맞는 형태로 수정할 수 있다.

구성 요소

Gatekeeper는 다음과 같은 주요 구성 요소로 이루어져 있다.

그림 출처) https://dev.to/ashokan/kubernetes-policy-management-ii-opa-gatekeeper-465g

ConstraintTemplate

ConstraintTemplate은 제약 조건을 정의하는 기본 템플릿으로, 다음과 같은 내용을 포함한다.

  • 제약 조건 정의 시 입력해야 할 파라미터
  • Rego 기반으로 제약 조건의 동작을 상세히 정의하는 로직

Constraint (Custom Resource)

Constraint는 ConstraintTemplate을 기반으로 작성된 커스텀 리소스이다. 템플릿당 여러 개의 Constraint를 생성할 수 있으며, 클러스터 내에서 정책을 적용하는 데 사용된다.

기본 구성

Gatekeeper를 설정하기 위해 다음과 같은 요소가 필요하다:

  • CRD(ConstraintTemplate): Gatekeeper의 기본 구조를 정의한다.
  • RBAC: 접근 제어를 설정하여 필요한 권한을 부여한다.
  • ValidatingWebhookConfiguration: Kubernetes의 Admission Controller와 통합하여 정책 검사를 수행한다.

Gatekeeper는 Kubernetes 클러스터 내에서 정책을 효과적으로 관리하고 집행할 수 있는 강력한 도구로, 이를 통해 클러스터의 일관성을 유지하고 보안을 강화할 수 있으며, 다양한 팀이 협력하여 작업할 때 발생할 수 있는 정책 위반을 예방할 수 있다. Gatekeeper의 구성 요소와 활용 방법을 이해하고 적절히 활용함으로써 Kubernetes 환경의 운영 효율성을 높일 수 있다.

실습

💡gate keeper을 통해서 허용되지 않는 서비스 타입과 허용되지 않는 ns를 제한한다.

네임스페이스 생성 정책

  • 제약 조건: 네임스페이스를 생성할 때 반드시 gatekeeper라는 label을 설정해야 합니다.
  • 제약 조건 정의: ConstraintTemplate과 Constraint을 작성하여 배포합니다.
    • gatekeeper label이 포함되지 않은 네임스페이스 생성 시, 오류가 발생하며 생성되지 않습니다.

Gatekeeper 설치

  • 관리자 권한 부여
kubectl create clusterrolebinding cluster-admin-binding \
  --clusterrole cluster-admin \
  --user ec2-user
helm repo add gatekeeper https://open-policy-agent.github.io/gatekeeper/charts
helm repo update
helm install gatekeeper gatekeeper/gatekeeper --namespace gatekeeper-system --create-namespace

kubectl delete -f https://raw.githubusercontent.com/open-policy-agent/gatekeeper/v3.17.1/deploy/gatekeeper.yaml

설치가 완료되면 gatekeeper-system이라는 네임스페이스가 생성되고 Gatekeeper 관련 리소스들이 배포된다.

  • 설치 확인
kubectl get pods -n gatekeeper-system

정책 생성 및 적용

  • ConstraintTemplate 작성

    • Loadbalancer나 NodePort Type의 서비스 배포 금지 정책
    • apiVersion: templates.gatekeeper.sh/v1beta1 kind: ConstraintTemplate metadata: name: k8sallowedservicetype spec: crd: spec: names: kind: K8sAllowedServiceType targets: - target: admission.k8s.gatekeeper.sh rego: | package k8sallowedservicetype violation[{"msg": msg}] { input.review.object.spec.type != "ClusterIP" msg := "Only ClusterIP services are allowed." }
  • ConstraintTemplate 리소스를 사용하여 정책의 구조와 로직을 정의할 수 있다. 예를 들어, 특정 리소스의 생성을 제한하는 ConstraintTemplate을 만들어본다.

  • Constraint 작성

      apiVersion: constraints.gatekeeper.sh/v1beta1
      kind: K8sAllowedServiceType
      metadata:
        name: allow-only-clusterip
      spec:
        match:
          kinds:
            - apiGroups: [""]
              kinds: ["Service"]
      kubectl apply -f contraint-clusterip-template.yaml
    
      ## 위의 template가 적용되기 까지 시간이 소요되므로 오류가 나면 기다렸다가 다시 배포하기
    
      kubectl apply -f contraint-clusterip.yaml

  • 실제로 ConstraintTemplate에 정의한 정책을 활성화하려면 Constraint 리소스를 작성해야 합니다.

  • 정책 적용 확인

설정한 정책이 적용되는지 확인하기 위해 label이 붙지 않은 Pod와 NodePort 서비스 타입을 생성해 본다. gatekeeper가 허용하는 contraint가 아닌 경우, Gatekeeper가 정책에 의해 해당 리소스의 생성을 차단한다.

정책 및 로그 확인

  • 정책 위반 시 발생하는 로그를 확인하려면 Gatekeeper Pod의 로그를 확인할 수 있습니다.어떤 리소스에서 정책을 위반하고 있는지 constaint를 통해 확인할 수 있다.

kubectl describe K8sBlockNodePort block-node-port
kubectl logs -n gatekeeper-system -l control-plane=gatekeeper-controller-manager
  • Constraint나 ConstraintTemplate의 상태도 Kubernetes 리소스를 통해 확인할 수 있다.
    kubectl get constrainttemplate kubectl get constraints
  • 아래와 같이 허용하지 않는 리소스를 배포하면 웹훅에 의해서 거부된다.

TroubleShooting

{"level":"info","ts":1730954201.1109257,"logger":"watch-manager","msg":"replaying events","registrar":"constrainttemplate-controller-status","gvk":"constraints.gatekeeper.sh/v1beta1, Kind=K8sRequiredLabels"}
{"level":"error","ts":1730954201.2092695,"logger":"controller","msg":"update ct pod status error","kind":"ConstraintTemplate","process":"constraint_template_controller","name":"k8srequiredlabels","crdName":"k8srequiredlabels.constraints.gatekeeper.sh","error":"Operation cannot be fulfilled on constrainttemplatepodstatuses.status.gatekeeper.sh "gatekeeper--controller--manager--8cfdfc7d4--mcp48-k8srequiredlabels": the object has been modified; please apply your changes to the latest version and try again","stacktrace":"github.com/open-policy-agent/gatekeeper/v3/pkg/controller/constrainttemplate.(*ReconcileConstraintTemplate.handleUpdate\n\t/go/src/github.com/open-policy-agent/gatekeeper/pkg/controller/constrainttemplate/constrainttemplate_controller.go:575[ngithub.com/open-policy-agent/gatekeeper/v3/pkg/controller/constrainttemplate.(_ReconcileConstraintTemplate](http://ngithub.com/open-policy-agent/gatekeeper/v3/pkg/controller/constrainttemplate.(_ReconcileConstraintTemplate)).Reconcile\n\t/go/src/github.com/open-policy-agent/gatekeeper/pkg/controller/constrainttemplate/constrainttemplate_controller.go:387[nsigs.k8s.io/controller-runtime/pkg/internal/controller.(_Controller](http://nsigs.k8s.io/controller-runtime/pkg/internal/controller.(_Controller)).Reconcile\n\t/go/src/github.com/open-policy-agent/gatekeeper/vendor/sigs.k8s.io/controller-runtime/pkg/internal/controller/controller.go:114[nsigs.k8s.io/controller-runtime/pkg/internal/controller.(_Controller](http://nsigs.k8s.io/controller-runtime/pkg/internal/controller.(_Controller)).reconcileHandler\n\t/go/src/github.com/open-policy-agent/gatekeeper/vendor/sigs.k8s.io/controller-runtime/pkg/internal/controller/controller.go:311[nsigs.k8s.io/controller-runtime/pkg/internal/controller.(_Controller](http://nsigs.k8s.io/controller-runtime/pkg/internal/controller.(_Controller)).processNextWorkItem\n\t/go/src/github.com/open-policy-agent/gatekeeper/vendor/sigs.k8s.io/controller-runtime/pkg/internal/controller/controller.go:261[nsigs.k8s.io/controller-runtime/pkg/internal/controller.(_Controller](http://nsigs.k8s.io/controller-runtime/pkg/internal/controller.(_Controller)).Start.func2.2\n\t/go/src/github.com/open-policy-agent/gatekeeper/vendor/sigs.k8s.io/controller-runtime/pkg/internal/controller/controller.go:222"}

Gatekeeper가 ConstraintTemplate 상태 업데이트 과정에서 충돌 문제가 발생constrainttemplatepodstatuses 오브젝트가 변경되면서 업데이트가 거부되고 있는 문제

반응형