[AWS EKS] EKS Security 7 - Kyverno

주영·2025년 3월 15일
0

AWS EKS Workshop Study 3기

목록 보기
24/31

이 글은 CloudNet@팀의 AWS EKS Workshop Study(AEWS) 3기 스터디 내용을 바탕으로 작성되었습니다.
AEWS는 CloudNet@의 '가시다'님께서 진행하는 스터디로, EKS를 학습하는 과정입니다.
EKS를 깊이 있게 이해할 기회를 주시고, 소중한 지식을 나눠주시는 가시다님께 다시 한번 감사드립니다.
이 글이 EKS를 학습하는 분들께 도움이 되길 바랍니다.

1. Kyverno란?

Kyverno는 Cloud Native Computing Foundation (CNCF)에서 관리하는 Kubernetes 네이티브 정책 엔진입니다.
이름인 "Kyverno"는 그리스어로 “Govern” (통제/관리하다) 라는 뜻을 가지고 있습니다.

특징

  • Kubernetes의 리소스를 YAML로 선언적으로 정의할 수 있습니다.
  • 새로운 정책 언어를 배울 필요 없이 기존 Kubernetes 리소스 형식으로 정책을 관리할 수 있습니다.
  • Validation(검증), Mutation(수정), Generation(생성) 기능을 제공하여 다양한 정책을 정의할 수 있습니다.
  • 소프트웨어 공급망 보안을 위한 컨테이너 이미지 서명 검증을 지원합니다.
  • 리소스의 Kind, Name, Label 등의 속성을 기준으로 정책을 적용할 수 있습니다.

사용 사례

  • 보안 정책 적용: Pod Security Standards(PSS) 구현
  • 리소스 제한: 특정 네임스페이스에 대한 CPU/메모리 제한 적용
  • 소프트웨어 공급망 보안: 이미지 서명 검증 및 취약점 스캔
  • RBAC 관리: Kubernetes RBAC(Role-Based Access Control) 설정 강화
  • CI/CD 파이프라인 검증: 정책 위반 여부를 사전 점검

2. Kyverno의 주요 기능

Kyverno는 Kubernetes의 동적 어드미션 컨트롤러(Dynamic Admission Controller) 로 동작하며, Mutating, Validating, Generating Admission Control Webhook을 활용하여 정책을 적용합니다.

정책 정의 기능

  1. Validation (검증): 리소스가 특정 조건을 충족하는지 확인하고 위반 시 차단 또는 경고
  2. Mutation (수정): 리소스를 자동으로 수정하여 일관된 설정 유지
  3. Generation (생성): 필요한 리소스를 자동으로 생성하여 클러스터의 일관성 유지
  4. Cleanup (삭제): 오래된 리소스를 자동으로 정리
  5. Verify Images (이미지 검증): 컨테이너 이미지 서명을 확인하여 무결성 유지

정책 적용 방식

  • Admission Control Webhook을 통해 요청이 클러스터에 반영되기 전 검사(Validation/Mutation)
  • Background Controller를 통해 기존 리소스에도 정책을 적용
  • Report Controller를 통해 정책 위반 사항을 감지하고 보고서 생성

https://kyverno.io/docs/introduction/

https://kyverno.io/docs/installation/

3. Kyverno 설치

Kyverno는 Helm Chart를 이용하여 쉽게 설치할 수 있습니다.

# 설치
# EKS 설치 시 참고 https://kyverno.io/docs/installation/platform-notes/#notes-for-eks-users
# 모니터링 참고 https://kyverno.io/docs/monitoring/
cat << EOF > kyverno-value.yaml
config:
  resourceFiltersExcludeNamespaces: [ kube-system ]

admissionController:
  serviceMonitor:
    enabled: true

backgroundController:
  serviceMonitor:
    enabled: true

cleanupController:
  serviceMonitor:
    enabled: true

reportsController:
  serviceMonitor:
    enabled: true
EOF
kubectl create ns kyverno
helm repo add kyverno https://kyverno.github.io/kyverno/
helm install kyverno kyverno/kyverno --version 3.3.7 -f kyverno-value.yaml -n kyverno

# 확인
kubectl get all -n kyverno
kubectl get crd | grep kyverno
kubectl get pod,svc -n kyverno

# (참고) 기본 인증서 확인 https://kyverno.io/docs/installation/customization/#default-certificates
# step-cli 설치 https://smallstep.com/docs/step-cli/installation/
wget https://dl.smallstep.com/cli/docs-cli-install/latest/step-cli_amd64.rpm
sudo rpm -i step-cli_amd64.rpm

#
kubectl -n kyverno get secret
kubectl -n kyverno get secret kyverno-svc.kyverno.svc.kyverno-tls-ca -o jsonpath='{.data.tls\.crt}' | base64 -d
kubectl -n kyverno get secret kyverno-svc.kyverno.svc.kyverno-tls-ca -o jsonpath='{.data.tls\.crt}' | base64 -d | step certificate inspect --short
X.509v3 Root CA Certificate (RSA 2048) [Serial: 0]
  Subject:     *.kyverno.svc
  Issuer:      *.kyverno.svc
  Valid from:  2024-04-07T06:05:52Z
          to:  2025-04-07T07:05:52Z

#
kubectl get validatingwebhookconfiguration kyverno-policy-validating-webhook-cfg -o jsonpath='{.webhooks[0].clientConfig.caBundle}' | base64 -d | step certificate inspect --short
X.509v3 Root CA Certificate (RSA 2048) [Serial: 0]
  Subject:     *.kyverno.svc
  Issuer:      *.kyverno.svc
  Valid from:  2024-04-07T06:05:52Z
          to:  2025-04-07T07:05:52Z

4. Kyverno 정책 적용

Kyverno에서 정책을 적용하려면 ClusterPolicy 또는 Policy 리소스를 생성해야 합니다.

4.1 Validation : 파드에 라벨(lables) 검증

# 모니터링
watch -d kubectl get pod -n kyverno

# ClusterPolicy 적용
kubectl apply -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

# 확인
kubectl get validatingwebhookconfigurations
kubectl get ClusterPolicy
NAME             ADMISSION   BACKGROUND   VALIDATE ACTION   READY   AGE   MESSAGE
require-labels   true        true         Enforce           True    12s   Ready

# 디플로이먼트 생성 시도
kubectl create deployment nginx --image=nginx
error: failed to create deployment: admission webhook "validate.kyverno.svc-fail" denied the request: 

resource Deployment/default/nginx was blocked due to the following policies 

require-labels:
  autogen-check-team: 'validation error: label ''team'' is required. rule autogen-check-team
    failed at path /spec/template/metadata/labels/team/'

# 디플로이먼트 생성 시도
kubectl run nginx --image nginx --labels team=backend
kubectl get pod -l team=backend

# 확인
kubectl get policyreport -o wide
NAME                                   KIND         NAME                          PASS   FAIL   WARN   ERROR   SKIP   AGE
e1073f10-84ef-4999-9651-9983c49ea76a   Pod          nginx                         1      0      0      0       0      29s

kubectl get policyreport e1073f10-84ef-4999-9651-9983c49ea76a -o yaml
apiVersion: wgpolicyk8s.io/v1alpha2
kind: PolicyReport
metadata: 
  labels: 
    app.kubernetes.io/managed-by: kyverno
  name: e1073f10-84ef-4999-9651-9983c49ea76a
  namespace: default
results: 
- message: validation rule 'check-team' passed.
  policy: require-labels
  result: pass
  rule: check-team
  scored: true
  source: kyverno
  timestamp: 
    nanos: 0
    seconds: 1712473900
scope: 
  apiVersion: v1
  kind: Pod
  name: nginx
  namespace: default
  uid: e1073f10-84ef-4999-9651-9983c49ea76a
summary: 
  error: 0
  fail: 0
  pass: 1
  skip: 0
  warn: 0

# 정책 삭제
kubectl delete clusterpolicy require-labels

4.2 Mutation : 파드에 라벨(lables) 추가

#
kubectl apply -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

# 확인
kubectl get mutatingwebhookconfigurations
kubectl get ClusterPolicy
NAME         ADMISSION   BACKGROUND   VALIDATE ACTION   READY   AGE     MESSAGE
add-labels   true        true         Audit             True    6m41s   Ready

# 파드 생성 후 label 확인
kubectl run redis --image redis
kubectl get pod redis --show-labels

# 파드 생성 후 label 확인 : 바로 위와 차이점은?
kubectl run newredis --image redis -l team=alpha
kubectl get pod newredis --show-labels

# 삭제
kubectl delete clusterpolicy add-labels

5. Kyverno 모니터링

Kyverno의 동작을 모니터링하기 위해 Prometheus 및 Grafana와 연동할 수 있습니다.

5.1 Prometheus

Kyverno는 Prometheus 메트릭을 지원하여 정책 위반 및 이벤트를 추적할 수 있습니다.

config:
  resourceFiltersExcludeNamespaces: [ kube-system ]

admissionController:
  serviceMonitor:
    enabled: true

backgroundController:
  serviceMonitor:
    enabled: true

cleanupController:
  serviceMonitor:
    enabled: true

reportsController:
  serviceMonitor:
    enabled: true

5.2 Grafana

설치 가이드: Kyverno Grafana Monitoring

  • Dashboard ID: 15987

  • Dashboard ID: 15804

6. Kyverno CLI 활용

Kyverno CLI는 로컬 환경에서 정책을 테스트하는 데 유용합니다.

# Install Kyverno CLI using kubectl krew plugin manager
kubectl krew install kyverno

# test the Kyverno CLI
kubectl kyverno version
kubectl kyverno --help

# 정책 테스트 : --policy-report 옵션은 로컬에서도 리포트 출력을 할 수 있는 기능
kubectl kyverno apply require-probes.yaml --resource nginx.yaml --policy-report

...

1개의 댓글

comment-user-thumbnail
2025년 3월 15일

스터디 모임장 가시다입니다.

6주차 스터디 내용만 4시간 분량인데, 거의 모든 내용을 소화하셔서 잘 정리를 해주셨네요. 수고하셨습니다.

그럼 12주차까지 완주 부탁드립니다.

답글 달기