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만 하거나 롤링 재시작을 수행합니다.
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' 같은 값이 미리 설정되어 있습니다.
logical replication이 필요 없는 클러스터라면 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 이하(1.30 지원 범위 밖)에서 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: true
PostgreSQL 17 이상에서는 이 설정이 네이티브 GUC인 allow_alter_system을 제어합니다.
정리
PostgreSQL 설정은 서버 파일이 아니라 .spec.postgresql에 선언하고, 반영과 재시작은 Operator가 맡습니다. parameters 값은 모두 문자열로 적으며, 기본값 → 사용자값 → 고정값 순으로 덮이므로 고정 파라미터는 항상 Operator 쪽이 이깁니다.
- 재시작이 필요 없는 파라미터는 무중단 reload로, 필요한 파라미터는 롤링 재시작으로 반영됩니다.
pg_stat_statements같은 관리 대상 extension은 파라미터만 적으면 자동으로 활성화됩니다.pg_hba·pg_ident도 리스트로 선언하며,podSelectorRefs로 Pod IP를 자동 반영할 수 있습니다.ALTER SYSTEM은 기본 차단, 필요할 때만enableAlterSystem으로 엽니다.