23.06.15
DEVOTEE를 활성화 시키면
지금 작성한 커뮤니티 글에 대해 1개의 댓글을 달아줍니다.
버튼을 누르면 글 수정 시 ChatGPT가 작성한 댓글이 수정됩니다.
| 컨텐츠 유형 | 제목 | 저장일 | 삭제 |
|---|
본인인증 로그인에 실패하였습니다.
회원이 아니시거나 본인인증 등록이
완료되지 않은 사용자입니다.
이글에서는 정책에 대해 정의하고 이를 지원하는 정책강제플랫폼들을 살펴보고자 한다.
정책을 정확하게 그리고 일반적으로 정의하는 것은 매우 어렵다. 당위적인 범위를 규정해보면 거버넌스의 일부분 이면서 인가를 포함하는 영역의 어딘가라고 할수 있다.

인가의 영역을 넘어서는 정책을 예를 들면 “네이밍룰에 대한 정책”이나 “접속관리정책”등을 들수 있다.
이러한 정책은 인가에서 발생하는 이상의 내용을 처리하거나 상황에 맞는 허용여부 판별하기 위해서 필요하다.
컴퓨팅 측면에서 Policy Enforcement는 자원 사용을 위한 요건들을 생성, 관리, 자동화된 실행 및 모니터링하는 기능을 말한다.
즉 정책의 시행 뿐 아니라 정의, 적용, 관리를 포함한 개념이다.
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)라는 간결한 정책 정의언어를 제공한다.
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는 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의 경우 템플릿의 개념은 없고 하나의 자원으로 기술하여 적용할 수 있다.
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에 비해 간결하고 직관적인 표현식을 사용하는 것을 확인할 수 있다.
구성하는 방법은 아래 그림을 통해 엿볼수 있으며 매우 간결한 정의 방식을 갖고 있음을 확인할 수 있다.

출처: https://kyverno.io/docs/kyverno-policies/
필자는 2년전 Kyverno를 처음 접했고 조사하여 블로그(Kyverno 소개 (OPA의 대항마?))도 작성했던 적이 있다.
이때만 해도 위와 같은 식을 통한 방식이 아니라 kyverno에서 제공하는 모듈들을 고르는 방식으로 접근했었던 기억이 있다.
PSP의 그것과 동일했었다. 하지만 지금 발전된 모습을 보면 앞으로도 기대되는 오픈소스이다.
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=latestpod 수준에서만 제어하는 기능으로 다른 정책관리 도구들에 비해 매우 간단하다.
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:
- testGatekeeper에서 비슷하게 2단계구조를 갖고있으나 Constraint가 파라미터와 적용범위 정보를 갖고 있는것에 반하여
ValidatingAdmissionPolicyBinding은 이미 정해진 제한 조건에서 추가적인 조건을 정의하는 형태로 정보를 넣어 연결(Binding)한다.
이 글을 통해 정책관리 도구들을 소개했다. 각 도구별로 난이도도 다르고 이에따라 접근성도 매우 상이하다.
요구사항에 맞춰 도구를 선택하여 클러스터를 보호할 수 있다. 앞에서 소개한 도구들의 비교표를 첨부하면서 글을 마무리한다.
DEVOTEE를 활성화 시키면
지금 작성한 댓글에 AI가 댓글을 달아줍니다.