Kyverno를 활용하면 쿠버네티스 노드 레이블링 작업에 대해 매우 세밀한 거버넌스(Governance)와 자동화를 구축할 수 있습니다. 특히 말씀하신 "사용자/그룹별 권한 제어"와 "워크벤치(UI) 연동" 시나리오에 Kyverno의 Validate(검증) 및 Mutate(변조) 정책이 어떻게 쓰이는지 핵심 전략을 정리해 드립니다.
기본적으로 쿠버네티스에서 노드 수정 권한은 매우 강력한 권한입니다. Kyverno를 사용하면 단순히 "수정 가능 여부"를 넘어 "누가, 어떤 키-값(Key-Value)만 수정할 수 있는지"를 통제할 수 있습니다.
예를 들어, admin 그룹은 모든 레이블을 고칠 수 있지만, data-scientist 그룹은 project나 workbench-id 레이블만 수정할 수 있도록 제한할 수 있습니다.
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: restrict-node-label-updates
spec:
validationFailureAction: Enforce
background: false
rules:
- name: check-user-label-permission
match:
any:
- resources:
kinds:
- Node
# 특정 그룹이 아닌 경우 검증 로직 실행
exclude:
clusterRoles:
- cluster-admin
validate:
message: "귀하의 그룹은 'workbench/'로 시작하는 레이블만 수정할 수 있습니다."
foreach:
- list: "request.object.metadata.labels"
# 변경된 레이블 키가 특정 패턴인지 확인
deny:
conditions:
- all:
- key: "{{ key }}"
operator: NotEquals
value: "workbench/*"
누가 레이블을 추가했는지 추적하기 위해, 레이블이 변경될 때 수정자의 정보를 별도 주석(Annotation)으로 자동 기입할 수 있습니다.
mutate:
patchStrategicMerge:
metadata:
annotations:
last-modified-by: "{{ serviceAccountName | request.userInfo.username }}"
사용자용 워크벤치 화면에서 이를 구현하려면 다음과 같은 아키텍처가 권장됩니다.
| 기능 | 구현 방법 | Kyverno의 역할 |
|---|---|---|
| 현재 레이블 조회 | kubectl get node --show-labels 결과를 API로 노출 | (직접 관여 안 함) |
| 레이블 추가/수정 | 워크벤치 백엔드에서 kubectl patch node 호출 | 요청을 가로채서(Intercept) 허용된 키인지 검사 |
| 그룹별 권한 분리 | RBAC(ClusterRole) + Kyverno Policy | RBAC이 통과되어도 Kyverno가 세부 레이블 정책 검증 |
workbench.io/owner: "user-a", workbench.io/allow-gpu: "true" 처럼 전용 접두사(Prefix)를 정해두고 해당 접두사가 붙은 레이블만 Kyverno에서 허용하는 것이 가장 안전합니다.message 필드 활용)nodeSelector를 자동 설정하는 흐름이 더 세련된 방식입니다.workbench-users)이 노드에 레이블을 추가하려고 할 때의 상세 YAML 정책 코드를 짜드릴까요?==
Keycloak과 AD가 연동된 환경이라면, 사용자 인증 정보는 OIDC(OpenID Connect)를 통해 쿠버네티스 API 서버로 전달됩니다. 이 과정에서 Keycloak은 AD의 그룹 정보를 ID Token의 groups 클레임(Claim)에 담아 보냅니다.
Kyverno는 이 토큰에 담긴 사용자 이름(User)과 그룹명(Groups)을 실시간으로 읽어 정책에 적용할 수 있습니다.
CN=Admin-Group,OU=Groups...)을 읽어와 JWT 토큰을 발행.Identity를 파악.request.userInfo를 검사하여 정책 승인 여부 결정.Kyverno의 match 또는 preconditions 섹션에서 AD 그룹명을 직접 대조할 수 있습니다.
아래 정책은 AD의 workbench-admins 그룹에 속한 사용자만 노드 레이블을 수정할 수 있도록 제한하는 예시입니다.
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: node-label-permission-by-ad-group
spec:
validationFailureAction: Enforce
rules:
- name: allow-only-specific-ad-groups
match:
any:
- resources:
kinds:
- Node
operations:
- UPDATE
# 권한이 없는 그룹인 경우 차단 로직 실행
preconditions:
all:
- key: "workbench-admins" # 허용할 AD 그룹명 (Keycloak 매핑 기준)
operator: AnyNotIn
value: "{{ request.userInfo.groups }}" # 사용자가 속한 전체 그룹 리스트
validate:
message: "귀하의 AD 그룹 권한으로는 노드 레이블을 수정할 수 없습니다."
deny:
conditions:
- all:
- key: "{{ request.object.metadata.labels }}" # 변경하려는 레이블 확인
operator: NotNull
이 구조가 작동하려면 Keycloak과 쿠버네티스 사이의 매퍼(Mapper) 설정이 선행되어야 합니다.
groups라는 이름의 Protocol Mapper를 추가하여 AD의 그룹 정보가 토큰에 포함되도록 설정해야 합니다.--oidc-username-claim=preferred_username (또는 email)--oidc-groups-claim=groups (토큰 내 groups 필드를 K8s 그룹으로 인식)workbench-admins 그룹인지 확인합니다. 만약 그룹에 속해 있다면 UI상에서 "레이블 수정" 버튼을 활성화합니다.단순히 "수정 가능"을 넘어, "AD 그룹별로 고칠 수 있는 레이블 키를 다르게" 할 수도 있습니다.
ML-Team 그룹: gpu-type, project-id 레이블만 수정 가능Ops-Team 그룹: 모든 레이블 수정 가능이런 식의 세부 제어가 필요하시다면, Kyverno의 foreach 구문을 사용한 Label Key-specific policy 예시를 더 자세히 구성해 드릴 수 있습니다. 어떻게 진행해 드릴까요?