본문으로 건너뛰기

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 PostgreSQL 설정 우선순위

전역 기본값 중 눈여겨볼 것들이 있습니다. 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는 다음 순서로 조립됩니다.

  1. 고정 규칙: 내부 복제(streaming replica)와 pooler 인증용. 사용자가 수정할 수 없습니다
  2. 사용자 정의 규칙: pg_hba에 적은 내용
  3. 선택적 LDAP 설정
  4. 기본 규칙: 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으로 엽니다.