9.3 Database 관리(선언적)
앞 절의 role이 Cluster 스펙 안에 인라인으로 선언되는 것과 달리, database는 별도의 Database CRD로 관리한다. psql에 붙어 CREATE DATABASE를 실행하는 대신, 어느 클러스터에 어떤 이름과 소유자로 database를 원하는지를 Database 매니페스트에 적으면 Operator가 그 database를 만들고 유지한다. database·schema·extension까지 코드로 관리되므로, 애플리케이션이 쓸 database 환경 전체를 GitOps로 재현할 수 있다.
Database CRD가 다루는 범위는 global object(database)와 그 안의 schema·extension까지다. 테이블 같은 애플리케이션 데이터 자체는 관리하지 않는다. 그 부분은 여전히 마이그레이션 도구나 개발 프로세스의 몫이다.
Database CRD 구조
Database는 어느 Cluster에 속하는지를 spec.cluster.name으로 가리키고, 실제 database 이름은 spec.name에 적는다.
apiVersion: postgresql.cnpg.io/v1
kind: Database
metadata:
name: pg-app-db
spec:
name: app
owner: app
cluster:
name: pg
ensure: present
databaseReclaimPolicy: delete주요 필드는 다음과 같다.
| 필드 | 의미 |
|---|---|
metadata.name | Kubernetes 객체 이름 (namespace 안에서 고유) |
spec.name | 실제 PostgreSQL database 이름 |
spec.owner | database를 소유할 role |
spec.cluster.name | 대상 Cluster 참조 (생성 후 변경 불가) |
spec.ensure | present(생성) 또는 absent(삭제) |
spec.databaseReclaimPolicy | 객체 삭제 시 동작 — retain(유지) 또는 delete(제거) |
조정 흐름
Database 객체를 적용하면 Operator가 spec.cluster.name이 가리키는 Cluster의 primary에 접속해 database를 만들고, .status에 반영 결과를 기록한다.
flowchart TD
DBA["DBA"] -->|apply Database| DB["Database CRD"]
OP["Operator"] -->|감시·조정| DB
DB -->|cluster.name| CL["Cluster"]
OP -->|primary에 실행| SQL["CREATE·ALTER DATABASE<br/>schema·extension"]
SQL --> ST["status.applied"]
classDef node fill:#dbeafe,stroke:#1d4ed8,color:#1e3a8a
class DBA,DB,OP,CL,SQL,ST node
extension 관리
database 안에 설치할 extension은 spec.extensions에 선언한다. Operator가 CREATE EXTENSION·ALTER EXTENSION·DROP EXTENSION을 실행해 상태를 맞춘다.
spec:
extensions:
- name: bloom
ensure: present
version: "1.0"
schema: public각 항목은 name(필수), ensure(present 기본 또는 absent), 특정 버전을 지정하는 version, 설치 대상 schema를 갖는다.
schema 관리
schema도 같은 방식으로 spec.schemas에 선언한다.
spec:
schemas:
- name: app
owner: app
ensure: presentname(필수), 소유자 owner, ensure를 지정하며 Operator가 CREATE SCHEMA·ALTER SCHEMA·DROP SCHEMA로 반영한다.
database 삭제
database를 없애는 방법은 두 가지다.
ensure: absent— 객체는 남겨 둔 채 PostgreSQL의 database만 제거한다.databaseReclaimPolicy: delete— Database 객체를 삭제할 때 실제 database도 함께 제거한다. 기본값retain은 객체를 지워도 database를 남긴다.
databaseReclaimPolicy의 기본값은 retain이다. 즉 아무 설정 없이 Database 객체만 지우면 Kubernetes 객체만 사라지고 실제 database는 그대로 남는다. database까지 함께 지우려는 의도라면 delete를 명시해야 한다.제약과 주의점
- Cluster 참조 불변 —
spec.cluster는 생성 후 바꿀 수 없다. 다른 클러스터를 대상으로 하려면 새 Database 객체를 만든다. - 예약 이름 —
postgres,template0,template1은spec.name으로 쓸 수 없다. - 이름 변경 불가 —
spec.name을 바꾸는 것은 지원되지 않으며 Kubernetes가 거부한다. - encoding·collation 불변 — PostgreSQL이 이 값들의 변경을 막으므로, 나중에 고쳐도 조용히 무시된다.
- 중복 관리 금지 — 같은
spec.name·spec.cluster.name조합을 가진 Database 객체가 둘이면 두 번째가 거부된다. - replica cluster 제약 — 읽기 전용 replica cluster에 선언한 database는 승격 전까지 pending 상태로 남고, 삭제해도 Kubernetes 객체만 정리될 뿐 실제 database는 지워지지 않는다.
status로 상태 확인
반영이 끝나면 Database 객체의 .status에 결과가 나타난다.
status:
applied: true
observedGeneration: 1applied: true는 조정이 성공했다는 뜻이다. 실패하면 status.message에 오류 내용이 담긴다.
정리
- database는 role과 달리 별도의 Database CRD로 관리.
spec.cluster.name으로 대상 지정 spec.name이 실제 database 이름,spec.owner가 소유 role- extension·schema도
spec.extensions·spec.schemas로 선언적으로 관리 - 삭제는
ensure: absent또는databaseReclaimPolicy: delete— 기본은retain(database 유지) - Cluster 참조·이름·encoding은 불변, 예약 이름은 사용 불가
- 반영 결과는
.status.applied로, 오류는.status.message로 확인
다음 절(9.4)에서는 애플리케이션이 이 database에 접속하는 통로인 Service를 관리하는 방법을 본다.