9.1 PostgreSQL 설정
전통적인 운영에서는 서버에 접속해 postgresql.conf를 편집하고 pg_ctl reload를 실행하거나, ALTER SYSTEM으로 파라미터를 바꾼다. CloudNativePG에서는 이런 파일을 직접 만지지 않는다. 대신 Cluster CRD의 .spec.postgresql 아래에 원하는 설정을 적어 두면, Operator가 이를 실제 설정 파일로 만들어 각 인스턴스에 반영하고 필요한 만큼 reload나 재시작까지 처리한다. 설정이 매니페스트에 코드로 남으므로 어떤 값이 왜 바뀌었는지가 Git 이력에 그대로 드러난다.
.spec.postgresql 아래에서 다루는 것은 크게 세 가지다. GUC(Grand Unified Configuration) 파라미터를 정의하는 parameters, 클라이언트 인증 규칙을 정의하는 pg_hba, 그리고 사용자 이름 매핑을 정의하는 pg_ident다.
설정이 반영되는 흐름
DBA가 Cluster를 수정하면 Operator가 그 차이를 감지해 새 설정 파일을 만들고, 파라미터의 성격에 따라 reload만 하거나 롤링 재시작을 수행한다.
flowchart TD
DBA["DBA"] -->|edit spec.postgresql| CR["Cluster CRD"]
OP["Operator"] -->|감시·조정| CR
OP -->|생성| CONF["custom.conf<br/>pg_hba.conf<br/>pg_ident.conf"]
CONF --> DEC{"재시작 필요?"}
DEC -->|아니오| RELOAD["reload<br/>(무중단)"]
DEC -->|예| RESTART["롤링 재시작"]
classDef node fill:#dbeafe,stroke:#1d4ed8,color:#1e3a8a
class DBA,CR,OP,CONF,RELOAD,RESTART node
Operator는 사용자가 적은 값을 custom.conf라는 파일로 만들고, 이 파일을 기본 postgresql.conf에 include한다. 즉 사용자 설정은 언제나 기본값 위에 덧씌워진다.
parameters — GUC 설정
파라미터는 .spec.postgresql.parameters 아래에 키-값으로 적는다. 이때 모든 값은 문자열로 써야 한다. 숫자나 불리언도 따옴표로 감싼다.
apiVersion: postgresql.cnpg.io/v1
kind: Cluster
metadata:
name: pg
spec:
instances: 3
postgresql:
parameters:
shared_buffers: "2GB"
max_parallel_workers: "8"
wal_level: "replica"Operator는 파라미터를 다음 순서로 쌓는다. 전역 기본값 → 버전별 기본값 → 사용자 지정값 → 고정값(fixed). 뒤에 오는 것이 앞을 덮으므로, 고정 파라미터는 사용자가 무엇을 적든 항상 Operator의 값이 이긴다.
전역 기본값 중 눈여겨볼 것들이 있다. CloudNativePG는 wal_level을 logical로 잡아 두어 logical replication을 기본 지원한다. 그 밖에 archive_timeout = '5min', max_replication_slots = '32', wal_keep_size = '512MB' 같은 값이 미리 설정되어 있다.
wal_level을 replica로 낮추길 권장한다. logical은 WAL에 더 많은 정보를 남기므로, 쓰지 않을 기능 때문에 WAL 부담을 지고 있을 이유가 없다. 참고로 minimal은 WAL 아카이빙을 끈 단일 인스턴스 클러스터에서만 허용된다.고정 파라미터
일부 파라미터는 Operator가 클러스터의 정합성을 위해 직접 통제하며, 사용자가 바꾸지 못하도록 막는다. listen_addresses, port, ssl, archive_command, hot_standby, restart_after_crash, unix_socket_directories, 그리고 primary_conninfo·restore_command 같은 복제 관련 파라미터가 여기 속한다. 이런 값을 parameters에 적으면 Operator가 거부하거나 무시한다.
동적 반영과 재시작
파라미터를 바꿨을 때의 동작은 그 파라미터가 reload로 반영되는지 재시작을 요구하는지에 따라 갈린다.
- reload로 충분한 파라미터 — Operator가 즉시 설정을 다시 읽는다. 다운타임이 없다.
- 재시작이 필요한 파라미터(
shared_buffers등) — Operator가 replica부터 차례로 재시작하는 롤링 업그레이드를 수행해 가용성을 유지한다.
shared_preload_libraries와 extension
shared_preload_libraries는 기본이 비어 있으며, .spec.postgresql.shared_preload_libraries에 리스트로 지정한다.
spec:
postgresql:
shared_preload_libraries:
- "custom_lib"다만 CloudNativePG가 잘 아는 몇몇 extension은 이 목록을 직접 관리해 준다. auto_explain, pg_stat_statements, pgaudit, pg_failover_slots가 그렇다. 이 extension들의 파라미터(예: pg_stat_statements.max)를 parameters에 적기만 하면 Operator가 알아서 라이브러리를 shared_preload_libraries에 추가하고, 접근 가능한 모든 database에 CREATE EXTENSION IF NOT EXISTS를 실행한다.
spec:
postgresql:
parameters:
pg_stat_statements.max: "10000"
pg_stat_statements.track: "all"
auto_explain.log_min_duration: "10s"
pgaudit.log: "all, -misc"shared_preload_libraries에서 제거하면 모든 인스턴스의 재시작이 필요하다. extension 활성화·비활성화는 재시작을 유발할 수 있으므로 트래픽이 적은 시간대에 진행하는 편이 안전하다.pg_hba — 클라이언트 인증
호스트 기반 인증 규칙은 .spec.postgresql.pg_hba에 문자열 리스트로 적는다. 각 문자열이 pg_hba.conf의 한 행이 된다.
spec:
postgresql:
pg_hba:
- "hostssl app appuser 10.0.0.0/8 scram-sha-256"
- "hostssl mydb myuser 10.244.0.0/16 scram-sha-256"Operator가 최종 생성하는 pg_hba.conf는 다음 순서로 조립된다.
- 고정 규칙 — 내부 복제(streaming replica)와 pooler 인증용. 사용자가 손대지 못한다
- 사용자 정의 규칙 —
pg_hba에 적은 내용 - 선택적 LDAP 설정
- 기본 규칙 —
host all all all <기본 인증방식>
기본 인증 방식은 PostgreSQL 14 이상에서 scram-sha-256, 13 이하에서 md5다.
podSelectorRefs — Pod IP 자동 반영
Kubernetes에서는 클라이언트 Pod가 재시작하면 IP가 바뀐다. 그때마다 pg_hba 규칙의 CIDR을 손으로 고치는 것은 비현실적이다. podSelectorRefs는 label selector로 Pod를 지목해 두면 Operator가 해당 Pod들의 IP를 규칙에 자동으로 펼쳐 넣는 기능이다.
spec:
podSelectorRefs:
- name: app-pods
selector:
matchLabels:
app: myapp
postgresql:
pg_hba:
- "hostssl mydb myuser ${podselector:app-pods} scram-sha-256"Operator는 ${podselector:app-pods}를 매칭되는 각 Pod의 IP(/32)로 확장한다. selector에 걸리는 Pod가 세 개면 그 규칙이 세 행으로 펼쳐지고, 하나도 없으면 그 행은 아예 생략된다. selector는 Cluster와 같은 namespace 안에서만 유효하다.
pg_ident — 사용자 이름 매핑
외부 인증 시스템의 사용자 이름을 PostgreSQL role 이름으로 매핑하는 규칙은 .spec.postgresql.pg_ident에 적는다.
spec:
postgresql:
pg_ident:
- "mymap /^(.*)@example\\.com$ \\1"이 예시는 @example.com으로 끝나는 외부 사용자 이름에서 앞부분만 뽑아 PostgreSQL role로 매핑한다. Operator는 여기에 postgres 시스템 사용자용 고정 규칙을 자동으로 덧붙인다.
ALTER SYSTEM 통제
선언적 관리의 일관성을 지키기 위해, CloudNativePG는 기본적으로 ALTER SYSTEM SQL을 막아 둔다. 누군가 psql에 붙어 ALTER SYSTEM으로 값을 바꾸면 그 변경은 매니페스트에 남지 않아 클러스터 간 불일치를 만들기 때문이다. 꼭 필요하다면 .spec.postgresql.enableAlterSystem을 true로 켠다.
spec:
postgresql:
enableAlterSystem: truePostgreSQL 17 이상에서는 이 설정이 네이티브 GUC인 allow_alter_system을 제어한다.
정리
- 설정은 서버가 아니라
.spec.postgresql에 선언한다. 반영·재시작은 Operator가 처리 parameters값은 모두 문자열. 기본값 → 사용자값 → 고정값 순으로 덮인다- 재시작 불필요 파라미터는 무중단 reload, 필요 파라미터는 롤링 재시작
pg_stat_statements등 관리 대상 extension은 파라미터만 적으면 자동 활성화pg_hba·pg_ident도 리스트로 선언.podSelectorRefs로 Pod IP를 자동 반영ALTER SYSTEM은 기본 차단, 필요 시enableAlterSystem으로 허용
다음 절(9.2)에서는 database에 접속하는 주체인 role을 선언적으로 관리하는 방법을 본다.