[AEKS2] 6주차 - EKS Security: Kyverno
Kyverno는 CNCF 프로젝트로, K8S의 Policy를 동적으로 관리할 수 있는 Policy-as-Code이다.
Dynamic Admission Control로 실행되며, Mutating/Validating admission 에서 동작하여 허용/거부 결과를 반환한다.
Admission Controller는 쿠버네티스에서 인증/인가 단계를 거치고 나서 실행되는 컨트롤러인데 API로의 요청을 가로채서 변경 또는 허용/거부를 할 수 있다.
그래서 Kyverno 정책을 사용하여 validate(검증), mutate(변경), generate(생성), verify images(이미지 검증)을 하면 보안 표준을 시행할 수 있다.
또한, Kyverno 정책은 리소스의 kind, name, label selectors 등을 match시켜 사용한다.
Match와 Exclude는 정책을 적용할 대상이며,
Kyverno가 적용할 수 있는 정책은 Validate, Mutate, Generate, Verify Images가 있다.
실습으로 동작을 확인해 볼 것이다.
Kyverno 설치
-
resourceFiltersExcludeNamespaces
로 정책에서 제외할 네임스페이스를 지정할 수 있다.cat << EOF > kyverno-value.yaml config: resourceFiltersExcludeNamespaces: [ kube-system ] EOF
-
네임스페이스를 생성하고 헬름으로 배포한다.
kubectl create ns kyverno helm repo add kyverno https://kyverno.github.io/kyverno/ helm install kyverno kyverno/kyverno --version 3.2.0-rc.3 -f kyverno-value.yaml -n kyverno
-
설치 확인
Policy1 ) Validate
-
ClusterPolicy를 생성한다
validationFailureAction
은 Enforce로 지정하고 대상은 POD이다.validate
부분에서 labels에서 key 값에 team이 있어야 POD 생성이 가능하다.kubectl create -f- << EOF apiVersion: kyverno.io/v1 kind: ClusterPolicy metadata: name: require-labels spec: validationFailureAction: Enforce rules: - name: check-team match: any: - resources: kinds: - Pod validate: message: "label 'team' is required" pattern: metadata: labels: team: "?*" EOF
-
ClusterPolicy 생성 확인
-
레이블 지정 없이 POD 생성 시도
-
레이블 key에 team이 있으니까 생성됨
-
policyreport 확인해 보면?
results
에pass
확인!
Policy2 ) Mutate
-
ClusterPolicy를 생성한다
이번엔
mutate
에 +(team)으로 labels의 key 값에 team이 없으면 team=bravo를 생성하고 key 값에 team이 있으면 생성하지 않는다.마찬가지로 대상은 POD이다.
kubectl create -f- << EOF apiVersion: kyverno.io/v1 kind: ClusterPolicy metadata: name: add-labels spec: rules: - name: add-team match: any: - resources: kinds: - Pod mutate: patchStrategicMerge: metadata: labels: +(team): bravo EOF
-
ClusterPolicy 생성 확인
-
label에 key 값이 team인지 아닌지에 따라 mutate 동작 유무가 달라졌다!
Policy3 ) Generate
-
테스트 secret을 하나 생성했다.
kubectl -n default create secret docker-registry **regcred** \ --docker-server=myinternalreg.corp.com \ --docker-username=john.doe \ --docker-password=Passw0rd123! \ --docker-email=john.doe@corp.com
-
ClusterPolicy를 생성한다
모든 네임스페이스를 대상으로 하며,
generate
를 통해 default 네임스페이스의 regcred라는 secret을 복제해서 생성한다.kubectl create -f- << EOF apiVersion: kyverno.io/v1 kind: ClusterPolicy metadata: name: sync-secrets spec: rules: - name: sync-image-pull-secret match: any: - resources: kinds: - Namespace generate: apiVersion: v1 kind: Secret name: regcred namespace: "" synchronize: true clone: namespace: default name: regcred EOF
-
새로운 네임스페이스를 만들자 마자 동일한 secret이 바로 생성되었다.
-
default와 mytestns 둘다 같은 이름의 secret이 있다!
-
기존 네임스페이스에는 영향을 주지 않고 신규 네임스페이스를 생성할 때만 영향을 주는가해서 테스트해 보았다
ClusterPolicy를 생성하기 전에 만든 testns1과 2에는 영향받지 않고 testns3에만 secret이 생성된 걸 알 수 있었다.
Kyverno를 실습하면서..
재밌었다!
Admission Control을 맞닥뜨렸을 때가 어려웠지,
막상 Kyverno를 알고 실습하니 이해하기가 수월했다.
동작 방식도 이해가 되고 활용법도 어렵지 않아서 꼭 실습해 보기를 추천한다!
특히 나는 generate가 맘에 들었다.
대상의 리소스가 생성될 때마다 규칙대로 무언가 실행된다는 것은 운영의 편리성이 증가할 것 같기 때문이다.
Leave a comment