본문 바로가기

DevOps

[AWS EKS] EKS Security (Kyverno)

CloudNet@팀의 EKS 스터디 AEWS 2기에 작성된 자료를 토대로 작성합니다.

 

  • Managing Pod Security on Amazon EKS with Kyverno 
  • Kyverno (Greek for “govern”) is a policy engine designed specifically for Kubernetes.

쿠버네티스 클러스터 내에서 정책기반 관리를 제공하는 오픈소스 프로젝트 입니다.

  • 정책을 코드로 관리 하며 validate,mutate 기반의 정책 설정이 가능합니다.
  • Admission Control : 인증과 권한확인 이후에 추가적으로 요청 내용에 대한 검증이나 요청 내용을 강제로 변경할 때 사용합니다.

 

 

 Kyverno 정책                                                                                                                           

  •  mutate과 validate 설정되어있는 정책들을 통해서 허용/거부합니다.
  • 권한이 있는 사용자에 한해서  추가로 특정 행동을 제한(validate) 혹은 변경(mutate)하는 작업이 가능

 Kyverno 실습                                                                                                                           

kubectl create ns kyverno

# 설치
# 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

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

 

  • kube-system 네임스페이스는 웹후크에서 필터 대상에서 제외하였습니다. EKS VPC-CNI로 배포 스페이스로 운영을 위해 선택하였습니다.
  • ArgoCD와 같이 배포하여 운영하는 경우 대상 감시에 충돌이 일어납니다

 validation                                                                                                                           

  • validationFailureAction: audit 인 경우, 리포트에서 실패를 남기지만 배포가 수행됩니다. 
  •  validationFailureAction: Enforce 배포까지 중지를 원한다면 옵션 값을 enforce
  • 정책 리포트를 확인하면 상세 내역을 확인할 수 있습니다. 배포한 정책들을 조회하면 다음과 같이 확인할 수 있습니다.
# 모니터링
watch -d kubectl get pod -n kyverno

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

# 확인
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 | kubectl neat | yh
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

 

 

 mutation                                                                                                                           

#
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

# 확인
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

 Generation                                                                                                                           

# First, create this Kubernetes Secret in your cluster which will simulate a real image pull 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

#
kubectl get secret regcred
NAME      TYPE                             DATA   AGE
regcred   kubernetes.io/dockerconfigjson   1      26s

#
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: "{{request.object.metadata.name}}"
      synchronize: true
      clone:
        namespace: default
        name: regcred
EOF

#
kubectl get ClusterPolicy
NAME           ADMISSION   BACKGROUND   VALIDATE ACTION   READY   AGE   MESSAGE
sync-secrets   true        true         Audit             True    8s    Ready

# 신규 네임스페이스 생성 후 확인
kubectl create ns mytestns
kubectl -n mytestns get secret

# 삭제
kubectl delete clusterpolicy sync-secrets

 kyverno 모니터링 / CLI                                                                                                                           

  • kyverno 모니터링 : 프로메테우스 - Link & 그라파나 대시보드 - Link
 

Grafana Dashboard

A ready-to-use dashboard for Kyverno metrics.

kyverno.io

  • 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

...

'DevOps' 카테고리의 다른 글

[AWS EKS] EKS IaC with Terraform (1)  (0) 2024.04.23
[AWS EKS] EKS CICD  (0) 2024.04.15
[AWS EKS] EKS Security (IRSA)  (0) 2024.04.11
[AWS EKS] EKS Security ( IAM Authenticator)  (0) 2024.04.08
[AWS EKS] Autoscaling ( Karpenter)  (0) 2024.04.03