본문으로 건너뛰기
9.3 Database 관리(선언적)

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.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에 반영 결과를 기록한다.

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

name(필수), 소유자 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, template1spec.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는 role과 달리 별도의 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로 확인한다.