안녕하세요! 쿠버네티스 정책의 연금술사, Kyverno 마스터 시리즈의 여섯 번째 시간입니다. 🧙♂️
지난 시간 우리는 정책에 지능을 부여하는 '변수'와 'ConfigMap 참조' 기술을 배웠습니다. 그런데 가져온 데이터가 너무 복잡하거나, 내가 딱 원하는 부분만 골라내고 싶을 땐 어떻게 해야 할까요?
여기서 등장하는 구원 투수가 바로 JMESPath입니다. Kyverno가 데이터를 자유자재로 다루는 핵심 엔진인 JMESPath의 기초부터 실전 활용법까지, 10분 동안 완벽하게 마스터해 봅시다! 🚀

🏗️ 1. JMESPath란 무엇인가요?
JMESPath(제임스패스)는 JSON 문서에서 데이터를 추출하고 가공하기 위한 쿼리 언어입니다. 쿠버네티스의 모든 리소스는 결국 JSON(혹은 YAML) 구조로 이루어져 있기 때문에, Kyverno는 이 JMESPath를 사용해 복잡한 리소스 정보 속에서 필요한 데이터만 쏙쏙 뽑아냅니다.
- 비유: 거대한 도서관(JSON 데이터)에서 특정 장르의 책(쿼리 조건)만 골라내어 예쁘게 요약본(결과값)을 만드는 과정과 같습니다.
🔍 2. JMESPath의 기본 문법 (기초 다지기)
가장 자주 쓰이는 핵심 문법 4가지를 먼저 익혀봅시다.
① 점 표기법 (Identifier) - .
데이터의 계층 구조를 따라 들어갑니다.
- 데이터: {"metadata": {"name": "my-pod"}}
- 쿼리: metadata.name → 결과: "my-pod"
② 리스트 추출 (Index & Flatten) - [ ]
배열(Array) 형태의 데이터에서 특정 요소를 가져오거나 펼칩니다.
- 데이터: {"containers": [{"name": "nginx"}, {"name": "sidecar"}]}
- 쿼리: containers[0].name → 결과: "nginx"
- 쿼리: containers[*].name → 결과: ["nginx", "sidecar"]
③ 필터링 (Filter) - [? ... ]
특정 조건을 만족하는 데이터만 골라냅니다.
- 쿼리: containers[?name=='nginx']
④ 파이프 (Pipe) - |
앞선 결과를 다음 쿼리의 입력으로 전달합니다. (가공의 연속!)
🛠️ 3. Kyverno 정책 내 데이터 추출 원리
Kyverno는 정책 내에서 {{ ... }} 중괄호 두 개를 사용해 JMESPath를 실행합니다.
실전 예제 1: 이미지 태그 추출하기
컨테이너 이미지 주소(nginx:1.21)에서 버전 정보만 가져오고 싶을 때:
# 쿼리: request.object.spec.containers[0].image | split(@, ':') | [1]
# @는 현재 데이터를 의미하며, ':'로 나누어 두 번째(인덱스 1) 값을 가져옵니다.
실전 예제 2: 복잡한 조건 검증 (JMESPath 활용)
서비스의 모든 포트가 8080이 아닌지 검증하고 싶을 때:
validate:
message: "Port 8080 is strictly forbidden!"
deny:
conditions:
all:
- key: 8080
operator: In
value: "{{ request.object.spec.ports[*].port }}" # 모든 포트 번호를 리스트로 추출
🧪 4. Kyverno만의 특별한 JMESPath 함수
Kyverno는 표준 JMESPath 외에도 쿠버네티스 운영에 유용한 전용 함수들을 제공합니다.
- split: 문자열을 특정 문자로 나눕니다. split('a/b/c', '/')
- to_upper / to_lower: 대소문자 변환
- length: 배열의 길이나 문자열의 길이를 반환
- contains: 특정 값이 포함되어 있는지 확인
🚀 5. 운영자를 위한 실무 팁 (Best Practices)
- 데이터가 없을 때를 대비하세요: {{ request.object.metadata.labels.env || 'default' }} 처럼 || 연산자를 사용해 기본값을 설정하면 에러를 방지할 수 있습니다.
- 공식 테스트 사이트 활용: jmespath.org에서 내 쿼리가 복잡한 JSON 데이터를 제대로 파싱하는지 미리 연습해 보세요.
- Kyverno CLI 활용: 정책을 배포하기 전 kyverno jp 명령어를 사용하여 로컬에서 쿼리 결과를 미리 확인하는 습관을 들이세요.
- 가독성 유지: 파이프(|)를 너무 많이 쓰면 정책이 읽기 힘들어집니다. 복잡한 로직은 context 섹션에서 변수로 미리 정의해 두는 것이 좋습니다.
💻 JMESPath 실전 종합 예제: 이미지 태그 및 보안 컨텍스트 검증
이 정책은 JMESPath를 활용하여 1) 모든 컨네이너 이미지의 태그를 추출하여 특정 값을 검증하고, 2) 특정 보안 설정이 누락되었는지 확인하는 고도의 로직을 보여줍니다.
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: jmespath-advanced-validation
annotations:
policies.kyverno.io/title: "Advanced Data Extraction with JMESPath"
policies.kyverno.io/description: "Using JMESPath to audit image tags and security contexts."
spec:
validationFailureAction: Audit
background: true
rules:
- name: validate-container-data
match:
any:
- resources:
kinds:
- Pod
validate:
message: "Security violation: Check image tags or security settings."
deny:
conditions:
all:
# 1. JMESPath로 모든 컨테이너의 이미지 태그만 추출하여 'latest'가 포함되어 있는지 검사
- key: "latest"
operator: In
value: "{{ request.object.spec.containers[*].image | map(&split(@, ':') | [1], @) }}"
# 2. 모든 컨테이너 중 'allowPrivilegeEscalation'이 true인 것이 하나라도 있는지 검사
- key: true
operator: AnyIn
value: "{{ request.object.spec.containers[*].securityContext.allowPrivilegeEscalation || [false] }}"
🔍 JMESPath 쿼리 상세 해설 (How it works?)
위 정책에서 사용된 복잡한 쿼리들이 어떻게 데이터를 요리하는지 단계별로 분석해 보겠습니다.
1️⃣ 이미지 태그 리스트 추출 🏷️
request.object.spec.containers[*].image | map(&split(@, ':') | [1], @)
- containers[*].image: 모든 컨테이너의 이미지 문자열을 배열로 가져옵니다. (예: ["nginx:latest", "redis:6.2"])
- map(...): 배열의 각 요소에 대해 명령을 실행합니다.
- split(@, ':') | [1]: 각 이미지 문자열을 : 기준으로 나누고, 그 중 두 번째 값(인덱스 1)인 태그만 가져옵니다.
- 최종 결과: ["latest", "6.2"] 라는 깔끔한 태그 리스트가 생성됩니다.
2️⃣ 보안 설정 기본값 처리 🛡️
request.object.spec.containers[*].securityContext.allowPrivilegeEscalation || [false]
- || [false]: 만약 사용자가 securityContext를 아예 설정하지 않아 데이터가 null인 경우, 에러를 내는 대신 [false]라는 기본값을 반환하여 정책 검증이 안정적으로 진행되게 합니다.
🚀 이 정책으로 무엇을 배울 수 있나요?
- 배열 처리 능력: [*]와 map()을 사용하면 컨테이너가 1개든 10개든 상관없이 한 번에 검증할 수 있습니다.
- 데이터 가공 기술: 원본 데이터(nginx:latest)를 그대로 쓰지 않고, 내가 필요한 부분(latest)만 잘라내어 비교하는 법을 익힐 수 있습니다.
- 예외 방지 설계: || 연산자를 통해 데이터가 없는 상황(Optional field)에서도 정책이 부드럽게 동작하게 만드는 노하우를 배웁니다.
🌟 마치며
오늘은 Kyverno의 보이지 않는 엔진, JMESPath의 기초와 데이터 추출 원리를 알아보았습니다.
JMESPath를 자유자재로 다루게 되면, 단순히 리소스를 차단하는 수준을 넘어 "사용자가 요청한 데이터의 특정 패턴을 분석하여 수정하거나 거부하는" 고급 정책 설계자가 될 수 있습니다. 🛠️
쿠버네티스 YAML은 복잡하지만, JMESPath라는 핀셋이 있다면 두려울 것이 없습니다.
궁금한 점은 댓글로 남겨주세요! 😊
'클라우드 > Kyverno' 카테고리의 다른 글
| Kyverno 마스터 클래스: YAML을 요리하는 두 가지 방법, 패치 방식의 차이점과 실습 🧩 (0) | 2026.01.06 |
|---|---|
| Kyverno 마스터 클래스: 패턴 매칭으로 완성하는 선언적 쿠버네티스 보안 가이드 (0) | 2026.01.06 |
| Kyverno 마스터 클래스: AdmissionReview 데이터 추출부터 외부 데이터 연동까지 (0) | 2026.01.05 |
| Kyverno 정책의 정교한 설계: Match/Exclude와 Any/All 완벽 가이드 🎯 (0) | 2026.01.05 |
| [Kyverno] Policy(네임스페이스 단위) vs ClusterPolicy(클러스터 전체)의 차이 (0) | 2026.01.05 |