Move directory
This commit is contained in:
@@ -0,0 +1,145 @@
|
||||
# 전체 아키텍처 개요
|
||||
|
||||
## 1. 목적
|
||||
|
||||
Helm Chart 신규 버전을 카탈로그에 자동으로 추가하고, 해당 버전으로 배포/업그레이드 시 참고할 주의사항을 문서화한다.
|
||||
|
||||
> **카탈로그 역할**: 신규 배포를 위한 Helm 차트 버전 보관소. 운영 클러스터 직접 변경과 무관.
|
||||
|
||||
자동화 항목:
|
||||
- 신규 버전 차트 pull 및 카탈로그 디렉토리 추가
|
||||
- Structured Diff JSON 기반 변경 분석
|
||||
- `custom-values.yaml` 수정 필요 여부(Breaking) 판단
|
||||
- 업그레이드 주의사항 문서 자동 생성 (`CUSTOM-README.md`에 추가)
|
||||
- Git PR 자동 생성
|
||||
|
||||
---
|
||||
|
||||
## 2. 설계 원칙
|
||||
|
||||
| # | 원칙 |
|
||||
|---|------|
|
||||
| 1 | LLM은 Helm CLI를 직접 구성하거나 실행하지 않는다. helm 실행은 결정론적 Skill이 전담하며, Agent/LLM은 Skill을 언제 호출할지만 결정한다 |
|
||||
| 2 | Diff 생성은 100% deterministic 해야 한다 |
|
||||
| 3 | LLM 입력은 반드시 Structured JSON 형식이다 |
|
||||
| 4 | Breaking Change 판단은 코드 기반 Rule Engine이 먼저 수행한다 |
|
||||
| 5 | LLM은 설명 및 Markdown 생성만 담당한다 |
|
||||
| 6 | 각 컴포넌트는 Agent Skill로 노출한다 (Agent가 직접 호출) |
|
||||
| 7 | 카탈로그 업데이트는 Git PR로 관리한다 (운영 환경 직접 변경 아님) |
|
||||
| 8 | 외부 입력(PR comment, webhook 등)은 신뢰 경계 밖으로 취급하며, 프롬프트 주입 방어를 기본 전제로 한다 |
|
||||
|
||||
## 2.1 운영 기준 (Non-Functional)
|
||||
|
||||
- **성능**: Diff 생성 + 요약 전체 파이프라인 5분 내 완료를 목표로 한다 (대형 차트는 예외).
|
||||
- **신뢰성**: 실패 시 재시도 3회, 재시도 후 실패는 알림 전송 + 중단.
|
||||
- **검토 정책**: `breaking=true` PR에는 `needs-review` 레이블을 부착한다. 담당자가 `custom-values.yaml` 수정 후 merge 여부를 판단한다. (`breaking=false` PR은 자동 merge 가능)
|
||||
|
||||
---
|
||||
|
||||
## 3. 전체 시스템 아키텍처
|
||||
|
||||
### Step 1: Skills (에이전트 내부에서 호출되는 개별 기능)
|
||||
|
||||
```
|
||||
[Chart Version Detector]
|
||||
│ chart명, current/new version
|
||||
▼
|
||||
[chart_updater Skill]
|
||||
│ helm pull → manifests/helm/<chart>/<to_version>/ 생성
|
||||
│ CUSTOM-README.md carry-over from previous version
|
||||
▼
|
||||
[helm_diff Skill]
|
||||
│ values/template/CRD 비교
|
||||
▼
|
||||
[Structured Diff JSON]
|
||||
│ { values, templates, crd, dependencies }
|
||||
▼
|
||||
[breaking_change_check Skill]
|
||||
│ custom-values.yaml 기준 판단 (LLM 없음)
|
||||
│ breaking=true: custom-values.yaml 수정 필요
|
||||
│ breaking=false: 수정 불필요 (주의사항만)
|
||||
▼
|
||||
[generate_upgrade_doc Skill] ← 항상 실행
|
||||
│ breaking=true → LLM 상세 가이드 (custom-values.yaml 수정 방법 포함)
|
||||
│ breaking=false → 템플릿 기반 간단 요약
|
||||
▼
|
||||
[update_docs_file Skill]
|
||||
│ CUSTOM-README.md에 업그레이드 주의사항 섹션 추가
|
||||
▼
|
||||
[create_pr Skill]
|
||||
│ branch 생성 → PR 생성 (항상)
|
||||
│ breaking=true → label: needs-review
|
||||
│ breaking=false → label: auto-update
|
||||
```
|
||||
|
||||
> 각 Skill은 독립적으로 호출 가능. 호출 순서는 Agent(Step 2~3)가 담당.
|
||||
|
||||
> `deploy_validate` Skill은 Phase 2에서 구현 예정 (현재 스코프 밖).
|
||||
|
||||
### Step 2~3: On-Cluster AI Agent
|
||||
|
||||
```
|
||||
[OpenClaw / Nanobot on K8s]
|
||||
│
|
||||
├── Skill: chart_version_detector → 신규 버전 감지
|
||||
├── Skill: chart_updater → 신규 버전 차트 pull
|
||||
├── Skill: helm_diff → Structured Diff JSON 생성
|
||||
├── Skill: breaking_check → custom-values.yaml 수정 필요 여부 판단
|
||||
├── Skill: generate_doc → 업그레이드 주의사항 문서 생성 (항상)
|
||||
├── Skill: update_docs → CUSTOM-README.md 업데이트
|
||||
├── Skill: create_pr → GitHub PR 생성
|
||||
└── Channel: Discord → 알림 발송 (추후 Slack으로 변경 가능)
|
||||
|
||||
트리거: Cron 스케줄 또는 K8s 이벤트
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 4. 컴포넌트 책임 분리
|
||||
|
||||
| 컴포넌트 | 역할 | 결정성 | LLM 사용 |
|
||||
|---------|------|--------|---------|
|
||||
| Chart Version Detector | 신규 버전 감지 | ✅ | ❌ |
|
||||
| Chart Updater | 신규 버전 차트 pull → 버전 디렉토리 생성 | ✅ | ❌ |
|
||||
| Helm Diff Engine | Structured Diff JSON 생성 | ✅ | ❌ |
|
||||
| Breaking Change Rule Engine | custom-values.yaml 수정 필요 여부 판단 | ✅ | ❌ |
|
||||
| LLM Summarizer | 업그레이드 주의사항 문서 생성 | ❌ | ✅ (breaking=true 시만) |
|
||||
| Docs Updater | CUSTOM-README.md 업그레이드 주의사항 섹션 추가 | ✅ | ❌ |
|
||||
| Git PR Bot | branch / commit / PR 생성 | ✅ | ❌ |
|
||||
|
||||
---
|
||||
|
||||
## 5. 기술 스택
|
||||
|
||||
| 영역 | 선택 | 비고 |
|
||||
|------|------|------|
|
||||
| Helm CLI | helm 3.x | pull, template, diff |
|
||||
| 버전 감지 | ArtifactHub API / GitHub Release Webhook | |
|
||||
| Diff 처리 | Python (deepdiff 또는 직접 구현) | |
|
||||
| Rule Engine | Python | 코드 기반, custom-values.yaml 기준 |
|
||||
| LLM | Claude (Anthropic) | via Skill or API, breaking=true 시만 호출 |
|
||||
| 문서 저장 | `manifests/helm/<chart>/<version>/CUSTOM-README.md` | 업그레이드 주의사항 섹션 추가 |
|
||||
| PR 생성 | GitHub API (PyGithub / gh CLI) | |
|
||||
| 스케줄링 | Agent 내장 스케줄러 (Cron) | Step 2~3 |
|
||||
| On-Cluster Agent | OpenClaw / Nanobot | Step 2~3 |
|
||||
| Skill Contract | JSON 스키마 (Skill I/O) | Step 1 계약 (Agent-Skill 인터페이스) |
|
||||
|
||||
---
|
||||
|
||||
## 6. 데이터 흐름 요약
|
||||
|
||||
```
|
||||
입력: chart명 + current_version + new_version (레포 내 디렉토리 기준)
|
||||
중간: Structured Diff JSON (values/templates/crd/breaking) + CUSTOM-README.md (docs_context)
|
||||
출력: CUSTOM-README.md 업그레이드 주의사항 섹션 + GitHub PR
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 7. 관련 설계 문서
|
||||
|
||||
- [01-helm-diff-engine.md](01-helm-diff-engine.md) — Diff Engine 상세 설계
|
||||
- [02-breaking-change-rules.md](02-breaking-change-rules.md) — Rule Engine 판단 로직
|
||||
- [03-llm-summarizer.md](03-llm-summarizer.md) — LLM Summarizer + Docs Updater
|
||||
- [04-skill-interface.md](04-skill-interface.md) — Skill 인터페이스 정의
|
||||
- [05-on-cluster-agent.md](05-on-cluster-agent.md) — On-Cluster Agent 설계 (Step 2~3)
|
||||
@@ -0,0 +1,281 @@
|
||||
# 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 기반 스케줄링 | 위 방법들을 주기적으로 실행 | 공통 |
|
||||
|
||||
### 출력
|
||||
|
||||
```json
|
||||
{
|
||||
"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
|
||||
|
||||
### 입력
|
||||
|
||||
```json
|
||||
{
|
||||
"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`: 신규 버전에서 추가된 key
|
||||
- `removed`: 신규 버전에서 삭제된 key
|
||||
- `changed`: default 값이 변경된 key
|
||||
- `type_changed`: 값의 타입이 변경된 key (string → int 등)
|
||||
|
||||
### 처리 방식
|
||||
|
||||
values.yaml을 **flat key** 형태로 변환 후 비교한다.
|
||||
|
||||
- dip-catalog에서는 `custom-values.yaml`을 기본 values_override로 사용한다.
|
||||
|
||||
```yaml
|
||||
# 중첩 구조 예시
|
||||
image:
|
||||
tag: 1.2.3
|
||||
pullPolicy: IfNotPresent
|
||||
|
||||
# flat key 변환 결과
|
||||
image.tag: 1.2.3
|
||||
image.pullPolicy: IfNotPresent
|
||||
```
|
||||
|
||||
> **주의**: key 이동(rename)은 `removed` + `added`로 표현된다. 의미적 rename 감지는 기본 비활성화하며, 필요한 경우 heuristic(유사도 기반) 옵션으로 제공한다.
|
||||
|
||||
### 출력
|
||||
|
||||
```json
|
||||
{
|
||||
"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 설계
|
||||
|
||||
### 처리 방식
|
||||
|
||||
```bash
|
||||
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 |
|
||||
|
||||
### 출력
|
||||
|
||||
```json
|
||||
{
|
||||
"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 추가/제거 |
|
||||
|
||||
### 출력
|
||||
|
||||
```json
|
||||
{
|
||||
"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` 블록 비교.
|
||||
|
||||
```json
|
||||
{
|
||||
"dependencies": {
|
||||
"added": ["redis"],
|
||||
"removed": [],
|
||||
"version_changed": {
|
||||
"postgresql": { "old": "12.1.0", "new": "13.0.0" }
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 8. 최종 Structured Diff JSON
|
||||
|
||||
LLM Summarizer에 전달되는 통합 출력:
|
||||
|
||||
```json
|
||||
{
|
||||
"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](02-breaking-change-rules.md) — Breaking Change 판단 로직
|
||||
- [04-skill-interface.md](04-skill-interface.md) — `helm_diff` Skill 인터페이스
|
||||
@@ -0,0 +1,158 @@
|
||||
# Breaking Change Rule Engine 설계
|
||||
|
||||
## 1. 개요
|
||||
|
||||
Structured Diff JSON을 입력받아 **코드 기반**으로 Breaking Change 여부를 판단한다.
|
||||
LLM을 사용하지 않으며, 결과는 완전히 deterministic하다.
|
||||
|
||||
> **카탈로그 맥락에서의 Breaking 정의**: `custom-values.yaml`을 수정해야 하는 상황.
|
||||
> 카탈로그는 신규 배포를 위한 차트 보관소이며, 운영 클러스터 직접 변경과 무관하다.
|
||||
> Breaking 판단의 기준은 "기존 `custom-values.yaml`이 새 차트 버전에서 유효한가?"이다.
|
||||
|
||||
> 설계 의도: LLM이 "이건 Breaking인 것 같아"라고 추론하는 대신, 코드가 명확한 기준으로 판단한다.
|
||||
|
||||
---
|
||||
|
||||
## 2. Breaking Change 판단 기준
|
||||
|
||||
### 2.0 공통 원칙
|
||||
|
||||
모든 values 관련 규칙에서 **`custom-values.yaml`에 해당 key가 존재하는지 여부**가 breaking 판단의 핵심 조건이다.
|
||||
|
||||
- `custom-values.yaml`이 없거나 해당 key를 사용하지 않는 경우 → `warning`으로 처리 (실제 수정 불필요)
|
||||
- `custom-values.yaml`에 해당 key가 존재하는 경우 → `breaking`으로 처리 (수정 필요)
|
||||
|
||||
### 2.1 Values 관련
|
||||
|
||||
| 조건 | 판정 | 조건 상세 |
|
||||
|------|------|---------|
|
||||
| values key 삭제 | ✅ Breaking | 해당 key가 `custom-values.yaml`에 **있을** 때 — 기존 override가 무시됨 |
|
||||
| values key 삭제 | ⚠️ Warning | 해당 key가 `custom-values.yaml`에 **없을** 때 (또는 custom-values.yaml 없음) |
|
||||
| values type 변경 | ✅ Breaking | 해당 key가 `custom-values.yaml`에 **있을** 때 — 파싱 오류 또는 예상치 못한 동작 |
|
||||
| values type 변경 | ⚠️ Warning | 해당 key가 `custom-values.yaml`에 **없을** 때 |
|
||||
| values key 추가 | ℹ️ Info | 항상 — 신규 기능, 필요 시 custom-values.yaml에 추가 검토 |
|
||||
| default 값 변경 | ⚠️ Warning | custom-values.yaml에서 명시적으로 override하지 않는 경우 동작 변경 가능 |
|
||||
|
||||
> **`custom-values.yaml` 없는 차트**: 해당 차트에 custom override가 없으므로 values 삭제는 모두 `warning`으로 처리.
|
||||
|
||||
### 2.2 Template / 리소스 관련
|
||||
|
||||
카탈로그 맥락에서 Template 변경은 `custom-values.yaml` 수정 요인이 아니므로 **Warning**으로 처리한다.
|
||||
담당자가 신규 배포 시 참고할 수 있도록 업그레이드 주의사항 문서에 기록한다.
|
||||
|
||||
| 조건 | 판정 | 이유 |
|
||||
|------|------|------|
|
||||
| Service port 변경 | ⚠️ Warning | 카탈로그 신규 배포 시 주의사항. custom-values.yaml에서 port override 가능 |
|
||||
| Service type 변경 (ClusterIP → NodePort 등) | ⚠️ Warning | 네트워크 구성 변경 필요, 주의사항으로 기록 |
|
||||
| Deployment selector 변경 | ⚠️ Warning | 재배포 시 주의사항. custom-values.yaml 수정 요인 아님 |
|
||||
| StatefulSet selector 변경 | ⚠️ Warning | 동일 |
|
||||
| StatefulSet volumeClaimTemplate 변경 | ⚠️ Warning | 동일 |
|
||||
| container 이름 변경 | ⚠️ Warning | 참조 변경 필요, 주의사항 기록 |
|
||||
| 리소스 삭제 | ⚠️ Warning | 의존 서비스 변경 필요, 주의사항 기록 |
|
||||
| resource limits 변경 | ℹ️ Info | 참고 사항 |
|
||||
| replicas 기본값 변경 | ℹ️ Info | custom-values.yaml에서 명시적 설정 시 영향 없음 |
|
||||
|
||||
### 2.3 CRD 관련
|
||||
|
||||
CRD 변경은 기존 Custom Resource의 유효성에 영향을 미치므로 Breaking으로 처리한다.
|
||||
|
||||
| 조건 | 판정 | 이유 |
|
||||
|------|------|------|
|
||||
| CRD field 삭제 | ✅ Breaking | 기존 CR의 해당 필드 손실 |
|
||||
| required field 추가 | ✅ Breaking | 기존 CR validation 실패 |
|
||||
| storage version 변경 | ✅ Breaking | migration 없이 롤백 불가 |
|
||||
| conversion webhook 제거 | ✅ Breaking | 구버전 API 호출 실패 |
|
||||
| field 추가 (optional) | ❌ Not Breaking | 하위 호환 |
|
||||
| schema 제약 완화 | ❌ Not Breaking | 기존 CR은 계속 유효 |
|
||||
|
||||
### 2.4 Dependency 관련
|
||||
|
||||
서브차트의 values를 `custom-values.yaml`에서 override하는 경우에만 breaking이다.
|
||||
|
||||
| 조건 | 판정 | 조건 상세 |
|
||||
|------|------|---------|
|
||||
| 하위 chart major version 변경 | ✅ Breaking | `custom-values.yaml`에 해당 subchart prefix key가 **있을** 때 (예: `postgresql.*`) |
|
||||
| 하위 chart major version 변경 | ⚠️ Warning | `custom-values.yaml`에 해당 subchart 관련 key가 **없을** 때 |
|
||||
| 하위 chart 제거 | ⚠️ Warning | 항상 — 주의사항으로 기록 |
|
||||
| 하위 chart 추가 | ℹ️ Info | 항상 — 신규 리소스 생성만 발생 |
|
||||
|
||||
### 2.5 Deprecated K8s API 감지
|
||||
|
||||
| 조건 | 판정 | 이유 |
|
||||
|------|------|------|
|
||||
| Deprecated API 사용 (extensions/v1beta1 등) | ⚠️ Warning | K8s 버전에 따라 영향 있을 수 있음 |
|
||||
|
||||
감지 방법: `helm template` 결과의 `apiVersion` 필드를 K8s deprecated API 목록과 대조.
|
||||
|
||||
---
|
||||
|
||||
## 3. Rule Engine 출력
|
||||
|
||||
## 2.6 Rule 우선순위 및 충돌 처리
|
||||
|
||||
- 동일 리소스에 여러 Rule이 매칭되면 **가장 높은 severity**를 최종 severity로 채택한다.
|
||||
- reasons는 모두 남기되, `severity`는 max 기준으로 집계한다.
|
||||
- `breaking=true`는 `reasons`에 항목이 하나라도 있을 때만 설정된다.
|
||||
|
||||
### 3.1 기본 출력
|
||||
|
||||
```json
|
||||
{
|
||||
"breaking": true,
|
||||
"severity": "high",
|
||||
"reasons": [
|
||||
{
|
||||
"type": "values_key_removed",
|
||||
"key": "ingress.enabled",
|
||||
"detail": "custom-values.yaml에서 사용 중인 key가 삭제됨 — custom-values.yaml 수정 필요"
|
||||
}
|
||||
],
|
||||
"warnings": [
|
||||
{
|
||||
"type": "service_port_changed",
|
||||
"resource": "Service/airflow-webserver",
|
||||
"detail": "port changed from 8080 to 8081 — 신규 배포 시 참고"
|
||||
},
|
||||
{
|
||||
"type": "values_key_removed",
|
||||
"key": "old_setting",
|
||||
"detail": "custom-values.yaml에서 사용하지 않는 key 삭제 — 수정 불필요"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### 3.2 severity 정의
|
||||
|
||||
| severity | 조건 |
|
||||
|----------|------|
|
||||
| `critical` | CRD storage version 변경 |
|
||||
| `high` | custom-values.yaml에서 사용 중인 values key 삭제/타입 변경, CRD required field 추가 |
|
||||
| `medium` | custom-values.yaml에서 사용 중인 subchart dependency major version 변경 |
|
||||
| `warning` | Deprecated API 사용, 미사용 values key 삭제, template 변경 (port, resource 등) |
|
||||
|
||||
---
|
||||
|
||||
## 4. 확장 방법
|
||||
|
||||
새로운 Breaking 조건을 추가하려면 Rule 정의 파일에 항목을 추가한다.
|
||||
각 Rule은 다음 인터페이스를 구현한다:
|
||||
|
||||
```python
|
||||
class BreakingRule:
|
||||
name: str
|
||||
severity: str # critical / high / medium / warning
|
||||
|
||||
def check(self, diff: StructuredDiffJSON, custom_keys: set[str]) -> list[BreakingReason]:
|
||||
...
|
||||
```
|
||||
|
||||
Rule 목록은 설정 파일(`rules.yaml`)로 활성화/비활성화 가능하도록 설계한다.
|
||||
|
||||
---
|
||||
|
||||
## 5. 관련 문서
|
||||
|
||||
- [01-helm-diff-engine.md](01-helm-diff-engine.md) — Structured Diff JSON 생성
|
||||
- [03-llm-summarizer.md](03-llm-summarizer.md) — Breaking Change 결과를 LLM에 전달
|
||||
- [04-skill-interface.md](04-skill-interface.md) — `breaking_change_check` Skill 인터페이스
|
||||
@@ -0,0 +1,243 @@
|
||||
# LLM Summarizer + Docs Updater 설계
|
||||
|
||||
## 1. 개요
|
||||
|
||||
Structured Diff JSON과 Breaking Change 판단 결과를 입력받아 자연어 업그레이드 주의사항 문서를 생성하고,
|
||||
해당 차트 버전의 `CUSTOM-README.md`에 반영한다.
|
||||
|
||||
> LLM의 유일한 역할: Structured JSON → Markdown 문서 변환. Diff 생성이나 Breaking 판단은 수행하지 않는다.
|
||||
|
||||
---
|
||||
|
||||
## 2. LLM Summarizer
|
||||
|
||||
### 2.0 실행 조건
|
||||
- `generate_upgrade_doc`은 **항상 실행**한다 (breaking 여부 무관).
|
||||
- `breaking=true` → LLM을 사용하여 `custom-values.yaml` 수정 방법을 포함한 상세 가이드 생성.
|
||||
- `breaking=false` → 템플릿 기반 간단 요약 생성 (LLM 미호출).
|
||||
|
||||
> 카탈로그는 신규 배포를 위한 차트 보관소이므로, breaking 여부와 무관하게 모든 업그레이드에 주의사항 기록이 필요하다.
|
||||
|
||||
### 2.1 입력
|
||||
|
||||
```json
|
||||
{
|
||||
"chart": "airflow",
|
||||
"from_version": "1.2.3",
|
||||
"to_version": "1.3.0",
|
||||
"values": { ... },
|
||||
"templates": { ... },
|
||||
"crd": { ... },
|
||||
"dependencies": { ... },
|
||||
"breaking": true,
|
||||
"severity": "high",
|
||||
"breaking_reasons": [
|
||||
{
|
||||
"type": "values_key_removed",
|
||||
"key": "ingress.enabled",
|
||||
"detail": "custom-values.yaml에서 사용 중인 key가 삭제됨 — 수정 필요"
|
||||
}
|
||||
],
|
||||
"warnings": [
|
||||
{
|
||||
"type": "service_port_changed",
|
||||
"resource": "Service/airflow-webserver",
|
||||
"detail": "port changed from 8080 to 8081"
|
||||
}
|
||||
],
|
||||
"docs_context": {
|
||||
"CUSTOM-README.md": "..."
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
> dip-catalog 구조에서는 버전 디렉토리 내 `CUSTOM-README.md` 내용을 `docs_context`로 제공한다.
|
||||
|
||||
### 2.2 Prompt 설계
|
||||
|
||||
```
|
||||
당신은 Kubernetes Helm 업그레이드 주의사항 문서를 작성하는 전문가입니다.
|
||||
|
||||
두 Helm 차트 버전 간 변경점을 담은 Structured Diff JSON이 제공됩니다.
|
||||
이 카탈로그는 신규 배포를 위한 것이며, custom-values.yaml 수정 필요 여부가 핵심입니다.
|
||||
|
||||
## 작업
|
||||
1. 핵심 변경 사항을 평문으로 요약합니다.
|
||||
2. custom-values.yaml 수정이 필요한 항목(breaking_reasons)을 상세히 설명합니다.
|
||||
3. 신규 배포 시 참고할 주의사항(warnings)을 기록합니다.
|
||||
4. 아래 형식의 간결한 Markdown 문서를 생성합니다.
|
||||
|
||||
## 규칙
|
||||
- 입력 JSON에 없는 내용은 절대 추가하지 마세요.
|
||||
- 추측하지 마세요.
|
||||
- docs_context는 보조 설명에만 사용하고, diff에 없는 변경을 추가하지 마세요.
|
||||
- errors가 있으면 분석이 불완전할 수 있음을 명시하세요.
|
||||
- 배포 담당자가 바로 참고할 수 있도록 명확하게 작성하세요.
|
||||
|
||||
## 출력 형식
|
||||
아래 Markdown 구조를 정확히 지키세요 (`## {to_version}` 헤더는 포함하지 마세요 — `update_docs_file`이 관리):
|
||||
|
||||
### 변경 요약
|
||||
- from_version: <from_version>
|
||||
- to_version: <to_version>
|
||||
- <핵심 변경 사항 bullet points>
|
||||
|
||||
### custom-values.yaml 수정 필요 항목
|
||||
<breaking=true면 항목별 수정 방법>
|
||||
<breaking=false면 "없음">
|
||||
|
||||
### 배포 시 주의사항
|
||||
<warnings가 있으면 나열>
|
||||
<없으면 섹션 생략>
|
||||
|
||||
### 참고
|
||||
- severity: <severity>
|
||||
- breaking: <true/false>
|
||||
|
||||
---
|
||||
|
||||
Input:
|
||||
<Structured Diff JSON>
|
||||
```
|
||||
|
||||
### 2.3 토큰 예산 관리
|
||||
|
||||
대형 chart(airflow, kafka 등)는 Structured Diff JSON이 매우 클 수 있다.
|
||||
|
||||
| 전략 | 설명 |
|
||||
|------|------|
|
||||
| 중요도 기반 필터링 | breaking_reasons와 changed 항목만 포함, unchanged는 제외 |
|
||||
| template diff 요약 | 리소스별 상세 diff 대신 `변경된 리소스 목록`만 전달 |
|
||||
| 청크 분할 | values / templates / crd를 각각 별도 LLM 호출 후 결과 합산 |
|
||||
| 토큰 상한 설정 | 입력 JSON 최대 크기 제한 (예: 50,000 tokens), 초과 시 요약 버전 사용 |
|
||||
|
||||
### 2.4 출력 검증
|
||||
|
||||
- **금지 규칙**: 입력 JSON에 없는 버전/리소스를 언급하면 실패 처리.
|
||||
- **서식 검증**: Markdown 구조가 규정과 다르면 1회 재생성, 실패 시 fallback 템플릿으로 대체.
|
||||
- **요약 품질 기준**: breaking_reasons 누락/허위 서술은 오류로 간주.
|
||||
|
||||
### 2.5 예상 출력 (breaking=true)
|
||||
|
||||
> `update_docs_file`이 `## {to_version}` 헤더를 추가하므로, LLM 출력은 `###` 수준부터 시작한다.
|
||||
|
||||
```markdown
|
||||
### 변경 요약
|
||||
- from_version: 1.2.3
|
||||
- to_version: 1.3.0
|
||||
- Image tag 1.2.3 → 1.3.0 업데이트
|
||||
- CPU limit 기본값 추가 (all containers)
|
||||
- 새 환경변수 `AIRFLOW__CORE__NEW_SETTING` 추가 (scheduler)
|
||||
|
||||
### custom-values.yaml 수정 필요 항목
|
||||
- **`ingress.enabled` 키 삭제**: 차트에서 해당 key가 제거되었습니다.
|
||||
현재 custom-values.yaml에서 `ingress.enabled: true`로 설정하고 있는 경우,
|
||||
신규 방식(`ingress.create: true` 등)으로 수정이 필요합니다.
|
||||
|
||||
### 배포 시 주의사항
|
||||
- **Service port 변경**: `airflow-webserver` port 8080 → 8081.
|
||||
Ingress, load balancer 설정 확인 필요.
|
||||
|
||||
### 참고
|
||||
- severity: high
|
||||
- breaking: true
|
||||
```
|
||||
|
||||
### 2.6 예상 출력 (breaking=false)
|
||||
|
||||
> 템플릿 기반 fallback 출력 (LLM 미호출).
|
||||
|
||||
```markdown
|
||||
### 변경 요약
|
||||
- from_version: 1.2.3
|
||||
- to_version: 1.3.0
|
||||
- Chart airflow 1.2.3 → 1.3.0 업데이트
|
||||
- Values: +2 추가 / -0 삭제 / ~3 변경
|
||||
- Templates: +0 추가 / -0 삭제
|
||||
|
||||
### custom-values.yaml 수정 필요 항목
|
||||
없음
|
||||
|
||||
### 참고
|
||||
- severity: warning
|
||||
- breaking: false
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 3. Docs Updater 설계
|
||||
|
||||
### 3.1 역할
|
||||
|
||||
생성한 업그레이드 주의사항 Markdown을 해당 차트 버전의 `CUSTOM-README.md`에 반영한다.
|
||||
(`CUSTOM-README.md`는 배포에 관한 내용을 포함하는 문서로, 업그레이드 주의사항의 적합한 위치다.)
|
||||
|
||||
### 3.2 처리 방식
|
||||
|
||||
```
|
||||
1. diff/breaking 결과로 업그레이드 주의사항 생성 (breaking=true면 LLM, 아니면 템플릿)
|
||||
2. manifests/helm/<chart>/<to_version>/CUSTOM-README.md에 반영
|
||||
- "# Upgrade History" 섹션이 없으면 파일 끝에 추가
|
||||
- 해당 버전 항목이 이미 있으면 skip (idempotent)
|
||||
3. 파일 저장
|
||||
```
|
||||
|
||||
### 3.3 파일 구조 규칙
|
||||
|
||||
- 각 차트 버전 디렉토리의 `CUSTOM-README.md`에 업그레이드 주의사항을 추가한다.
|
||||
- `CUSTOM-README.md`는 `chart_updater`가 이전 버전에서 carry-over하므로 기존 배포 내용은 유지된다.
|
||||
- `BUILD-README.md`는 차트 메타 정보(repo, 설치 명령어 등)를 유지한다.
|
||||
- 별도의 `docs/upgrade.md`는 생성하지 않는다.
|
||||
|
||||
### 3.4 중복 방지
|
||||
|
||||
이미 해당 버전 업그레이드 섹션이 존재하면 덮어쓰기 또는 스킵한다 (설정으로 제어).
|
||||
|
||||
---
|
||||
|
||||
## 4. Git PR Bot 설계
|
||||
|
||||
### 4.1 자동화 단계
|
||||
|
||||
```
|
||||
1. 새 branch 생성: update-{chart}/{to_version}
|
||||
2. 카탈로그 신규 버전 디렉토리 커밋 (manifests/helm/<chart>/<to_version>/)
|
||||
3. CUSTOM-README.md 업그레이드 주의사항 섹션 포함
|
||||
4. git commit
|
||||
5. PR 생성
|
||||
```
|
||||
|
||||
### 4.2 PR 메타데이터
|
||||
|
||||
**PR 제목**:
|
||||
```
|
||||
update {chart}: {from_version} → {to_version}
|
||||
```
|
||||
|
||||
**PR labels**:
|
||||
- `needs-review` (breaking=true 시) — 담당자 확인 권장
|
||||
- `auto-update` (breaking=false 시) — 자동 업데이트, 검토 선택적
|
||||
|
||||
**PR description**:
|
||||
```markdown
|
||||
## Helm Chart Update: {chart} `{from_version}` → `{to_version}`
|
||||
|
||||
**Severity**: `high`
|
||||
**Breaking**: ✅ custom-values.yaml 수정 필요 (담당자 확인 권장)
|
||||
|
||||
### Breaking Changes
|
||||
- `[values_key_removed]` ingress.enabled — custom-values.yaml에서 사용 중인 key 삭제
|
||||
|
||||
### Warnings
|
||||
- `[service_port_changed]` Service/airflow-webserver — port 8080 → 8081
|
||||
|
||||
---
|
||||
*Generated by update-catalog automation*
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 5. 관련 문서
|
||||
|
||||
- [02-breaking-change-rules.md](02-breaking-change-rules.md) — Breaking Change 입력 생성
|
||||
- [04-skill-interface.md](04-skill-interface.md) — `generate_upgrade_doc`, `create_pr` Skill
|
||||
@@ -0,0 +1,242 @@
|
||||
# Skill 인터페이스 정의
|
||||
|
||||
## 1. 개요
|
||||
|
||||
각 컴포넌트를 **OpenClaw Skill**로 노출한다.
|
||||
이 인터페이스는 Skills(Step 1)와 On-Cluster Agent(Step 2~3) 간의 **계약(contract)**이다.
|
||||
|
||||
> Agent(OpenClaw/Nanobot)가 이 Skill들을 워크플로로 호출한다.
|
||||
|
||||
---
|
||||
|
||||
## 2. Skill 목록
|
||||
|
||||
| Skill 이름 | 역할 | 해당 컴포넌트 |
|
||||
|-----------|------|-------------|
|
||||
| `helm_diff` | 두 버전 간 Structured Diff JSON 생성 | Helm Diff Engine |
|
||||
| `breaking_change_check` | Diff JSON에서 Breaking Change 판단 | Breaking Change Rule Engine |
|
||||
| `generate_upgrade_doc` | 업그레이드 주의사항 Markdown 문서 생성 (항상 실행) | LLM Summarizer |
|
||||
| `update_docs_file` | CUSTOM-README.md에 업그레이드 주의사항 섹션 추가 | Docs Updater |
|
||||
| `create_pr` | GitHub PR 생성 | Git PR Bot |
|
||||
| `deploy_validate` | test namespace에 배포 후 health 검증 **(Phase 2, 미구현)** | Deploy Validator |
|
||||
|
||||
---
|
||||
|
||||
## 3. Skill 상세 정의
|
||||
|
||||
## 2.1 공통 에러 스키마
|
||||
|
||||
모든 Skill은 실패 시 아래 형식으로 에러를 반환한다.
|
||||
|
||||
```json
|
||||
{
|
||||
"error": {
|
||||
"code": "ERR_HELM_PULL" ,
|
||||
"message": "helm pull failed",
|
||||
"retryable": true,
|
||||
"details": { "exit_code": 1 }
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
- `retryable=true`인 경우에만 자동 재시도를 수행한다.
|
||||
|
||||
## 2.2 Idempotency / Retry 정책
|
||||
|
||||
- **read-only Skill**(helm_diff, breaking_change_check, generate_upgrade_doc)는 안전 재시도 가능.
|
||||
- **side-effect Skill**(update_docs_file, create_pr, deploy_validate)은 idempotency key를 사용한다.
|
||||
- `create_pr`는 동일 key 요청 시 기존 PR URL을 반환해야 한다.
|
||||
|
||||
## 2.3 Auth/Secret 전달
|
||||
|
||||
- 토큰/시크릿은 **env var 또는 K8s Secret**으로 주입한다.
|
||||
- 입력 payload에 직접 포함하지 않는다.
|
||||
|
||||
### 3.1 `helm_diff`
|
||||
|
||||
```yaml
|
||||
name: helm_diff
|
||||
description: >
|
||||
두 버전의 Helm Chart를 비교하여 Structured Diff JSON을 생성한다.
|
||||
values, templates, CRD, dependencies 변경사항을 포함한다.
|
||||
|
||||
input:
|
||||
chart: string # 차트 이름 (예: "airflow")
|
||||
repo: string # Helm repo 이름 또는 URL (repo 기반일 때만)
|
||||
chart_path: string # 로컬 차트 경로 (dip-catalog 구조)
|
||||
from_version: string # 기존 버전 (예: "1.2.3")
|
||||
to_version: string # 신규 버전 (예: "1.3.0")
|
||||
values_override: object # 사용자 정의 values (선택, dip-catalog은 custom-values.yaml 기본)
|
||||
|
||||
output:
|
||||
chart: string
|
||||
from_version: string
|
||||
to_version: string
|
||||
generated_at: string # ISO 8601 timestamp
|
||||
values: object # Values Diff
|
||||
templates: object # Template Diff
|
||||
crd: object # CRD Diff
|
||||
dependencies: object # Dependency Diff
|
||||
errors: array # 부분 실패 정보
|
||||
```
|
||||
|
||||
### 3.2 `breaking_change_check`
|
||||
|
||||
```yaml
|
||||
name: breaking_change_check
|
||||
description: >
|
||||
Structured Diff JSON을 입력받아 Breaking Change 여부를 코드 기반으로 판단한다.
|
||||
LLM을 사용하지 않으며 결과는 완전히 deterministic하다.
|
||||
|
||||
input:
|
||||
diff_json: object # helm_diff 출력 (Structured Diff JSON)
|
||||
|
||||
output:
|
||||
breaking: boolean
|
||||
severity: string # critical / high / medium / warning
|
||||
reasons: array # Breaking 사유 목록
|
||||
warnings: array # 비중단 경고 목록
|
||||
```
|
||||
|
||||
### 3.3 `generate_upgrade_doc`
|
||||
|
||||
```yaml
|
||||
name: generate_upgrade_doc
|
||||
description: >
|
||||
Structured Diff JSON과 Breaking Change 결과를 기반으로 업그레이드 주의사항 Markdown을 생성한다.
|
||||
항상 실행된다. breaking=true면 LLM 상세 가이드, breaking=false면 템플릿 기반 간단 요약.
|
||||
|
||||
input:
|
||||
diff_json: object # helm_diff 출력
|
||||
breaking_result: object # breaking_change_check 출력
|
||||
docs_context: object # CUSTOM-README.md 내용 (dip-catalog)
|
||||
max_tokens: integer # LLM 입력 최대 토큰 수 (기본: 50000)
|
||||
|
||||
output:
|
||||
markdown: string # 생성된 Markdown 문서
|
||||
truncated: boolean # 토큰 제한으로 입력이 잘렸는지 여부
|
||||
```
|
||||
|
||||
### 3.4 `update_docs_file`
|
||||
|
||||
```yaml
|
||||
name: update_docs_file
|
||||
description: >
|
||||
CUSTOM-README.md에 업그레이드 주의사항 섹션을 추가한다.
|
||||
CUSTOM-README.md는 배포 관련 정보를 담는 문서로, 업그레이드 주의사항의 적합한 위치다.
|
||||
BUILD-README.md는 chart_updater의 carry-over로만 관리된다.
|
||||
|
||||
input:
|
||||
repo_path: string # 로컬 Git 저장소 경로
|
||||
docs_file: string # 문서 파일 경로 (예: "manifests/helm/<chart>/<version>/CUSTOM-README.md")
|
||||
version: string # 삽입할 버전 표기 (예: "1.2.3 → 1.3.0")
|
||||
content: string # 삽입할 Markdown 내용
|
||||
overwrite: boolean # 기존 버전 섹션 덮어쓰기 여부 (기본: false)
|
||||
|
||||
output:
|
||||
success: boolean
|
||||
file_path: string
|
||||
already_existed: boolean
|
||||
```
|
||||
|
||||
### 3.5 `create_pr`
|
||||
|
||||
```yaml
|
||||
name: create_pr
|
||||
description: >
|
||||
Helm Chart 업그레이드를 위한 GitHub PR을 생성한다.
|
||||
branch 생성, commit, PR 생성을 포함한다.
|
||||
|
||||
input:
|
||||
chart: string # 차트 이름
|
||||
from_version: string
|
||||
to_version: string
|
||||
repo_path: string # 로컬 Git 저장소 경로
|
||||
doc_content: string # upgrade.md에 삽입할 내용
|
||||
breaking: boolean # PR label 결정에 사용
|
||||
severity: string # PR label 결정에 사용
|
||||
|
||||
output:
|
||||
pr_url: string
|
||||
branch_name: string
|
||||
labels: array
|
||||
```
|
||||
|
||||
### 3.6 `deploy_validate` (Phase 2A+)
|
||||
|
||||
```yaml
|
||||
name: deploy_validate
|
||||
description: >
|
||||
Ephemeral test namespace에 Helm Chart를 배포하고 health를 검증한다.
|
||||
성공/실패 결과와 Pod 상태를 반환한다.
|
||||
|
||||
input:
|
||||
chart: string
|
||||
repo: string
|
||||
version: string
|
||||
values_override: object
|
||||
namespace: string # test namespace (예: "helm-test-airflow")
|
||||
timeout: integer # 초 단위, 기본 300
|
||||
|
||||
output:
|
||||
success: boolean
|
||||
dry_run_passed: boolean
|
||||
pod_status: object # { running: int, pending: int, failed: int }
|
||||
events: array # 비정상 K8s events
|
||||
logs: string # 실패 시 관련 Pod 로그
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 4. Agent 워크플로 호출 순서
|
||||
|
||||
Agent(OpenClaw/Nanobot)가 Skill들을 등록하고, 아래 순서를 워크플로로 정의한다.
|
||||
|
||||
```yaml
|
||||
# 개념적 호출 순서 (실제 워크플로 정의는 implementation/02-agent.md 참고)
|
||||
1. helm_diff(chart, repo, from_version, to_version)
|
||||
↓
|
||||
2. breaking_change_check(diff_json, custom_values) # custom-values.yaml 기준 판단
|
||||
↓
|
||||
3. generate_upgrade_doc(diff_json, breaking_result) # 항상 실행
|
||||
│ breaking=true → LLM 상세 가이드 생성
|
||||
│ breaking=false → 템플릿 기반 간단 요약
|
||||
↓
|
||||
4. update_docs_file(
|
||||
repo_path,
|
||||
docs_file="manifests/helm/<chart>/<to_version>/CUSTOM-README.md", # to_version으로 경로 결정
|
||||
version="<from_version> → <to_version>",
|
||||
content=<markdown>
|
||||
) # 항상 실행
|
||||
↓
|
||||
5. create_pr(chart, from_version, to_version, ...) # 항상 실행
|
||||
│ breaking=true → label: needs-review
|
||||
│ breaking=false → label: auto-update
|
||||
↓ exit 0 (항상)
|
||||
|
||||
# Phase 2 (미구현):
|
||||
6. deploy_validate(chart, repo, to_version, namespace)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 5. 버전 관리
|
||||
|
||||
이 인터페이스는 **명시적 버전**을 관리한다.
|
||||
|
||||
```yaml
|
||||
skill_interface_version: "1.0"
|
||||
```
|
||||
|
||||
Skill 입출력 변경 시:
|
||||
- **하위 호환 변경** (필드 추가): 마이너 버전 증가
|
||||
- **Breaking 변경** (필드 삭제/타입 변경): 메이저 버전 증가 + 마이그레이션 가이드 작성
|
||||
|
||||
---
|
||||
|
||||
## 6. 관련 문서
|
||||
|
||||
- [01-helm-diff-engine.md](01-helm-diff-engine.md) — `helm_diff` 구현 설계
|
||||
- [02-breaking-change-rules.md](02-breaking-change-rules.md) — `breaking_change_check` 구현 설계
|
||||
- [03-llm-summarizer.md](03-llm-summarizer.md) — `generate_upgrade_doc`, `create_pr` 구현 설계
|
||||
- [05-on-cluster-agent.md](05-on-cluster-agent.md) — Agent가 이 인터페이스를 Skills로 사용하는 방법
|
||||
@@ -0,0 +1,189 @@
|
||||
# On-Cluster AI Agent 설계 (Step 2~3)
|
||||
|
||||
## 1. 개요
|
||||
|
||||
Skills(Step 1)를 **클러스터 위에서 상시 동작하는 자율 에이전트**로 오케스트레이션한다.
|
||||
OpenClaw 또는 Nanobot을 오케스트레이터로 삼아, Step 1에서 구현한 Skill들을 등록하여 Helm 업그레이드 자동화 전체를 수행한다.
|
||||
|
||||
> **전제**: Skills(Step 1) 구현 완료 + 인터페이스 버전 `1.0` 확정 이후 진행.
|
||||
|
||||
---
|
||||
|
||||
## 2. 아키텍처
|
||||
|
||||
```
|
||||
[OpenClaw / Nanobot on K8s]
|
||||
│
|
||||
├── Skill: helm_diff → Structured Diff JSON 생성
|
||||
├── Skill: breaking_check → Breaking Change 판단
|
||||
├── Skill: generate_doc → 업그레이드 주의사항 문서 생성 (항상 실행)
|
||||
├── Skill: update_docs → CUSTOM-README.md 업그레이드 주의사항 섹션 추가
|
||||
├── Skill: create_pr → GitHub PR 생성
|
||||
# deploy_validate: Phase 2 예정
|
||||
├── Skill: k8s_event_watch → 클러스터 이벤트 감지
|
||||
└── Channel: Slack / Telegram → 알림 발송
|
||||
```
|
||||
|
||||
트리거:
|
||||
- Cron 스케줄 (신규 chart 버전 주기 감지)
|
||||
- K8s Event Watch (ArgoCD App 상태 변화 등)
|
||||
|
||||
---
|
||||
|
||||
## 3. OpenClaw vs Nanobot
|
||||
|
||||
| 항목 | OpenClaw | Nanobot |
|
||||
|------|---------|---------|
|
||||
| 코드 규모 | 430K+ lines | ~4,000 lines |
|
||||
| 성숙도 | 높음 (100K+ GitHub stars) | 낮음 (신생) |
|
||||
| Skills 생태계 | 풍부 (ClawHub) | 기본 지원 |
|
||||
| K8s 배포 | 공식 Helm chart + K8s Operator | 직접 구성 필요 |
|
||||
| 수평 확장 | 불가 (Recreate 전략) | 미정 |
|
||||
| LLM 지원 | Claude, OpenAI, 로컬 모델 | Claude, OpenAI, Qwen 등 |
|
||||
| 커스터마이징 | TypeScript / YAML 워크플로 | 코드 직접 수정 용이 |
|
||||
| 보안 이슈 | 커뮤니티 이슈 있음 (Cisco, Palo Alto 조사) | 미검증 |
|
||||
|
||||
**권장**:
|
||||
- 운영 안정성 우선 → **OpenClaw** (K8s Operator, 성숙한 생태계)
|
||||
- 경량 커스터마이징 우선 → **Nanobot** (코드 소규모, 직접 수정)
|
||||
|
||||
---
|
||||
|
||||
## 4. Skills → Agent 연결 전략
|
||||
|
||||
Step 1에서 Skill 인터페이스를 표준으로 구현해두면 Agent 연결이 매끄럽다.
|
||||
|
||||
```
|
||||
Step 1 (Skills) Step 2~3 (Agent)
|
||||
───────────────────────────── ─────────────────────────────
|
||||
helm_diff, breaking_check 등 OpenClaw/Nanobot Agent가
|
||||
Skill로 구현 완료 → 동일한 Skill들을 등록 후
|
||||
워크플로로 오케스트레이션
|
||||
```
|
||||
|
||||
Agent 연결 시 추가되는 부분:
|
||||
- 실행 환경: K8s Pod (Agent)
|
||||
- 오케스트레이션: Agent 워크플로 정의 (Cron 스케줄 + 조건 분기)
|
||||
- 스케줄링: Agent 내장 스케줄러
|
||||
|
||||
변경되지 않는 부분:
|
||||
- Skill 구현체 (helm_diff, breaking_check 등)
|
||||
- Structured Diff JSON 포맷
|
||||
- Breaking Change 규칙
|
||||
|
||||
---
|
||||
|
||||
## 5. 보안 고려사항
|
||||
|
||||
## 4.1 운영 정책
|
||||
|
||||
- `breaking=true` PR에는 `needs-review` 레이블을 부착한다. 담당자가 `custom-values.yaml` 수정 후 merge 여부를 판단한다.
|
||||
- `breaking=false` PR은 `auto-update` 레이블을 부착하며, 자동 merge가 가능하다.
|
||||
- Agent는 PR 생성까지만 수행한다. merge 책임은 담당자에게 있다.
|
||||
|
||||
## 4.2 실패 처리
|
||||
|
||||
- Skill 실패 시: 알림 전송 + 자동 중단. 재시도는 최대 3회.
|
||||
- `deploy_validate`는 Phase 2에서 구현 예정 (현재 스코프 밖).
|
||||
|
||||
## 4.3 관찰성
|
||||
|
||||
- 모든 Skill 호출은 audit log에 남긴다 (input hash + output status).
|
||||
- Prometheus metrics: 성공/실패 카운트, 평균 처리 시간, 재시도 횟수.
|
||||
- LLM 호출은 request_id를 부여하여 추적 가능해야 한다.
|
||||
|
||||
On-Cluster AI Agent는 구조적 위험이 있다.
|
||||
|
||||
| 위험 | 내용 | 대응 |
|
||||
|------|------|------|
|
||||
| 과도한 K8s 권한 | helm upgrade 권한 남용 | RBAC: test namespace만 허용, ServiceAccount 최소 권한 |
|
||||
| Skill 취약점 | 3rd-party Skill의 26%가 취약 (Cisco 조사) | 허용 Skill allowlist 관리, ClawHub Skill 검토 필수 |
|
||||
| Prompt Injection | PR comment, webhook 등 외부 콘텐츠로 에이전트 조작 | 입력 sanitization, 신뢰 범위(trust boundary) 명확화 |
|
||||
| 외부 통신 데이터 유출 | GitHub API, Slack 등 외부 전송 | NetworkPolicy: 허용 egress 목록 명시, 민감 데이터 마스킹 |
|
||||
| Shell 접근 | RCE 가능성 | shell skill 비활성화, read-only root filesystem, UID 1000 |
|
||||
|
||||
> Palo Alto Networks 평가: "Shell 접근 + 개인 데이터 + 외부 통신" = **"lethal trifecta"**
|
||||
|
||||
### 최소 보안 요구사항 (운영 투입 전 필수)
|
||||
|
||||
```yaml
|
||||
# RBAC 예시: test namespace만 허용
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: Role
|
||||
metadata:
|
||||
namespace: helm-test
|
||||
rules:
|
||||
- apiGroups: ["apps"]
|
||||
resources: ["deployments", "statefulsets"]
|
||||
verbs: ["get", "list", "create", "update", "delete"]
|
||||
- apiGroups: [""]
|
||||
resources: ["pods", "services", "configmaps"]
|
||||
verbs: ["get", "list", "create", "update", "delete"]
|
||||
```
|
||||
|
||||
```yaml
|
||||
# NetworkPolicy: 허용 egress만 통과
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: NetworkPolicy
|
||||
metadata:
|
||||
name: agent-egress-policy
|
||||
spec:
|
||||
podSelector:
|
||||
matchLabels:
|
||||
app: helm-upgrade-agent
|
||||
policyTypes: ["Egress"]
|
||||
egress:
|
||||
- to: # GitHub API
|
||||
- ipBlock:
|
||||
cidr: 140.82.112.0/20
|
||||
- to: # Slack API
|
||||
- ipBlock:
|
||||
cidr: 35.190.0.0/16
|
||||
- ports:
|
||||
- port: 443
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 6. K8s 배포 구성
|
||||
|
||||
```yaml
|
||||
# OpenClaw Helm values 예시
|
||||
image:
|
||||
tag: latest
|
||||
|
||||
skills:
|
||||
allowlist:
|
||||
- helm_diff
|
||||
- breaking_change_check
|
||||
- generate_upgrade_doc
|
||||
- update_docs_file
|
||||
- create_pr
|
||||
# deploy_validate: Phase 2에서 추가 예정
|
||||
|
||||
securityContext:
|
||||
runAsNonRoot: true
|
||||
runAsUser: 1000
|
||||
readOnlyRootFilesystem: true
|
||||
|
||||
resources:
|
||||
limits:
|
||||
memory: "1Gi"
|
||||
cpu: "500m"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 7. 도입 순서 권장
|
||||
|
||||
1. Staging 클러스터에서 먼저 검증
|
||||
2. 보안 정책 확립 (RBAC, NetworkPolicy, Skill allowlist)
|
||||
3. Skill을 하나씩 추가하며 동작 확인
|
||||
4. 운영 클러스터 투입 시 `breaking=true` PR은 사람이 직접 머지 승인 유지
|
||||
|
||||
---
|
||||
|
||||
## 8. 관련 문서
|
||||
|
||||
- [04-skill-interface.md](04-skill-interface.md) — Agent가 호출하는 Skill 인터페이스
|
||||
- [../implementation/02-agent.md](../implementation/02-agent.md) — Agent 구현 계획 (Step 2~4)
|
||||
Reference in New Issue
Block a user