본문으로 건너뛰기
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으로 대상 지정
  • 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를 관리하는 방법을 본다.