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 오브젝트가 변경되면서 업데이트가 거부되고 있는 문제
'사이드 프로젝트' 카테고리의 다른 글
[CI/CD 프로젝트] Ansible을 통한 인프라 관리의 자동화 (0) | 2024.11.20 |
---|---|
[CI/CD 프로젝트] Prometeus + Grafana 를 통한 모니터링 가시성 높이기 (1) | 2024.11.20 |
[CI/CD 프로젝트] ArgoRollout로 canary배포하기 (0) | 2024.11.20 |
[CI/CD 프로젝트] ArgoRollout로 Blue/Green 배포하기 (1) | 2024.11.20 |
[CI/CD 프로젝트] ArgoCD를 통한 CD 구성 (2) | 2024.11.20 |