From 427ed307e12ca2039f5eec31a7ed941f110938f5 Mon Sep 17 00:00:00 2001 From: kappa Date: Mon, 13 Apr 2026 16:15:51 +0900 Subject: [PATCH] Add Helm charts management and ESO documentation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - infra/helm-charts.md: 전체 Helm 관리 체계, 차트 구조, ArgoCD 앱 목록, 배포 워크플로우 - infra/external-secrets.md: ESO 구성, ExternalSecret 목록, Vault 경로 정리, 운영 가이드 --- infra/external-secrets.md | 106 +++++++++++++++++++++++++++ infra/helm-charts.md | 147 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 253 insertions(+) create mode 100644 infra/external-secrets.md create mode 100644 infra/helm-charts.md diff --git a/infra/external-secrets.md b/infra/external-secrets.md new file mode 100644 index 0000000..2d76120 --- /dev/null +++ b/infra/external-secrets.md @@ -0,0 +1,106 @@ +--- +title: External Secrets Operator (ESO) +updated: 2026-04-13 +tags: [infra, k3s, vault, eso, secrets] +--- + +## 개요 + +HashiCorp Vault의 시크릿을 K8s Secret으로 자동 동기화. Vault가 단일 진실 소스(Single Source of Truth). + +## 구성 요소 + +| 항목 | 값 | +|------|-----| +| 설치 방식 | Helm (external-secrets/external-secrets) | +| 네임스페이스 | external-secrets | +| 버전 | v2.3.0 | +| ClusterSecretStore | `vault` | +| Vault 주소 | `http://10.253.101.58:8200` (K3s 내부 직접 접근) | +| Vault 인증 | Token (Secret `vault-token` in external-secrets ns) | +| KV 엔진 | v2 | +| refresh 주기 | 1시간 | + +### Vault 접근 경로 + +ESO는 K3s Pod에서 Vault에 접근해야 하므로 CDN URL(`hcv.inouter.com`)이 아닌 **내부 IP 직접 접근** 사용. +- Vault 위치: incus-jp1 `vault` 컨테이너 (10.253.101.58) +- `hcv.inouter.com`은 BunnyCDN을 거치며 API 경로가 404 반환 → ESO 사용 불가 + +## ExternalSecret 목록 + +| ExternalSecret | 네임스페이스 | K8s Secret 이름 | Vault 경로 | 키 매핑 | +|---|---|---|---|---| +| smtp-relay-mailgun | mail | smtp-relay-mailgun | `messaging/mailgun/smtp` | username, password | +| bunnycdn-secrets | mcp | bunnycdn-secrets | `cloud/bunnycdn` | api_key → api-key | +| outline-secrets | outline | outline-secrets | `apps/outline` | dataFrom extract (전체 키) | +| openmemory-secrets | openmemory | openmemory-secrets | `ai/openai` | API_KEY → OPENAI_API_KEY | +| cfb-ssh-key | tools | cfb-ssh-key | `apps/cfb-manager` | ssh_key → id_rsa | +| namecheap-api-env | tools | namecheap-api-env | `domain/namecheap` | API_KEY, API_USER, CLIENT_IP, USERNAME, SANDBOX | + +## ESO로 관리하지 않는 Secret + +| Secret | 네임스페이스 | 이유 | +|--------|-------------|------| +| searxng-ca-bundle | searxng | 270KB CA 인증서, Vault 부적합. ArgoCD prune 제외 어노테이션 적용 | +| searxng-config | searxng | Helm 차트 values에서 생성 | + +## Vault 시크릿 경로 정리 + +``` +secret/ +├── ai/ +│ └── openai # OPENAI_API_KEY (openmemory 등) +├── apps/ +│ ├── outline # DB URL, OIDC, SECRET_KEY 등 11개 키 +│ ├── cfb-manager # ssh_key +│ ├── portainer # api_token, google_client_id/secret +│ └── gitea # api_token 등 +├── cloud/ +│ └── bunnycdn # api_key +├── domain/ +│ └── namecheap # API_KEY, API_USER, CLIENT_IP, USERNAME, SANDBOX +├── messaging/ +│ └── mailgun/smtp # username, password, host, port 등 +└── infra/ + └── ... # SSH 키, Tailscale 등 +``` + +## 운영 가이드 + +### 새 시크릿 추가 절차 + +1. Vault에 시크릿 저장: `vault kv put -mount=secret key=value` +2. ExternalSecret 매니페스트 작성 및 적용 +3. `kubectl get externalsecret -A` 로 SecretSynced 확인 +4. Pod에서 참조 확인 + +### Vault 토큰 갱신 + +ESO가 사용하는 토큰은 `external-secrets/vault-token` Secret에 저장. +토큰 만료 시: +``` +vault token create -policy=default -ttl=768h +kubectl -n external-secrets create secret generic vault-token --from-literal=token= --dry-run=client -o yaml | kubectl apply -f - +``` + +### 트러블슈팅 + +```bash +# ExternalSecret 상태 확인 +kubectl get externalsecret -A + +# 상세 에러 확인 +kubectl get externalsecret -n -o jsonpath='{.status.conditions}' + +# 강제 재동기화 +kubectl annotate externalsecret -n force-sync=$(date +%s) --overwrite + +# ClusterSecretStore 상태 +kubectl get clustersecretstore vault +``` + +## 관련 문서 + +- [[helm-charts]] — Helm 차트 관리 체계 +- [[k3s-ingress-architecture]] — 인그레스 구조 diff --git a/infra/helm-charts.md b/infra/helm-charts.md new file mode 100644 index 0000000..d122032 --- /dev/null +++ b/infra/helm-charts.md @@ -0,0 +1,147 @@ +--- +title: Helm 차트 관리 체계 +updated: 2026-04-13 +tags: [infra, k3s, helm, argocd, gitops] +--- + +## 개요 + +K3s 클러스터의 모든 서비스를 Helm으로 관리. 자체 차트는 Gitea에 호스팅하고 ArgoCD로 GitOps 배포. + +## 차트 저장소 + +| 항목 | 값 | +|------|-----| +| Git 레포 | `gitea.inouter.com/kaffa/helm-charts` (private) | +| Helm 레지스트리 | `gitea.inouter.com/api/packages/kaffa/helm` | +| ArgoCD 레포 시크릿 | `repo-helm-charts` (argocd 네임스페이스) | + +### BunnyCDN 캐시 바이패스 + +`iron-git` Pull Zone (ID 5584382)에 Edge Rule 적용: +- 패턴: `*/api/packages/*` +- ActionType: 3 (OverrideCacheTime), 값: 0 +- 차트 업로드 후 index.yaml 캐시 문제 방지 + +## 자체 차트 구조 + +``` +helm-charts/ +├── charts/ +│ ├── app/ # 범용 차트 (v0.4.0) — 단순 서비스용 +│ ├── kroki/ # 전용 차트 — Kroki + Mermaid +│ ├── searxng/ # 전용 차트 — SearXNG + UA 패치 + TLS proxy CA +│ ├── outline/ # 전용 차트 — Outline Wiki + Redis +│ └── openmemory/ # 전용 차트 — MCP + UI + Qdrant +└── values/ # app 차트용 서비스별 values + ├── juiceshop.yaml + ├── cfb-manager.yaml + ├── bunnycdn-mcp.yaml + ├── smtp-relay.yaml + ├── namecheap-api.yaml + ├── vultr-api.yaml + ├── pgcat.yaml # sidecar(monitor) 포함 + ├── proxysql.yaml # Galera 설정 포함 + ├── nas-proxy.yaml # external service (Synology NAS) + └── vault-mcp.yaml # external service (Vault) + extraIngressRoutes +``` + +### app 차트 기능 (v0.4.0) + +- Deployment + Service + IngressRoute 기본 구성 +- `sidecars` — 사이드카 컨테이너 지원 +- `configMaps` — multiline ConfigMap 생성 +- `secrets` — Secret 생성 +- `external` — selector 없는 Service + EndpointSlice (외부 서비스 프록시) +- `extraIngressRoutes` — 복수 도메인 IngressRoute +- `probes` — liveness/readiness probe + +## 전체 Helm 릴리스 목록 + +### 공식/외부 차트 (20개) + +| 릴리스 | 네임스페이스 | 차트 | +|--------|-------------|------| +| apisix | apisix | apisix | +| apisix-ingress-controller | apisix | apisix-ingress-controller | +| argocd | argocd | argo-cd | +| cert-manager | cert-manager | cert-manager | +| external-secrets | external-secrets | external-secrets | +| gitea | gitea | gitea | +| longhorn | longhorn-system | longhorn | +| metallb | metallb-system | metallb | +| n8n | n8n | n8n | +| nfs-provisioner | nfs-provisioner | nfs-subdir-external-provisioner | +| nocodb | tools | zekker6/nocodb | +| portainer | portainer | portainer | +| reflector | kube-system | reflector | +| safeline | safeline | safeline | +| sftpgo | sftpgo | sftpgo | +| sshpiper | sshpiper | sshpiper | +| synology-iscsi | democratic-csi | democratic-csi | +| teleport-cluster | teleport | teleport-cluster | +| traefik | kube-system | traefik | +| vector | logging | vector | +| vlogs | logging | victoria-logs-single | +| vm-stack | monitoring | victoria-metrics-k8s-stack | + +### 자체 app 차트 (10개, ArgoCD 관리) + +| 릴리스 | 네임스페이스 | 비고 | +|--------|-------------|------| +| juiceshop | juiceshop | | +| cfb-manager | tools | SSH key 마운트 | +| bunnycdn-mcp | mcp | IngressRoute: bunny.inouter.com | +| smtp-relay | mail | Mailgun relay | +| namecheap-api | api | | +| vultr-api | api | | +| pgcat | db | monitor sidecar 포함 | +| proxysql | db | Galera hostgroup 설정 | +| nas-proxy | tools | external → 192.168.9.100:5000 | +| vault-mcp | tools | external → 10.253.101.58, hcv.inouter.com + vault-mcp.inouter.com | + +### 전용 차트 (4개, ArgoCD 관리) + +| 릴리스 | 네임스페이스 | 구성 | +|--------|-------------|------| +| kroki | kroki | kroki + mermaid sidecar | +| searxng | searxng | UA 패치, TLS proxy CA, Google proxy | +| outline | outline | outline + redis + PVC + IngressRoute | +| openmemory | openmemory | MCP + UI + Qdrant + PVC 2개 | + +### Operator 관리 (ArgoCD/Helm 외) + +| 서비스 | 네임스페이스 | 관리 방식 | +|--------|-------------|-----------| +| rabbitmq-cluster-operator | rabbitmq-system | 직접 매니페스트 | +| rabbitmq-server | mq | RabbitmqCluster CRD → Operator | + +## ArgoCD 앱 목록 + +14개 Application, 모두 `automated + prune + selfHeal`: + +``` +juiceshop, cfb-manager, bunnycdn-mcp, smtp-relay, namecheap-api, vultr-api, +pgcat, proxysql, nas-proxy, vault-mcp, kroki, searxng, outline, openmemory +``` + +### 주의사항 + +- **EndpointSlice는 ArgoCD 제외 대상** — `discovery.k8s.io` 그룹이 argocd-cm에서 제외됨. external service의 EndpointSlice는 수동 관리 필요 +- ArgoCD 앱 소스는 Gitea `helm-charts` 레포의 `charts/` 경로 참조 + +## 배포 워크플로우 + +``` +1. charts/ 또는 values/ 수정 +2. helm template 로 렌더링 확인 +3. git push → Gitea helm-charts +4. ArgoCD 자동 sync (또는 hard refresh) +5. 동작 확인 +``` + +## 관련 문서 + +- [[external-secrets]] — ESO + Vault 시크릿 동기화 +- [[k3s-ingress-architecture]] — Traefik/APISIX 인그레스 구조 +- [[cert-manager]] — TLS 인증서