7.5 KiB
7.5 KiB
Helm Diff Engine 설계
1. 개요
두 버전의 Helm Chart를 비교하여 Structured Diff JSON을 생성하는 컴포넌트. 모든 출력은 deterministic하며 LLM을 사용하지 않는다.
2. Chart Version Detector
역할
새로운 Helm Chart 버전 출시를 감지한다.
감지 방법
| 방법 | 설명 | 적합 대상 |
|---|---|---|
| Repo 디렉토리 스캔 | manifests/helm/<chart>/ 하위 버전 디렉토리 변화를 감지 |
dip-catalog 구조 |
| Git diff 기반 감지 | 최신 커밋에서 추가된 <version>/ 디렉토리 파악 |
dip-catalog 구조 |
Helm repo index.yaml 주기 스캔 |
등록된 repo의 index 파일 직접 파싱 | 외부/사내 Helm repo |
| ArtifactHub API 조회 | https://artifacthub.io/api/v1/packages/helm/{org}/{chart} |
공개 chart |
| GitHub Release Webhook | 차트 소스 저장소의 release 이벤트 구독 | GitHub 기반 차트 |
| Cron 기반 스케줄링 | 위 방법들을 주기적으로 실행 | 공통 |
출력
{
"chart": "airflow",
"repo": "apache",
"current_version": "1.2.3",
"latest_version": "1.3.0",
"detected_at": "2025-01-01T00:00:00Z"
}
dip-catalog 차트 업데이트 흐름 (버전 디렉토리 유지)
신규 버전이 감지되면 dip-catalog 구조에 맞춰 버전 디렉토리를 추가한다. 기존 버전 디렉토리는 유지한다.
1) helm pull <repo>/<chart> --version <new> # 최신 차트 다운로드
2) tar xzf <chart>-<new>.tgz # 압축 해제
3) manifests/helm/<chart>/<new>/ 로 이동 # 버전 디렉토리 생성
4) chart_updater: 이전 버전 디렉토리에서 파일 복사
- custom-values.yaml → 그대로 복사
- CUSTOM-README.md → 그대로 복사 (배포 관련 내용 유지)
- BUILD-README.md → 복사 + 버전 번호 치환 (from_version → to_version)
5) generate_upgrade_doc → CUSTOM-README.md에 업그레이드 주의사항 섹션 추가 (항상 실행)
3. Helm Diff Engine
입력
{
"chart": "airflow",
"from_version": "1.2.3",
"to_version": "1.3.0",
"values_override": {},
"chart_path": "manifests/helm/airflow/1.3.0"
}
dip-catalog 구조에서는
chart_path를 우선 사용한다.
처리 단계
1. (repo 구조) helm pull <repo>/<chart> --version <from> → chart_old/
2. (repo 구조) helm pull <repo>/<chart> --version <to> → chart_new/
1'. (dip-catalog) manifests/helm/<chart>/<from>/ 복사 → chart_old/
2'. (dip-catalog) manifests/helm/<chart>/<to>/ 복사 → chart_new/
3. values.yaml 비교 → Values Diff
4. helm template 결과 비교 → Template Diff
5. CRD schema 비교 → CRD Diff
6. Chart.yaml 비교 → Dependency Diff
7. 결과 병합 → Structured Diff JSON
helm template 표준 옵션
재현성을 위해 아래 옵션을 고정한다.
helm template <chart> \
--values values_override.yaml \
--include-crds \
--kube-version <target_k8s_version> \
--api-versions <explicit_api_versions>
target_k8s_version과api-versions는 환경별 설정값으로 관리한다. dip-catalog의 경우custom-values.yaml이 존재하면values_override기본값으로 적용한다.
에러 처리
| 상황 | 대응 |
|---|---|
| helm pull 실패 | 재시도 3회 → 실패 시 알림 후 중단 |
| chart 미존재 | 로그 기록 + 스킵 |
| helm template 렌더링 오류 | 오류 내용 JSON에 포함, partial diff 생성 |
| 네트워크 타임아웃 | 60s timeout 설정, 재시도 |
4. Values Diff 설계
비교 항목
added: 신규 버전에서 추가된 keyremoved: 신규 버전에서 삭제된 keychanged: default 값이 변경된 keytype_changed: 값의 타입이 변경된 key (string → int 등)
처리 방식
values.yaml을 flat key 형태로 변환 후 비교한다.
- dip-catalog에서는
custom-values.yaml을 기본 values_override로 사용한다.
# 중첩 구조 예시
image:
tag: 1.2.3
pullPolicy: IfNotPresent
# flat key 변환 결과
image.tag: 1.2.3
image.pullPolicy: IfNotPresent
주의: key 이동(rename)은
removed+added로 표현된다. 의미적 rename 감지는 기본 비활성화하며, 필요한 경우 heuristic(유사도 기반) 옵션으로 제공한다.
출력
{
"values": {
"added": ["resources.limits.cpu", "resources.limits.memory"],
"removed": ["ingress.enabled"],
"changed": {
"image.tag": { "old": "1.2.3", "new": "1.3.0" },
"replicaCount": { "old": 1, "new": 2 }
},
"type_changed": [
{ "key": "workers.replicas", "old_type": "string", "new_type": "integer" }
]
}
}
5. Template Diff 설계
처리 방식
helm template <chart_old> --values values_override.yaml > old.yaml
helm template <chart_new> --values values_override.yaml > new.yaml
YAML을 리소스 단위로 분리 후 비교한다 (kind + metadata.name 기준).
generateName만 존재하는 리소스는 템플릿 파일명 + 순번으로 안정적 ID를 생성한다.- Cluster-scoped 리소스는 namespace를 무시한다.
비교 리소스 타입
| 리소스 | 분석 항목 |
|---|---|
| Deployment / StatefulSet | container image, env, resource limits, replicas |
| Service | port, targetPort, type |
| Ingress | rules, TLS, annotations |
| ConfigMap | data key 추가/삭제/변경 |
| CRD | 별도 CRD Diff로 처리 |
| ServiceAccount | annotations |
출력
{
"templates": {
"Deployment/airflow-scheduler": {
"image_changed": true,
"image": { "old": "apache/airflow:1.2.3", "new": "apache/airflow:1.3.0" },
"env_added": ["AIRFLOW__CORE__NEW_SETTING"],
"env_removed": [],
"resource_limits_changed": true
},
"Service/airflow-webserver": {
"port_changed": false
}
}
}
6. CRD Diff 설계
비교 항목
| 항목 | 설명 |
|---|---|
| schema 변경 | OpenAPI v3 schema 필드 변경 |
| required 필드 추가 | 기존 CR에 영향 |
| field 제거 | 기존 CR의 해당 필드 무시됨 |
| version 변경 | storage version 변경 시 migration 필요 |
| webhook 변경 | conversion webhook 추가/제거 |
출력
{
"crd": {
"AirflowCluster": {
"changed": true,
"breaking": true,
"breaking_reasons": ["required field added: spec.executor"],
"schema_changed": true,
"version_changed": false,
"fields_removed": [],
"fields_added": ["spec.executor"],
"required_fields_added": ["spec.executor"]
}
}
}
7. Dependency Diff 설계
Chart.yaml의 dependencies 블록 비교.
{
"dependencies": {
"added": ["redis"],
"removed": [],
"version_changed": {
"postgresql": { "old": "12.1.0", "new": "13.0.0" }
}
}
}
8. 최종 Structured Diff JSON
LLM Summarizer에 전달되는 통합 출력:
{
"chart": "airflow",
"from_version": "1.2.3",
"to_version": "1.3.0",
"generated_at": "2025-01-01T00:00:00Z",
"values": { ... },
"templates": { ... },
"crd": { ... },
"dependencies": { ... },
"errors": []
}
errors 필드에는 렌더링 실패 등의 부분적 오류를 포함한다. LLM은 이를 참고하여 분석 범위를 명시해야 한다.
9. 관련 문서
- 02-breaking-change-rules.md — Breaking Change 판단 로직
- 04-skill-interface.md —
helm_diffSkill 인터페이스