# dipup 인수인계 — postgresql-ha → cnpg-cluster (gitea/keycloak/dnsup) 이 문서는 실행 문서가 아니다. dip-catalog가 아닌 `paasup/dipup` 레포에서 관리되는 gitea/keycloak/dnsup의 DB 전환 작업을 위해, dip-catalog 쪽에서 파악한 내용을 정리해 넘기는 참고 자료다. dip-catalog는 이 3개 앱과 `postgresql-ha`를 직접 변경하지 않는다. ## 배경 카탈로그의 `postgresql-ha`(bitnami postgresql-repmgr + pgpool, `manifests/helm/postgresql-ha/11.9.4/`)는 현재 `platform` 네임스페이스에 배포되어 있고, `gitea`·`keycloak`·`dnsup` 3개 앱이 이 인스턴스의 4개 DB를 쓴다. | DB | 소비 앱 | owner role | |---|---|---| | `gitea` | gitea | gitea | | `gitea_session` | gitea (세션 저장소) | gitea | | `keycloak` | keycloak | keycloak | | `paasup` | dnsup | paasup | GitHub 이슈 [#9](https://github.com/paasup/dip-catalog/issues/9)에서 이 인스턴스를 CloudNativePG(cnpg-cluster + cloudnative-pg operator)로 대체하기로 이미 결정되었다 (2026-07-31). dip-catalog에는 이미 `cloudnative-pg`(0.29.0, operator)·`cnpg-cluster` (1.0.0, Cluster/Database 래퍼 차트)가 추가되어 있고, 이번 작업(카탈로그 앱 airflow/lakekeeper/mlflow/superset 전환)에서 이 두 차트로 4개 앱의 내장 DB를 전용 인스턴스로 옮기는 배포 테스트까지 실측 검증했다. ## 현재 연결 정보 (변경 지점) 3개 앱은 서브차트가 아니라 외부 호스트를 직접 참조한다. cnpg-cluster로 전환 시 아래 지점만 바뀐다. | 앱 | 파일 | 현재 값 | 변경 후 (예: 릴리스명 `platform-db`) | |---|---|---|---| | gitea | `gitea.config.database.HOST` | `postgresql-postgresql-ha-postgresql:5432` | `platform-db-rw:5432` | | gitea | `gitea.config.session.PROVIDER_CONFIG` | `host=postgresql-postgresql-ha-postgresql` | `host=platform-db-rw` | | keycloak | `extraEnv` (`DB_ADDR`) | `postgresql-postgresql-ha-postgresql` | `platform-db-rw` | | dnsup | `env.DB_HOST` | `postgresql-postgresql-ha-postgresql.platform.svc.cluster.local` | `platform-db-rw.platform.svc.cluster.local` | cnpg-cluster의 서비스 명명 규칙은 `<릴리스명>-rw`(쓰기/기본 연결)이다 — 자세한 내용은 `manifests/helm/cnpg-cluster/1.0.0/CUSTOM-README.md` §3 참고. ## 선결 과제 — 공유 인스턴스 하나로 4개 DB를 만들 수 없다 `cnpg-cluster` 차트의 `bootstrap.initdb`는 **DB 1개 + owner role 1개만** 최초 생성한다. `databases[]`(Database CRD)로 DB를 추가할 수는 있지만 **owner role은 미리 존재해야 한다** — role 자체를 새로 만들지 못한다. `postgresql-ha`의 `initdbScripts`처럼 gitea/keycloak/paasup 3개 role을 한 번에 만들 방법이 지금 차트에는 없다. 이번 dip-catalog 작업(airflow/lakekeeper/mlflow/superset)은 각 앱이 **자기 전용 인스턴스**를 쓰는 구조라 이 문제를 만나지 않았다(인스턴스마다 role 1개만 필요). gitea/keycloak/dnsup는 원래 인스턴스 1개를 공유하던 구조라 선택이 필요하다. ### 옵션 A — 공유 인스턴스 유지 (기존 토폴로지와 동일) `bootstrap.initdb.postInitSQL`(CNPG 업스트림 API에 있는 필드 — superuser로 최초 1회, DB 생성 전 단계에 실행되는 SQL. 기존 `postInitApplicationSQL`과 달리 `CREATE ROLE`/ `CREATE DATABASE`에 적합)을 `manifests/helm/cnpg-cluster/1.0.0/templates/cluster.yaml`· `values.yaml`에 추가해야 한다. 이 필드로 keycloak/paasup role을 만들고(gitea role은 `bootstrap.initdb.owner`로 자동 생성), `databases[]`로 gitea/gitea_session/keycloak/ paasup 4개 DB를 선언하는 방식이다. **이 작업은 dip-catalog 쪽 차트 변경이 선행되어야 하므로, dipup에서 이 옵션을 원하면 dip-catalog에 먼저 요청이 필요하다.** ### 옵션 B — 앱별 전용 인스턴스 3개 (이번 작업에서 검증된 패턴 그대로) gitea용, keycloak용, dnsup(paasup)용 `cnpg-cluster` 릴리스를 각각 배포한다. 각 인스턴스는 `bootstrap.initdb.database`/`owner`만 채우면 되므로 **차트 수정이 필요 없다** — `manifests/applicationset/airflow/1.16.0/airflow-db-values.yaml` 등과 동일한 패턴의 값 오버레이 3개(dipup 쪽에 `gitea-db-values.yaml`, `keycloak-db-values.yaml`, `dnsup-db-values.yaml` 격)만 있으면 된다. 이 값들은 ArgoCD ApplicationSet의 `valuesPath`로 연결하는 것을 권장한다 — `manifests/applicationset/{airflow,lakekeeper,mlflow,superset}/`가 그 구조의 실제 예시다(DB 차트 syncWave 0 → 앱 차트 syncWave 1). gitea의 `gitea_session` DB는 같은 인스턴스 안에서 `databases[]`에 `owner: gitea`로 추가하면 된다(role은 이미 bootstrap로 생성됨). 단점은 postgres 파드 수가 늘어나는 것(인스턴스 3개 × instances 설정값)이다 — 리소스는 `manifests/helm/cnpg-cluster/1.0.0/dip-resources-quotas.yaml`의 `small`(instances:1) 기준을 참고한다. **권장**: 별도 사유가 없다면 옵션 B — dip-catalog 차트 변경 없이 바로 시작할 수 있고, 이번 4개 앱 전환에서 동일 패턴이 실측 검증되었다. ## 이번 작업에서 실측된 주의사항 (그대로 적용됨) - cnpg-cluster의 `-ro`(replica 전용) 서비스는 `instances:1`이면 엔드포인트가 0개다. 읽기/쓰기를 분리해서 연결하는 앱이 있다면 읽기는 `-ro`가 아니라 `-r`(전체 인스턴스 라운드로빈)을 쓴다 — `lakekeeper/0.11.0/custom-values.yaml`에서 실측. - `cloudnative-pg` operator(namespace `cnpg-system`, release `cnpg`)는 클러스터에 이미 1회 설치되어 있으므로 재사용하면 된다 — 새로 설치할 필요 없다. - DB owner 계정의 비밀번호는 `bootstrap.initdb.secretName`으로 지정한 시크릿(키: `username`/`password`)에서 온다. 앱 쪽 값(예: keycloak의 `DB_PASSWORD`)과 반드시 일치해야 한다. ## 이번 작업 범위에 포함되지 않은 것 - gitea/keycloak/dnsup의 `custom-values.yaml` 실제 수정 (dipup 관리 대상) - `postgresql-ha` 카탈로그 항목 제거 여부 판단 - 실 데이터 마이그레이션(`pg_dump`/`pg_restore`) 및 컷오버 절차, 다운타임 계획, 롤백 계획 — SSO(keycloak)·git(gitea) 서비스에 영향을 주는 운영 작업이라 별도 계획·승인이 필요하다.