0. Contents#
1. Overview# 맥북 · 측정 환경: 눌러서 설명 보기 맥북 · 측정 환경 helm template 만 · 빈 KUBECONFIG · 동시 3개 · nice 19 공개 차트 21개: 눌러서 설명 보기 공개 차트 21개 워크로드 53개 · 목표 칸 209개 ingress-nginx cert-manager kube-prometheus-stack prometheus grafana loki argo-cd metrics-server external-secrets external-dns traefik podinfo vault kyverno cluster-autoscaler aws-load-balancer-controller harbor opentelemetry-collector sealed-secrets jenkins redis podinfo 6.17.0: 눌러서 설명 보기 podinfo 6.17.0 예시 차트. 다른 차트도 같은 길을 지난다 values.yaml: 눌러서 설명 보기 values.yaml replicaCount: 1 logLevel: info image.tag: 6.17.0 extraEnvs: [] resources: { … } … templates/deployment.yaml: 눌러서 설명 보기 templates/deployment.yaml replicas: {{ .Values.replicaCount }} image: "{{ …repository }}: {{ .Values.image.tag }}" ① 기본 렌더: 눌러서 설명 보기 1 기본 렌더 지금 칸의 값을 읽는다 ② 후보 모으기: 눌러서 설명 보기 2 후보 모으기 지금 값과 같은 키 이름이 맞는 키 replica · tag … replicas 칸의 후보 7개 ③ 표시값을 넣어 다시 렌더: 눌러서 설명 보기 3 표시값을 넣어 다시 렌더 replicaCount: 137 ④ 판정: 눌러서 설명 보기 4 판정 키가 아니라 렌더 결과만 본다 렌더 결과: 눌러서 설명 보기 렌더 결과 Deployment kr-podinfo spec.replicas: 눌러서 설명 보기 spec.replicas 키 replicaCount 1 → 137 image: 눌러서 설명 보기 image 키 image.tag podinfo:6.17.0 → 6.17.987 resources: 눌러서 설명 보기 resources 키 resources 137m · 137Mi / 337m · 337Mi env: 눌러서 설명 보기 env 키 extraEnvs KUKIE_MARKER_ENV 판정: 눌러서 설명 보기 판정 합격: 눌러서 설명 보기 합격: 목표 칸 = 표시값 불합격: 눌러서 설명 보기 불합격: 칸은 바뀌었지만 표시값이 아님 기록: 눌러서 설명 보기 기록: 요청 안 한 칸도 바뀜 (합격 중 31칸) 방식 A: 눌러서 설명 보기 방식 A · ② 를 코드가 21개 차트, 칸 209개 찾음 191 / 209 (91.4%) 렌더링 1,135번 · 59.9초 토큰 0 방식 B: 눌러서 설명 보기 방식 B · ② 를 Sonnet 이 놓친 칸이 있는 5개 차트, 칸 62개 찾음 60 / 62 (A 는 55) 207초 789,744 토큰 A 가 놓친 18칸: 눌러서 설명 보기 A 가 놓친 18칸 하드코딩 9: 눌러서 설명 보기 하드코딩 9 규칙 4: 눌러서 설명 보기 규칙 4 조합 2: 눌러서 설명 보기 조합 2 렌더 실패 2: 눌러서 설명 보기 렌더 실패 2 스키마 거부 1: 눌러서 설명 보기 스키마 거부 1 절반은 바꿀 키가 없는 칸이다 두 방식은 ② 만 다르다. ③ ④ 는 같은 렌더 검사라 키를 고른 방법만 비교한다 실측 결과이고 제품 연결 전이다. 지금 Kukie 는 Helm 앱을 PR 로 고치지 못한다. 방식 B 는 LLM 에 유리하게 뽑은 표본이다 키를 추측으로 믿지 않는다 — 값을 넣어 렌더링한 결과로만 합격을 정한다
칸을 누르면 설명이 열린다
배경
02편 의 PR 경로는 plain 과 Kustomize 만 지원한다. 두 형식은 고칠 위치가 형식으로 정해져 코드가 고른다Helm 앱은 values 키를 고쳐야 하는데, 어느 키가 어느 칸으로 가는지는 차트마다 다르다 코드로 찾을지 LLM 에게 맡길지 정하려면 숫자가 필요해 공개 차트로 쟀다 이 글의 질문
고칠 키를 맞게 찾았다는 것을 무엇으로 판단하는가 코드만으로 몇 칸을 찾는가. 왜 못 찾는가 LLM 을 쓰면 얼마나 더 찾고, 무엇을 내는가 렌더링 한 번은 얼마나 드는가 측정 범위
항목 값 대상 공개 차트 21개, 워크로드 53개 목표 칸 209개. 레플리카, 이미지 태그, 리소스, 환경변수 도구 Helm 4.2.2, helm template 만, --kube-version 1.33.0 제외 주 컨테이너 외 컨테이너, 커스텀 리소스, 기존 환경변수 수정
2. Why Helm Is Different — Helm 의 차이# 2.1 형식별 고칠 위치# 형식 고칠 곳 위치를 정하는 것 plain YAML 의 그 칸 apiVersion · kind · name · namespace Kustomize overlay 의 replicas: · images: · patches: kustomization 문법 Helm values 의 어떤 키 차트 작성자의 템플릿
2.2 키와 칸의 거리# ① 기본 렌더 ② 후보 모으기 ③ 표시값 렌더 ④ 판정 차트 values 키 템플릿 렌더 결과 칸 특징 차트 작성자의 코드 podinfo replicaCount spec.replicas 키 하나 → 칸 하나 argo-cd applicationSet.replicas spec.replicas 워크로드마다 다른 키 ingress-nginx controller.image.tag digest image digest 를 함께 비워야 태그가 반영됨 vault server.ha.replicas ha.enabled spec.replicas HA 를 켜야 레플리카 값이 쓰임 cert-manager image.tag image 키가 values 주석에만 있어 후보에서 빠짐 plain 과 Kustomize 는 고칠 위치가 형식으로 정해진다 — Helm 은 템플릿이라는 코드를 사이에 둔다 같은 칸이라도 키 이름은 차트 작성자가 정한다 — 위치를 규칙으로 고정할 수 없다
키 이름만으로는 맞다고 할 수 없다. 같은 이름의 키가 다른 워크로드나 다른 조건에 쓰인다 차트를 읽어도 헬퍼와 조건이 겹치면 결과를 눈으로 확정하기 어렵다 2.3 합격 기준# 키를 고른 근거로 합격을 정하지 않는다. 값을 넣고 렌더링한 결과만 본다. 방식 A 와 방식 B 에 같은 판정을 쓰면 키를 고른 방법만 비교할 수 있다.
3. Code Search — 코드 방식# 3.1 표시값 렌더링# ① 기본 렌더 ② 후보 모으기 ③ 표시값 렌더 ④ 판정 tools/hv.py (요약) MARK_REPLICAS = 137 1 MARK_RES = {"requests": {"cpu": "137m", "memory": "137Mi"}, "limits": {"cpu": "337m", "memory": "337Mi"}} def target_hit(target, base, new): if target == "replicas": 2 if new.get("replicas") == MARK_REPLICAS: return True, "" if new.get("replicas") != base.get("replicas"): 3 return False, "changed-not-marker" return False, "" ... def side_effects(base_surface, new_surface, noise, key, cname, target): want = cell_paths(key, cname)[target][0] 4 # 요청한 칸 말고 바뀐 칸을 모은다 1 눈에 띄는 표시값 기본값으로 잘 안 쓰는 값을 넣는다 태그는 semver 분기가 안 갈리게 앞자리를 살린다 2 합격 목표 칸이 표시값과 같다 3 불합격 칸이 바뀌었지만 표시값이 아니다 값을 가공하는 키일 수 있다 4 다른 칸 변화 합격과 따로 기록한다 무작위 값은 비교에서 뺀다 렌더링만 쓴다 — helm template 과 빈 KUBECONFIG, 플러그인 없음, 의존 차트는 먼저 받아 두고 네트워크를 쓰지 않는다 표시값이 목표 칸에 그대로 나타나야 합격이다 — 값이 바뀌기만 한 키는 합격이 아니다
3.2 후보 좁히기# ① 기본 렌더 ② 후보 모으기 ③ 표시값 렌더 ④ 판정 렌더링 횟수, 같은 눈금 전수 시험 (중단): 모든 키 × 모든 칸 계획 47,761번 · 맥북 부하 31까지 올라 중단 후보 시험 실제 1,135번 · 59.9초 · 동시 실행 3개 · nice 19 전수 계획의 약 2.4% 규칙 1: 같은 값 지금 렌더 값과 같은 키 규칙 2: 이름 replica · tag · resources · env 칸당 평균 후보 17.0개 첫 합격까지 평균 2.51번 후보를 좁혀 놓친 칸이 있는지가 다음 질문이다 — 4.2 의 18칸이 그 답이다 키가 있는데 후보에서 빠진 칸은 cert-manager 3칸과 pushgateway 1칸이었다. 전수 시험 실행의 시간은 쓰지 않았다 모든 키를 시험할 이유가 없다 — 지금 값이나 이름으로 먼저 좁힌다
3.3 측정 안전 조건# 고객이 올릴 차트를 다루는 일의 예행이라 공개 차트에도 같은 제한을 걸었다.
helm install, upgrade, --dry-run=server, 플러그인을 쓰지 않는다빈 KUBECONFIG 를 준다 기본값으로 렌더링이 안 되는 차트 5개는 최소 값(base-values.json)을 넣었다 시험 Pod 의 무작위 이름 같은 값은 비교에서 뺐다 4. Results — 코드 방식 결과# 4.1 21개 차트 결과# 목표 찾음 다른 칸 변화 없음 첫 합격까지 평균 시도 칸당 평균 후보 레플리카 39 / 50 27 1.90 31.5 이미지 태그 49 / 53 40 2.18 11.2 리소스 53 / 53 45 2.25 10.4 환경변수 50 / 53 48 3.60 15.8 합계 191 / 209 (91.4%) 160 2.51 17.0
4.2 놓친 18칸# ① 기본 렌더 ② 후보 모으기 ③ 표시값 렌더 ④ 판정 목표 칸 209개를 한 칸씩 레플리카 39 / 50 이미지 태그 49 / 53 리소스 53 / 53 환경변수 50 / 53 찾음 찾음 · 다른 칸도 바뀜 31 하드코딩 9 스키마 거부 · 렌더 실패 3 규칙이 놓침 4 키 조합 2 이번 측정에서 바꾸지 못함 12칸 하드코딩 레플리카 7 · 환경변수 2 템플릿에 값이 박혀 있다 스키마 거부 external-dns replicaCount 최대 1 렌더 실패 jenkins 0 또는 1 loki 다른 모드와 충돌 값으로 바꿀 수 있음 6칸 규칙이 놓침 cert-manager 태그 3 pushgateway 환경변수 1 키 조합 ingress-nginx digest vault HA 자동 스케일 0, 값 가공으로 실패 0, 하위 차트 0 — 걱정했던 원인은 이번 차트들에서 나오지 않았다 오른쪽 6칸은 직접 렌더링해 확인했다. loki 는 키 조합을 확인하지 못해 렌더 실패 2칸에 남았다 놓친 18칸 중 절반은 찾을 키가 없었다 — 없는 키를 만들 수는 없다
4.3 다른 칸이 함께 바뀌는 키# 합격한 191칸 중 31칸은 키를 바꾸면 요청하지 않은 칸도 함께 바뀌었다. 표시값이 목표 칸에 나타났으니 키는 맞지만, 사용자가 원한 변경인지는 코드가 알 수 없다.
레플리카가 12칸으로 가장 많고, 이미지 태그 9칸, 리소스 8칸, 환경변수 2칸이다 렌더 diff 를 카드에 보여 주고 사람이 판단하는 쪽이 후보다. 제품에서 어떻게 처리할지는 정하지 않았다 5. LLM Comparison — LLM 비교# 5.1 비교 조건# 항목 값 대상 방식 A 가 놓친 칸이 있고 키가 실제로 있는 5개 차트: cert-manager, ingress-nginx, vault, prometheus, loki. 62칸 모델 Sonnet. 차트당 1회 입력 코드가 모은 파일 목록(values, helper, 워크로드 템플릿). 방식 A 결과는 주지 않음 제한 목표당 후보 최대 5개. 키 조합 허용 판정 방식 A 와 같은 렌더 검사
LLM 에 유리한 표본이다. 방식 A 가 “바꿀 수 없음"으로 끝난 11칸이 있는 차트는 넣지 않았다. 21개 전체로 늘려 쟀을 때의 수치가 아니다.
5.2 목표별 결과# 목표 칸 A 찾음 B 찾음 A 만 B 만 둘 다 못 찾음 레플리카 14 12 13 0 1 1 이미지 태그 16 12 16 0 4 0 리소스 16 16 16 0 0 0 환경변수 16 15 15 1 1 0 합계 62 55 60 1 6 1
합격한 60칸은 모두 첫 시도에 합격했다. 키 조합이 필요한 ingress-nginx 태그와 vault 레플리카도 찾았다 실패 2칸 중 loki 본체 레플리카는 validate.yaml 이 거부했다 나머지 node-exporter 환경변수는 칸이 바뀌었지만 표시값 이름과 달라 규칙상 실패다. 판정기가 좁은 영향도 있다 5.3 비용 비교# ① 기본 렌더 ② 후보 모으기 ③ 표시값 렌더 ④ 판정 표본 5개 차트의 칸 62개를 한 칸씩 방식 A: 코드 55 / 62 렌더링 419번 · 10.6초 · 토큰 0 방식 B: Sonnet 60 / 62 칸당 평균 1.34번 시도 · 207초 (차트당 22.8~97.2초) · 789,744 토큰 A 다음 B 61 / 62 A 가 찾은 칸은 토큰을 쓰지 않고, 실패 칸의 차트만 B 로 보낸다 둘 다 찾음 54 A 만 1 B 만 6 못 찾음 표본: A 가 놓친 칸이 있고 키가 실제로 있는 5개 차트, 차트당 1회 실행, 목표당 후보 최대 5개 21개 전체로는 197 / 209 (94%). 나머지 16개 차트의 놓친 칸을 템플릿을 읽어 바꿀 수 없다고 분류해 A 값을 그대로 쓴 수치다 LLM 은 5칸을 더 찾았다 — 대신 토큰과 시간을 쓴다. 다만 LLM 에 유리하게 뽑은 표본이다
토큰은 서브에이전트의 기본 사용량을 포함한 값이다. 실제 서비스에서는 프롬프트와 캐시 구성에 따라 달라지므로 비용으로 환산하지 않았다.
5.4 올바른 변경의 판단# 렌더 검사는 “이 키가 이 칸을 바꾼다"까지만 말해 준다. 코드와 LLM 모두 그 변경이 운영상 맞는지는 알 수 없다.
loki 레플리카처럼 키가 있어도 다른 모드와 충돌하는 칸이 있다 차트 작성자가 값을 하드코딩한 칸은 values 로 바꾸지 않는 것이 맞을 수 있다 최종 판단은 렌더 diff 를 보는 사람의 몫으로 남는다 6. Render Cost — 렌더링 비용# 값 찾기는 후보마다 렌더링을 돌리므로 렌더링 비용이 설계를 정한다. 아래는 이번 측정의 렌더링 1,154번 기록이다. 맥북에서 helm 을 직접 실행했고, 동시 실행 3개, nice 19 다.
항목 시간 중앙값 0.083초 상위 5% 경계 0.38초 상위 1% 경계 0.51초 최대 0.60초
차트 시간 중앙값 최대 메모리 출력 크기 작은 차트 (podinfo 등) 약 0.03초 약 41MB 약 5KB kube-prometheus-stack 0.11초 83MB 650KB harbor (가장 느림) 0.40초 46MB 55KB kyverno (메모리 최대) 0.33초 137MB 5.7MB
메모리는 차트별 기본 렌더링을 한 번씩 재서 얻었다. 정상 차트는 가볍지만, 메모리 137MB 는 모든 고객이 함께 쓰는 에이전트 파드(768Mi)에서 동시에 돌리기에 작지 않다. 고장 났거나 일부러 무겁게 만든 차트는 이 범위 밖이다. 이 숫자가 05편 의 제한 값이 된다.
7. Discussion# 7.1 확인 범위# 내용 확인 방법 방식 A 21개 차트 실측. 원자료 보관 놓친 칸의 분류 템플릿을 읽어 사람이 분류 키 조합 합격 ingress-nginx, vault 는 직접 렌더 확인. loki 는 미확인 방식 B 5개 차트 실측. 차트당 1회라 실행마다의 차이는 재지 않았다 제품 연결 하지 않았다
7.2 남은 한계# 공개 차트만 쟀다. 회사 자체 차트는 이름 규칙이 더 제각각일 수 있다 기존 환경변수 수정과 사이드카는 재지 않았다 놓친 4칸을 잡는 후보 규칙을 더하면 수치가 오를 수 있지만 다시 재지 않았다 측정은 Helm 4.2.2, 렌더링 파드는 Argo CD 에 맞춘 4.2.1 이다 7.3 첫 구현의 방향# 단계 방식 근거 1 코드로 후보를 좁혀 표시값 렌더 91.4%, 토큰 없음, 초 단위 2 실패한 칸만 LLM 5개 차트에서 코드가 놓친 키를 대부분 찾음 3 합격 키로 PR, 렌더 diff 를 카드에 표시 다른 칸 변화는 사람이 판단
제안이고 구현 전이다. 먼저 코드만으로 시작해 놓친 칸의 안내 문구를 다듬어도 된다.
핵심 메시지# 판정 기준: 키 이름이 아니라 렌더 결과 표시값이 목표 칸에 나타나야 합격이고, 방식과 무관하게 같은 검사를 쓴다 코드 방식: 후보를 좁히면 충분히 빠르다 렌더링 1,135번, 59.9초로 209칸 중 191칸을 찾았다 못 찾은 칸: 절반은 찾을 키가 없다 LLM: 어려운 칸에만 5칸을 더 찾지만 토큰 78만 개와 3분 반을 쓴다. 유리한 표본의 값이다 8. References# helm template 과 values 의 동작. 2장과 3장의 근거다.
Application 의 Helm 소스와 values 지정 방식. 2.1 의 근거다.