본문으로 건너뛰기

9.3 Database 관리(선언적)

database는 별도의 Database CRD로 관리합니다(role의 DatabaseRole과 같은 방식). 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.nameKubernetes 객체 이름 (namespace 안에서 고유)
spec.name실제 PostgreSQL database 이름
spec.ownerdatabase를 소유할 role
spec.cluster.name대상 Cluster 참조 (생성 후 변경 불가)
spec.ensurepresent(생성) 또는 absent(삭제)
spec.databaseReclaimPolicy객체 삭제 시 동작 — retain(유지) 또는 delete(제거)

조정 흐름​

Database 객체를 적용하면 Operator가 spec.cluster.name이 가리키는 Cluster의 primary에 접속해 database를 만들고, .status에 반영 결과를 기록합니다.

extension 관리​

여기서 다루는 것은 database 안에 CREATE EXTENSION을 실행하는 마지막 단계입니다. extension 바이너리를 이미지로 공급하는 앞 단계와 설치 권한 통제는 9.5를 봅니다.

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: present

name(필수), 소유자 owner, ensure를 지정하며 Operator가 CREATE SCHEMA·ALTER SCHEMA·DROP SCHEMA로 반영합니다.

database 삭제​

database를 없애는 방법은 두 가지입니다.

  • ensure: absent: 객체는 남겨 둔 채 PostgreSQL의 database만 제거합니다.
  • databaseReclaimPolicy: delete: Database 객체를 삭제할 때 실제 database도 함께 제거합니다. 기본값 retain은 객체를 지워도 database를 남깁니다.

Database CRD 삭제 경로와 실제 데이터베이스 상태

경고

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: 1

applied: true는 조정이 성공했다는 뜻입니다. 실패하면 status.message에 오류 내용이 담깁니다.

정리​

database는 별도의 Database CRD로 관리하며, spec.cluster.name으로 대상 Cluster를, spec.name으로 실제 database 이름을, spec.owner로 소유 role을 지정합니다. database 안의 extension·schema도 spec.extensions·spec.schemas에 함께 선언합니다.

  • 삭제는 ensure: absent 또는 databaseReclaimPolicy: delete로 하며, 기본값 retain은 객체만 지워도 database를 남깁니다.
  • Cluster 참조·이름·encoding은 불변이고 예약 이름은 쓸 수 없으며, 반영 결과는 .status.applied, 오류는 .status.message로 확인합니다.