데보션앱 소개페이지 바로가기
로그인 선택

신고하기

CLOSE
신고사유 (대표 사유 1개)
상세내용 (선택)
0/200
  • 신고한 게시글은 더 이상 보이지 않습니다.
  • 이용약관과 운영정책에 따라 신고사유에 해당하는지 검토 후 조치됩니다.
  • 허위 신고인 경우, 신고자의 서비스 이용이 제한될 수 있으니 유의하시어 신중하게 신고해 주세요.
(이 회원이 작성한 모든 댓글과 커뮤니티 게시물이 보이지 않고, 알림도 오지 않습니다.)

미리보기

커뮤니티

      1,234

      badge 23.06.15

      글 등록

      카테고리를 선택해주세요.

      DEVOTEE를 활성화 시키면
      지금 작성한 커뮤니티 글에 대해 1개의 댓글을 달아줍니다.

      버튼을 누르면 글 수정 시 ChatGPT가 작성한 댓글이 수정됩니다.

      임시저장함에 저장되었습니다. 저장일시 : 2022.5.17 14:29:08

      임시저장함

      제목을 선택하시면 이어서 작성이 가능하며,
      최대 20건까지 저장합니다.
      컨텐츠 유형, 제목, 저장일시, 삭제로 이뤄진 임시저장 목록
      컨텐츠 유형 제목 저장일 삭제

      데보션 블로그 게재 요청

      CLOSE
      • *
      • *

      본인인증

      효율적인 데보션 서비스 이용 및
      고객님의 소중한 개인정보보호를 위해
      본인인증을 진행해주세요. 본인인증 미 진행 시 로그인이 제한됩니다.
      본인인증 실패

      본인인증 로그인에 실패하였습니다.
      회원이 아니시거나 본인인증 등록이
      완료되지 않은 사용자입니다.

      회원정보 연결

      Policy Enforcement Platform 비교

      sungil 24.07.23
      767 5 0
      DEVOTEE 요약
      본 블로그에서는 정책의 정의와 컴퓨팅에서의 정책 시행 등을 설명하고 Kubernetes의 정책 지원 기능과 외부 정책 관리 도구를 소개합니다. Kubernetes에서는 RBAC, PSA/PSS, 네트워크 정책, Validating Admission Policy 등을 활용하여 정책을 적용하며, 외부 도구로는 OPA, Gatekeeper, Kyverno 등이 있습니다. 마지막으로 각 도구별 사용방법을 비교하여 소개하며, 이를 통해 클러스터를 보호하는 방법을 제안합니다.
      DEVOTEE 추천 블로그

      이글에서는 정책에 대해 정의하고 이를 지원하는 정책강제플랫폼들을 살펴보고자 한다.


      Policy 란?

      정책을 정확하게 그리고 일반적으로 정의하는 것은 매우 어렵다. 당위적인 범위를 규정해보면 거버넌스의 일부분 이면서 인가를 포함하는 영역의 어딘가라고 할수 있다.


      image


      인가의 영역을 넘어서는 정책을 예를 들면 “네이밍룰에 대한 정책”이나 “접속관리정책”등을 들수 있다.

      이러한 정책은 인가에서 발생하는 이상의 내용을 처리하거나 상황에 맞는 허용여부 판별하기 위해서 필요하다.

      Policy Enforcement 란?

      컴퓨팅 측면에서 Policy Enforcement는 자원 사용을 위한 요건들을 생성, 관리, 자동화된 실행 및 모니터링하는 기능을 말한다.

      즉 정책의 시행 뿐 아니라 정의, 적용, 관리를 포함한 개념이다.


      kubernetes에서의 정책지원기능

      k8s에서는 인가(authorization) 관련되어 몇가지 기능을 제공하고 있다.


      첫번쨰는 RBAC으로 각 자원에 대한 접근허용 여부를 역할로 정의하고 역할을 사용자나 그룹등 접근자에게 부여함으로써 자원에 대한 접근을 제어하는 방식이다.


      두번째로 Pod를 중심으로 좀더 추가적인 정책을 정의할수 있도록 하는 시스템을 제공하고 있으며

      과거에는 PSP(Pod Security Policy)라 불렸고 다양한 모듈을 제공하여 Pod에 대한 접근제어를 추가하도록 했었으나 1.21버전에서 deprecate 했다.

      이후1.25버전에서 훨씬 간단한 모습으로 PSA/PSS(Pod Security Admission / Standard) 라는 이름으로 복귀시켰다.


      세번째는 네트워크 사용관련하여 정책을 정의할수 있도록 해주는 기능을 제공하고 워크로드마다 network policy 부분에 설정할 수 있도록 해준다.


      네번째로 가장 최근(v1.30, 24년 4월)에 등장한 Validating Admission Policy라는 녀석이 있다.

      보다 유연한 정책을 정의할 수 있도록 CEL (Common Expression Langage)라는 간결한 정책 정의언어를 제공한다.


      Kubernetes 외부에서 제공하는 정책관리 도구들

      v1.21 당시 k8s 진영에서는 정책기능 관련하여 외부에서 그 기능을 제공하도록 가이드하면서 PSP를 종료시켰다.

      이전부터 해당 영역을 노리고 있던 정책관리 도구들이 있다. OPA와 Gatekeeper, Kyverno 등이 그것이다.


      OPA는 k8s외부에서 이미 정책관련 정의부터 강제까지의 흐름을 표준화하고자하는 흐름 상에 위치한 오픈소스 소프트웨어이고, kube-mgmt 라는 형태를 통해 k8s의 웹훅시스템으로 들어와 자리 잡고 있다.

      Gatekeeper는 OPA를 좀더 k8s 스럽게 만들고자 정책을 사용자자원(Custom Resource)으로 만들어 사용할 수 있도록 편의 기능 및 seamless 한 kubeapi 연동 등을 제공하면서 빠르게 입지를 넓혔다.

      Gatekeeper도 v1에서는 kube-mgmt의 모듈을 사용하여 동작하였으나 v2 부터는 독자적인 연동구조를 만들고 내부 정책평가 엔진만 OPA를 사용하도록 변경했고

      v3에 이르러서는 OPA에서 제공하지 않는 Mutating 기능까지도 포함하고 있다.


      Kyverno는 가장 나중에 나온 오픈소스로 가장 k8s에 친화적인 시스템을 갖고 있으며 적극적인 마케팅과 극적인 변화를 통해 많은 부분에 영역을 확보하고 있다.


      정책관리 도구 사용방법

      비교를 위핸 동일한 정책-“team 라벨을 지정해야 배포할수 있다.”-을 구현하는 방식을 놓고 각 도구별 사용방법을 알아보자.

      Gatekeeper

      gatekeeper는 2가지 사용자 자원에 의해 정책을 정의하고 적용한다.

      • ConstraintTemplate

        • 정책이 동작하는 구체적인 흐름을 전용언어인 Rego를 통해 기술한다.

        • 사용할때 정의해야할 파라미터등을 포함한다.

      • Constraint

        • 특정 ConstraintTemplate을 적용시키는 역할을 한다.

        • 템플릿에서 정의한 파라미터를 최종결정하여 구체적인 정책을 정의한다.

        • 적용을 위한 대상을 한정할수 있으며

        • 정책 위반에 대응하는 방식도 정의할 수 있다.

      구체적인 CostraintTemplate의 모습은 아래와 같다. spec.targets[].rego 를 보면 REGO를 통해 작성된 로직을 확인할 수 있다.

      apiVersion: templates.gatekeeper.sh/v1beta1
      kind: ConstraintTemplate
      metadata:
        name: k8srequiredlabels
      spec:
        crd:
          spec:
            names:
              kind: K8sRequiredLabels
            validation:
              openAPIV3Schema:
                properties:
                  labels:
                    type: array
                    items:
                      type: string
      ... 중략 ...
        targets:
          - target: admission.k8s.gatekeeper.sh
            rego: |
              package k8srequiredlabels
      
              get_message(parameters, _default) := _default {
                not parameters.message
              }
      
              get_message(parameters, _) := parameters.message
      
              violation[{"msg": msg, "details": {"missing_labels": missing}}] {
                provided := {label | input.review.object.metadata.labels[label]}
                required := {label | label := input.parameters.labels[_].key}
                missing := required - provided
                count(missing) > 0
                def_msg := sprintf("you must provide labels: %v", [missing])
                msg := get_message(input.parameters, def_msg)
              }

      이를 적용하는 Constraint의 모습은 아래와 같다. 파라미터(spec.parameters)를 정의하고 적용범위(spec.match)를 정의한 것을 볼수 있다.

      apiVersion: constraints.gatekeeper.sh/v1beta1
      kind: K8sRequiredLabels
      metadata:
        name: all-must-have-owner
      spec:
        match:
          kinds:
            - apiGroups: [""]
              kinds: ["Namespace"]
        parameters:
          message: "All namespaces must have an `owner` label that points to your company username"
          labels:
            - key: team
              allowedRegex: "^[a-zA-Z]+.agilebank.demo$"

      이 두개의 자원을 클러스터에 배포함으로써 정책을 적용할수 있으며 이를 통해 클러스터에 해당 내역이 강제된다.

      Kyverno

      kyverno의 경우 템플릿의 개념은 없고 하나의 자원으로 기술하여 적용할 수 있다.

      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: "?*"

      spec.rules[].validate 항목에서 Gatekeeper의 REGO에 비해 간결하고 직관적인 표현식을 사용하는 것을 확인할 수 있다.

      구성하는 방법은 아래 그림을 통해 엿볼수 있으며 매우 간결한 정의 방식을 갖고 있음을 확인할 수 있다.

      kyverno-policies

      출처: https://kyverno.io/docs/kyverno-policies/

      필자는 2년전 Kyverno를 처음 접했고 조사하여 블로그(Kyverno 소개 (OPA의 대항마?))도 작성했던 적이 있다.

      이때만 해도 위와 같은 식을 통한 방식이 아니라 kyverno에서 제공하는 모듈들을 고르는 방식으로 접근했었던 기억이 있다.

      PSP의 그것과 동일했었다. 하지만 지금 발전된 모습을 보면 앞으로도 기대되는 오픈소스이다.

      PSA/PSS

      PSA는 PSS를 사용하여 전체 적용하도록 하는 방식으로 단순하게 3가지 모드만 지정할 수 있는 단순한 기능이다.

      따라서 라벨 지정을 강제하는 정책을 만들수가 없으며 k8s 진영에서 정의한 기본(baseline), 최소권한(restricted), 권한허용(previledged) 중 하나를 전체적으로 적용하는 것만 가능하다.


      적용범위를 클러스터와 네임스페이스로 지정할 수 있다. 클러스터 전체에 적용하기 위해서는 PSS 지정한 설정을 kubeapi에 추가하여 k8s를 시작해야한다.

      네임스페이스에 대한 지정은 라벨을 지정함으로써 적용할 수 있다.

      > kubectl label --overwrite ns example  \
      pod-security.kubernetes.io/enforce=baseline \ 
      pod-security.kubernetes.io/enforce-version=latest \ 
      pod-security.kubernetes.io/warn=restricted \ 
      pod-security.kubernetes.io/warn-version=latest \ 
      pod-security.kubernetes.io/audit=restricted \ 
      pod-security.kubernetes.io/audit-version=latest

      pod 수준에서만 제어하는 기능으로 다른 정책관리 도구들에 비해 매우 간단하다.

      Validating Admission Policy

      k8s에서 최근발표한 기능인 Validating Admission Policy의 경우는 2가지 자원을 제공하여 조절할 수 있다.

      가장 나중에 나온 것인만큼 기존의 좋은 부분을 대부분 수용한 모습을 갖고 있다.

      • ValidatingAdmissionPolicy

        • 접근하고자하는 자원의 정의

        • CEL을 사용하여 검증조건 정의

      • ValidatingAdmissionPolicyBinding

        • 좀더 구체적인 조건 정의

      구체적인 ValidatingAdmissionPolicy의 모습은 아래와 같다.

      spec.matchConstraints.resourceRules에서 대상자원의 정의를 확인할 수 있으며, spec.validations[].expression 를 보면 CEL로 작성된 검증식을 확인할 수 있다.

      apiVersion: admissionregistration.k8s.io/v1
      kind: ValidatingAdmissionPolicy
      metadata:
        name: "demo-policy.example.com"
      spec:
        failurePolicy: Fail
        matchConstraints:
          resourceRules:
          - apiGroups:   ["apps"]
            apiVersions: ["v1"]
            operations:  ["CREATE", "UPDATE"]
            resources:   ["deployments"]
        validations:
          - expression: "object.metadata.labels.team != ''"

      ValidatingAdmissionPolicyBinding의 구체적인 예시는 아래와 같으며 spec.matcheResources에 적용을 위한 조건을 좀더 추가하여 넣을수 있다.

      apiVersion: admissionregistration.k8s.io/v1alpha1
      kind: ValidatingAdmissionPolicyBinding
      metadata:
        name: "demo-binding-test.example.com"
      spec:
        policyName: "demo-policy.example.com"
        matchResources:
          namespaceSelector:
            matchExpressions:
              -key: environment
                operator: In
                values:
                  - test

      Gatekeeper에서 비슷하게 2단계구조를 갖고있으나 Constraint가 파라미터와 적용범위 정보를 갖고 있는것에 반하여

      ValidatingAdmissionPolicyBinding은 이미 정해진 제한 조건에서 추가적인 조건을 정의하는 형태로 정보를 넣어 연결(Binding)한다.


      마치며

      이 글을 통해 정책관리 도구들을 소개했다. 각 도구별로 난이도도 다르고 이에따라 접근성도 매우 상이하다.

      요구사항에 맞춰 도구를 선택하여 클러스터를 보호할 수 있다. 앞에서 소개한 도구들의 비교표를 첨부하면서 글을 마무리한다.


      댓글 0

      DEVOTEE를 활성화 시키면
      지금 작성한 댓글에 AI가 댓글을 달아줍니다.

      sungil 님의 최신 블로그

      더보기

      DEVOTEE 추천 블로그

      동영상 기고하기