Files
obsidian/ops-agents/overview.md

148 lines
7.9 KiB
Markdown

---
title: 내부 운영 에이전트 (Ops Agents)
updated: 2026-04-09
tags: [agent, ops, claude-code]
---
<!-- 2026-04-09: heimdall tofu 재생성. 유저 root→kaffa, project default→ops, IP 10.100.3.92→10.100.3.108 -->
kappa가 혼자 쓰는 **내부 인프라·운영 자동화 Claude Code 에이전트** 집합. 고객 대상 OpenClaw 에이전트(jp1 `agents` 프로젝트, anvil/stamp/flux 등)와는 완전히 분리된 영역. 외부 클라우드 BM 프로비저닝(jp1 `infra-tool` 의 Tofu API)과도 무관.
**명명 규칙**: 북유럽 신화 (Heimdall = 파수꾼, Syn = 문지기, …). OpenClaw 쪽은 대장간/중세 기능 네이밍(anvil/forge/smelt/stamp/…)이라 자연스럽게 분리됨.
## 에이전트 목록
| 이름 | 호스트 | Incus 프로젝트 | IP | 역할 | 비고 |
|------|--------|---------------|-----|------|------|
| **[[heimdall]]** | kr1 | `ops` | 10.100.3.108 | 인프라 전반 (K3s, Incus, Longhorn, 스토리지, 네트워크, 일반 서비스) | 2026-04-09 tofu 재생성 (`kaffa/ops-agents-tofu/heimdall`) |
| **[[syn]]** | hp2 | `ops` | 10.100.2.173 | 엣지 레이어 전담 (BunnyCDN, SafeLine WAF, APISIX, Cloudflare 엣지) | 2026-04-09 신규, tofu 관리 (`kaffa/ops-agents-tofu/syn`) |
## 공통 원칙
### 통신 프로토콜 (ssh + tmux send-keys 체인)
모든 내부 에이전트는 **한 줄 태그 포맷**으로 서로와 kappa에 신호 전송:
| 태그 | 의미 |
|------|------|
| `[SYN DONE] ...` | 작업 완료 |
| `[SYN FAIL] ...` | 실패 (원인 한 줄) |
| `[SYN ASK] ...` | 결정/입력 필요 |
| `[SYN PROGRESS] ...` | 중간 이정표 (드물게) |
| `[SYN→HEIMDALL] ...` | 피어 투 피어 |
| `[HEIMDALL→SYN] ...` | 역방향 |
| `[SYN CC] ...` / `[HEIMDALL CC] ...` | 피어 대화를 kappa 에 CC |
핵심 규칙: **한 줄만**. 상세는 자기 tmux 창 또는 Outline `agent-qna` 문서에 남기고, 신호에는 포인터만.
### 통신 경로
- **kappa Mac → Syn**: `tmux send-keys -t 0:0 '...' Enter` (window 0 이 syn-login, ssh 체인 유지)
- **kappa Mac → Heimdall**: `ssh kaffa@10.100.3.108 'tmux send-keys -t heimdall ...'`
- **Syn → kappa Mac**: `ssh kaffa@100.106.245.27 '/opt/homebrew/bin/tmux send-keys -t 0:1 ...'`
- **Syn → Heimdall**: `ssh kaffa@10.100.3.108 'tmux send-keys -t heimdall ...'`
- **Heimdall → Syn**: `ssh kaffa@100.106.245.27 '/opt/homebrew/bin/tmux send-keys -t 0:0 ...'` (경유 필요)
Syn 컨테이너는 hp2 subnet routing 덕분에 **Tailscale 설치 없이** tailnet의 다른 노드(kappa Mac 100.106.245.27, heimdall 10.100.3.92 등)에 직접 reachable. 호스트의 tailscale0 interface가 container bridge 로 투명하게 열려있음 — 2026-04-09 실측 확인.
## 역할 분담 원칙
**Heimdall 전담 (Syn 손대지 말 것)**:
- K3s 클러스터 전반 (노드, Longhorn, 일반 워크로드)
- Incus 호스트 관리
- 스토리지, 네트워크 (Tailscale/OpenWrt/HAProxy)
- 일반 서비스 파드 (Outline/Gitea/Vault 본체 등)
- Obsidian 정본 전체 쓰기 권한
**Syn 전담 (Heimdall 손대지 말 것)**:
- BunnyCDN: 풀존, 엣지 스크립트(MiddlewareScriptId 64811 `crowdsec-bouncer-middleware` 포함), Shield/WAF, 캐시 정책
- SafeLine WAF: K3s `safeline` ns, Traefik middleware, 탐지 규칙, APISIX 통합
- APISIX: 모든 인스턴스 (K3s 서울 / osaka-gw / sandbox-tokyo / zlambda), 라우트, 플러그인, Admin API
- Cloudflare 엣지 관련: Turnstile 위젯, cs-cf-worker-bouncer, cfb-manager
- Obsidian 중 엣지 범위 파일 쓰기: `infra/apisix.md`, `infra/crowdsec-safeline.md` 의 엣지 섹션, `services/bunnycdn*.md`
**공동/협업**:
- CrowdSec 시나리오: Heimdall 소유, Syn은 APISIX/SafeLine용 시나리오 파라미터 튜닝 제안만
- 두 에이전트 모두 OpenMemory·Outline 읽기·쓰기 OK (MCP 경유). **Vault는 kappa 게이트웨이 ASK-only** (아래 섹션).
## Vault 접근 — kappa 게이트웨이 프로토콜
2026-04-09 도입. 에이전트는 Vault에 직접 접근할 수 없다. 중앙 집중 감사·블라스트 래디우스 제한이 목적.
**구현**:
- Heimdall `~/.mcp.json` · Syn `~/syn/.mcp.json` 에서 `vault` 항목 완전 제거
- 두 에이전트 모두 `mcp__vault__*` 도구를 물리적으로 호출 불가
- CLAUDE.md 에 규칙·포맷 명시
**프로토콜**:
| 단계 | 행위자 | 포맷 |
|------|-------|------|
| 1 | 에이전트 | `[SYN ASK] vault:<path> <key> 필요 (용도: <한줄>)` → kappa tmux 0:1 에 주입 |
| 2 | kappa | Vault 조회 (MCP `mcp__vault__read_secret`) |
| 3a | kappa | `[KAPPA->SYN] <path> <key> = <value>` → 에이전트 tmux 에 주입 (성공) |
| 3b | kappa | `[KAPPA->SYN] DENIED: <사유/정정힌트>` → 에이전트 tmux 에 주입 (거절) |
| 4 | 에이전트 | 값 사용·즉시 폐기, 파일/OpenMemory/Obsidian 평문 저장 금지 |
| 5 | 에이전트 | `[SYN DONE] vault ... 수신 확인, 미저장 폐기` CC |
**규칙**:
- ASK 한 번에 여러 키를 동시 요청 가능 (같은 작업 범위 내)
- 예외 없음 — bunnycdn/openmemory/nocodb 등 다른 MCP는 그대로 동작
- 환경변수 잔존(`$VAULT_TOKEN`, `$VAULT_ADDR`) 신뢰 금지
- 검증: 2026-04-09 Syn + Heimdall 양쪽에서 e2e 테스트 완료 (DENIED 경로 포함)
**이점**:
- 기술적 격리 (에이전트가 규칙을 잊거나 혼동해도 Vault 도달 불가)
- 중앙 감사 로그 (kappa 세션 대화 히스토리에 모든 ASK/응답 기록)
- 동기 승인 (kappa 부재 시 자동 차단)
**한계**:
- kappa 세션 활성 상태 필요 (에이전트 자율 작업 중 kappa 부재 시 시크릿 요구 작업 blocking)
- kappa 세션 대화 히스토리에 시크릿 평문 잔존 (`/clear` 또는 세션 종료 시 사라짐)
- kappa 본인의 MCP 권한 남용 방지책은 별도 필요 (vault audit log on Vault 서버 사이드 병행 권장)
## 배포 관리
### Heimdall
- OpenTofu 관리: [`kaffa/ops-agents-tofu/heimdall`](https://gitea.inouter.com/kaffa/ops-agents-tofu) (2026-04-09 재생성)
- 이전: 2026-03 수동 생성 (root 유저, kr1 default project, IP 10.100.3.92) → 2026-04-09 tofu 재생성 (kaffa 유저, kr1 ops project, IP 10.100.3.108)
- 재생성 시 `~/.claude` (CLAUDE.md, credentials, settings, plugins) 전체 백업/복원
- 변경 플로우: 로컬 clone → `heimdall/` 에서 `tofu plan``tofu apply`
- State: 로컬 `terraform.tfstate` (gitignore, 수동 백업)
- Secrets (`terraform.tfvars`): Vault `secret/apps/gitea` 참조, 커밋 금지
### Syn
- OpenTofu 관리: [`kaffa/ops-agents-tofu`](https://gitea.inouter.com/kaffa/ops-agents-tofu) (2026-04-09 신규)
- 변경 플로우: 로컬 clone → `syn/` 에서 `tofu plan``tofu apply`
- State: 로컬 `terraform.tfstate` (gitignore, 수동 백업). 향후 R2 s3 backend 이주 검토.
- Secrets (`terraform.tfvars`): Vault 참조, 커밋 금지
### 런타임 설정 (Syn 기준)
- Debian 13 cloud 이미지, 4GiB RAM / 4 vCPU, limits.cpu/memory
- 유저: kaffa (uid 1000, NOPASSWD sudo)
- Claude Code 공식 인스톨러 (`curl -fsSL https://claude.ai/install.sh | bash`), npm 미사용
- uv / uvx (MCP 서버용)
- `~/syn/` workspace: CLAUDE.md + bunnycdn/cloudflare/safeline/apisix 런북 + .mcp.json (bunnycdn/vault/openmemory/kubernetes)
- systemd `syn-tmux.service` (enabled, 첫 로그인 후 수동 start)
## 향후 확장 후보
내부 에이전트를 더 찍어낸다면 (Tofu 템플릿화 완료 후):
| 이름 (북유럽) | 역할 후보 |
|---|---|
| **Mimir** | 지식·메모리 관리 (Obsidian 정합성, OpenMemory 큐레이션) |
| **Forseti** | 분쟁 조정 — CI/CD, PR 리뷰, 코드 품질 |
| **Bragi** | 프론트엔드·UX·카피 |
| **Eir** | 헬스체크·복구·장애 대응 |
| **Vör** | 관찰성 (VictoriaMetrics/Logs/Grafana) |
이름 예약만. 실제 생성은 필요 시점에.
## 참조
- [[infra-hosts]] — 전체 인프라 토폴로지
- [[../openclaw/openclaw-agents|openclaw-agents]] — 분리된 OpenClaw 시스템 (고객용)
- [`kaffa/ops-agents-tofu`](https://gitea.inouter.com/kaffa/ops-agents-tofu) — Tofu IaC 정본