feat(cli): clusterName 환경별 소스명 매핑 + 운영 소스 3-모드 결정 조회(datasource options/ls) + 검증·문서 · v0.32.0

This commit is contained in:
2026-09-06 03:41:17 +09:00
parent 789aaee5b4
commit 075d7bc3d7
9 changed files with 356 additions and 62 deletions

View File

@ -14,12 +14,20 @@ project: my-app # 프로젝트 이름(이미지 경로/표
#
# ★ 환경별 오버라이드(오버레이 병합): 아래 base 의 requires/workloads 를 environments.<env> 에서 '이름 매칭'으로
# 덮어쓰거나 추가할 수 있다 → dev↔prod 소스/리소스가 달라도 promote 때 매니페스트 수정 불필요(앱 binds 는 논리이름 고정).
# 예) prod 는 관리형 공유 mongo + 큰 리소스:
# · requires 는 논리 '이름(name)' 으로 매칭 → type/mode/plan 을 환경별로 덮어쓴다.
# · 각 environments.<env> 오버레이는 **base 하고만** 병합된다 — dev↔val↔prod 끼리는 서로 상속하지 않는다
# (그래서 type 이 base 에 없으면 필요한 환경마다 오버레이에 직접 적어야 한다. 위반은 배포 전 친절한 검증 오류로 잡힌다).
# · clusterName: 논리 이름과 '실제 클러스터 소스 이름'을 분리한다 — 로컬(dev)은 논리 이름으로 소스를 만들고,
# 운영(prod)은 이미 존재하는 (이름이 다른) 외부/공유 소스에 매핑한다. binds 는 그대로 논리 이름을 가리키므로
# 앱 코드·바인딩은 불변. (원격 클러스터의 데이터 소스 기본은 인클러스터가 아니라 외부/공유 → 이름이 다른 게 흔하다.)
# 예) base 의 논리 소스(appdb)를 prod 에선 이미 있는 외부 공유 소스(이름이 다름)에 매핑 + 큰 리소스:
# (전제: base.requires 에 { name: appdb, type: … } 가 있음 — 오버레이는 그 논리 이름을 매칭해 덮어쓴다.
# base 에 없는 이름을 오버레이에 처음 쓰면 신규 항목이라 type 을 반드시 함께 적어야 한다.)
# prod:
# cluster: my-prod-cluster
# domains: [app.example.com]
# requires: # 이름(appdb) 매칭 → base 의 정체를 덮어씀
# - { name: appdb, type: mongodb, mode: shared, plan: medium }
# requires: # 이름(appdb) 매칭 → base 의 정체를 덮어씀(type 은 base 상속)
# - { name: appdb, mode: shared, clusterName: shared-prod-db } # 운영의 기존 소스명으로 매핑
# workloads: # 워크로드명(web) 키로 필드 패치(resources·replicas·env 는 병합, 그 외 교체)
# web: { replicas: 3, resources: { cpu: 500m, mem: 512Mi } }
environments:
@ -31,10 +39,19 @@ environments:
# type ∈ postgresql·mysql·mariadb·mongodb·redis·minio·rabbitmq·solr·oracle
# - 기본(shared, mode 생략): 공유 외부 서버에 클러스터/프로젝트별 **격리 DB·계정** 민팅(인클러스터 리소스 생성 없음).
# - 인클러스터(옵션): 정말 전용 인스턴스가 필요할 때만 `mode: local, plan: small|medium|large`.
# - 외부(옵션): `mode: remote` — 관리형이 프로비저닝 안 하고 기존 외부 서버에 연결. **접속정보(호스트·계정)는 매니페스트/git 에**
# **절대 쓰지 말고** 콘솔/API 로 등록한 뒤, 매니페스트는 `{ name, type, mode: remote, clusterName: <등록된 소스명> }` 로 매핑만 한다.
# - 타입별 지원 모드: postgresql·mysql·mariadb·mongodb·rabbitmq·solr = local/remote/shared, redis·minio = local/remote(**shared 없음**), oracle = remote 전용.
# (배포별 실제 공유 가용성 확인 = `yakcloud datasource options <type> --env prod`)
# - ★ redis 는 예외 — 공유 격리가 ACL 키/채널 '프리픽스'(비투명, 맨 pub/sub 차단)라 **기본이 전용(local)**.
# REDIS_URL 로 전권(pub/sub 포함). 프리픽스-인지 앱이면 `mode: shared` 로 공유 사용 가능.
# - 이름이 클러스터의 기존 READY 소스와 일치하면 스킵·바인딩. ('yakcloud project check' 로 미리 확인)
# (운영 모드/이름 결정 조회: 'yakcloud datasource options <type> --env prod' = 지원모드·공유 가용성·기존 소스,
# 'yakcloud datasource ls --env prod' = 대상 클러스터의 기존 소스 이름 목록 → clusterName 매핑에 사용)
# (기존 소스의 mode 를 바꾸려면 삭제 후 재배포 — 리컨실은 재프로비저닝하지 않고 경고만 함)
# - clusterName(선택): 이 소스가 '대상 클러스터에서 갖는 실제 이름'을 논리 name 과 다르게 지정. 기본값=name.
# 주로 environments.<env> 오버레이에서 '운영의 기존 외부/공유 소스명'으로 매핑할 때 쓴다(로컬↔운영 이름이 달라도 됨).
# 매칭·프로비저닝·상태 조회는 clusterName(실제명) 기준, 앱 binds 는 논리 name 참조로 불변.
# ⚠ 소스 이름은 '프로젝트 고유'로 두라(my-app-db → init 이 프로젝트명으로 치환). 공용 클러스터에선
# 리컨실이 '같은 이름의 기존 READY 소스'를 재사용·바인딩하므로, appdb 같은 일반 이름은 다른 프로젝트의
# DB 에 붙어 그 DB 에 테이블을 만드는 사고가 난다. 고유 이름이면 각 프로젝트가 자기 소스를 갖는다.