Kyverno 업무 사용기

Jerry·2024년 11월 16일

EKS-Governance

목록 보기
1/1
post-thumbnail

최근 업무에 Kyverno(이하 키베르노)를 무사히 적용하였습니다. 이전부터 간단히 테스트만 하고 해야지 해야지 하고 미루어 두었는데, 이제야 완료하여 속시원합니다. (늘 중요하지만 급하지 않은 일은 미루고 있습니다.)

회사에 DevOps 저 혼자이고, 혼자서 9개의 클러스터를 관리하니 늘 업무를 빠르게 처리할 수 있는 자동화 도구를 찾습니다. 키베르노를 사용하면 쿠버네티스 운영에 필요한 정책을 9개 클러스터에 동시에 적용할 수 있습니다. 예를들어 저희는 노드의 효율적인 자원 사용을 위하여 파드의 cpu - limit 설정을 제거합니다. 그런데 이걸 일일이 최소 수백개의 모든 파드에서 확인하려면 시간이 많이 걸립니다. 이때 키베르노를 사용하면 클러스터 전체에서 cpu - limit 설정이 적용된 파드를 쉽게 찾을 수 있습니다. 그리고 혹시 실수로 새로운 파드에 cpu - limit를 사용하면 강제로(enforce) 설치하지 못하게 하거나 설치는 가능하지만 경고(audit) 메시지만 출력하게 옵션을 선택하여 정책을 지정할 수 있습니다.

유사한 거버넌스 도구로 이 분야에 초기부터 사용되던 OPA(Open Policy Agent, 오파)가 있습니다. 필자가 잘 몰라서 그렇겠지만 오파에 비하여 키베르노가 훨씬 다양한 정책을 참고하기 쉽고, 정책 적용 시 예외 처리(exclude), 조건 지정(match) 등이 용이하였습니다.

그럼 간단히 제가 적용한 주요 내역을 정리합니다.

  • 헬름 이용 Kyverno 설치
  • 정책 준수/위반 여부를 GUI로 확인할 수 있는 policy-reporter 설치
  • kyverno 공식 best practices 기반 정책 적용
  • 손쉬운 예외 처리(exclude) / 선택(?, match) / any pattern 사용 사례

설치

다른 모든 애플리케이션과 동일하게 헬름을 이용하여 쉽게 설치할 수 있습니다. 설치에 사용한 values.yaml 파일을 공유합니다. (깃허브 링크)

admissionController:
  replicas: 3
backgroundController:
  replicas: 2
cleanupController:
  replicas: 2
reportsController:
  replicas: 2

설치 명령어입니다.

helm install kyverno kyverno/kyverno -n kyverno --create-namespace --version 3.2.7 -f values.yaml

Policy Reporter

키베르노를 설치하고 실제 정책, 예를 들어 모든 파드는 cpu/memory request와 memory limit을 가져야 한다를 적용하면 실제 파드가 해당 정책을 준수하였는지(pass) 위반했는지(fail) 확인합니다. CLI 명령어로 Text 기반으로 확인하면 번거로우니 GUI를 사용합니다.

다행히 키베르노는 Policy Reporter 도구를 지원해서 GUI로 편리하게 확인할 수 있습니다. 동일하게 헬름을 이용하여 설치할 수 있습니다.(깃허브링크)

ui:
  enabled: true

kyvernoPlugin:
  enabled: true
helm install policy-reporter policy-reporter/policy-reporter -n kyverno --version 2.24.2 -f values.yaml

GUI라 외부에서 접속 가능하도록 인그레스를 사용합니다. 제가 못찾은건지 policy reporter 헬름 차트는 ingress 설정이 없어서 ingress 파일은 별도로 만들었습니다.

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: policy-reporter-ui
  namespace: kyverno
  annotations:
    alb.ingress.kubernetes.io/certificate-arn: arn:aws:acm:ap-northeast-2:XXXX
    alb.ingress.kubernetes.io/listen-ports: '[{"HTTP":80,"HTTPS": 443}]'
    alb.ingress.kubernetes.io/actions.ssl-redirect: '{"Type": "redirect", "RedirectConfig": { "Protocol": "HTTPS", "Port": "443", "StatusCode": "HTTP_301"}}'
    alb.ingress.kubernetes.io/scheme: internet-facing
    alb.ingress.kubernetes.io/target-type: ip
    alb.ingress.kubernetes.io/group.name: XXXX
    external-dns.alpha.kubernetes.io/hostname: kyverno.XXXX.XXX
spec:
  ingressClassName: alb
  rules:
    - host: kyverno.XXXX.XXX
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: policy-reporter-ui
                port:
                  number: 8080

EKS 환경 인그레스 파일인데, 온프렘 기반은 수정이 필요합니다.

키베르노 Policies

이제 정책을 적용합니다. 정책도 역시 YAML 파일 기반입니다. 처음 키베르노 등의 도구를 사용하면 어떤 정책을 적용해야 할지 막막합니다. 다행히 키베르노는 다양한 예시를 깃허브로 공유합니다. 필자는 그 중에서 Best Practices를 참고하였습니다.

https://github.com/kyverno/policies/tree/main/best-practices

대부분의 정책을 그대로 사용했는데, 제 운영 환경에 맞게 조금 수정하였습니다. 실제 업무에 사용한 정책을 깃허브로 공유합니다.

https://github.com/junghoon2/k8s-class/tree/main/Kyverno/kyverno-policies

키베르노는 이렇게 참고할 수 있는 정책이 풍부하고 best practices 이 외 다른 정책이 필요하면 위 깃허브에서 찾아보면 어렵지 않게 찾을 수 있습니다. 필자도 아래 forbid-cpu-limits 정책은 best practices 이 외 정책인데 검색하여 동일하게 적용하였습니다.

실제 업무에 적용하면 회사마다 환경이 달라 각자 환경에 맞는 정책을 만들어야 합니다. 다행히 키베르노는 정책을 참조하고 수정하기가 편리합니다.

먼저 예외 처리 exclude 설정 예시입니다. 전체 네임스페이스 중에서 정책을 적용하지 않을 네임스페이스를 제외할 때 사용합니다.

      exclude:
        any:
          - resources:
              namespaces:
                - default
                - kube-system
                - kyverno
                - monitoring

위와 같이 exclude 구문에 제외하려는 namespaces 이름을 리스트 형식으로 하나하나 나열하면 간단하게 해당 정책을 적용하지 않을 수 있습니다.

유사하게 특정 이름의 리소스만 제외하려면 아래와 같이 names 설정에 이름을 지정하면 됩니다.

    exclude:
      any:
      - resources:
          names:
          - 'prometheus-prometheus-kube-prometheus-*'

필자는 forbid-cpu-limits 정책 적용 시 Prometheus 파드는 위와 같이 제외하였습니다. Prometheus 헬름 차트에서 해당 설정을 찾기가 어려웠습니다.

다음으로 특정 네임스페이스의 파드 리소스만 포함하려면 아래와 같이 match 구문을 아래와 지정하면 됩니다.

  rules:
  - name: validate-probes
    match:
      any:
      - resources:
          kinds:
          - Pod
          namespaces:
          - foo

Readiness, Liveness Probe 설정을 전체 파드가 아닌 커스텀 헬름 차트로 생성한 파드의 네임스페이스에만 적용하는 예시입니다.

그리고 둘 중에 하나(or) 조건을 사용하려면 아래와 같이 anyPattern을 사용하면 됩니다.

      validate:
        message: "Either the label `app.kubernetes.io/name` or `app` is required."
        anyPattern:
          - metadata:
              labels:
                app.kubernetes.io/name: "?*"
          - metadata:
              labels:
                app: "?*"

위 구문은 모드 파드에 app.kubernetes.io/name 또는 app 레이블을 반드시 포함하는 설정입니다.

키베로노 적용 전에는 안해도 되는데 굳이 해야 하나 싶었는데 막상 적용하니 이 좋은 걸 왜 진작 안했을까 싶습니다. 무엇보다 설치하고 정책을 적용하고 수정하는게 어렵지 않아, 빠르게 할 수 있는 것이 가장 좋았습니다.

제 주위 분들도 실제 사용하시는 분들이 있으니 만약 사용하지 않는다면 한 번 검토하면 좋을 것 같습니다.

profile
도서 <24단계 실습으로 정복하는 쿠버네티스> 저자. 쿠버네티스/EKS 관련 문의 erdia22@gmail.com.

0개의 댓글