본문 바로가기
WIKI 기술 지식 베이스

PostgreSQL 구성

원문 보기 위키 갱신

PostgreSQL 구성 (PostgreSQL Configuration)

CloudNativePG에서 PostgreSQL 인스턴스를 구성하는 방법을 알려 드릴게요. 선언적 구성과 불변성(immutability) 원칙에 따라 postgresql.conf 같은 파일을 직접 만지지 않고, Cluster 리소스의 postgresql 섹션에서 pg_hba, pg_ident, parameters 키로 제어해요.

출처: 문서

본문

PostgreSQL에 익숙한 사용자는 인스턴스를 구성하는 다음 세 파일의 존재를 알고 있을 거예요:

  • postgresql.conf: PostgreSQL의 주요 런타임 구성 파일
  • pg_hba.conf: 클라이언트 인증 파일
  • pg_ident.conf: 외부 사용자를 내부 사용자로 매핑

선언적 구성과 PostgreSQL 컨테이너 불변성의 개념 때문에 사용자는 이 파일들을 직접 건드릴 수 없어요. 구성은 Cluster 리소스 정의의 postgresql 섹션에서 parameters, pg_hba, pg_ident 키를 통해 커스텀 postgresql.conf, pg_hba.conf, pg_ident.conf 설정을 정의함으로써 가능해요.

이 설정들은 모든 인스턴스에서 동일해요.

:::warning PostgreSQL 인스턴스의 구성을 명령형(imperative)으로 변경하기 위해 ALTER SYSTEM 쿼리를 사용하지 마세요. 오퍼레이터가 일반적으로 제어하는 일부 옵션을 변경하면 클러스터가 예측할 수 없거나 복구할 수 없는 상태가 될 수 있어요. 게다가 ALTER SYSTEM 변경은 클러스터 전체에 복제되지 않아요. 자세한 내용은 아래의 "ALTER SYSTEM 활성화"를 참고해 주세요. :::

커스텀 설정 사용에 대한 참조는 샘플에 포함되어 있으며, cluster-example-custom.yaml을 참고해 주세요.

postgresql 섹션 (The postgresql section)

파드의 PostgreSQL 인스턴스는 기본 postgresql.conf 파일로 시작하며, 여기에 이 설정들이 자동으로 추가돼요:

listen_addresses = '*'
include custom.conf

custom.conf 파일에는 postgresql 섹션의 사용자 정의 설정이 포함돼요. 예를 들어:

  # ...
  postgresql:
    parameters:
      shared_buffers: "1GB"
  # ...

:::note[PostgreSQL GUCs: Grand Unified Configuration] 사용 가능한 파라미터(GUC, Grand Unified Configuration이라고도 함)에 대한 자세한 내용은 PostgreSQL 문서를 참고해 주세요. CloudNativePG는 PostgreSQL 파라미터에 문자열만 허용한다는 점을 유의해 주세요. :::

custom.conf의 내용은 오퍼레이터가 다음 섹션을 이 순서로 적용해 자동으로 생성하고 유지 관리해요:

  • 전역 기본 파라미터
  • PostgreSQL 메이저 버전에 따른 기본 파라미터
  • 사용자 제공 파라미터
  • 고정(fixed) 파라미터

**전역 기본 파라미터(global default parameters)**는 다음과 같아요:

archive_timeout = '5min'
dynamic_shared_memory_type = 'posix'
full_page_writes = 'on'
logging_collector = 'on'
log_destination = 'csvlog'
log_directory = '/controller/log'
log_filename = 'postgres'
log_rotation_age = '0'
log_rotation_size = '0'
log_truncate_on_rotation = 'false'
max_parallel_workers = '32'
max_replication_slots = '32'
max_worker_processes = '32'
shared_memory_type = 'mmap'
shared_preload_libraries = ''
ssl_max_protocol_version = 'TLSv1.3'
ssl_min_protocol_version = 'TLSv1.3'
wal_keep_size = '512MB'
wal_level = 'logical'
wal_log_hints = 'on'
wal_sender_timeout = '5s'
wal_receiver_timeout = '5s'

:::warning PostgreSQL 클러스터에서 WAL 세그먼트 보존을 계획하고, 예상 및 관찰된 워크로드에 따라 서버 버전에 맞는 wal_keep_size 또는 wal_keep_segments를 적절히 구성하는 것은 여러분의 책임이에요.

또는, 유일한 스트리밍 리플리케이션 클라이언트가 고가용성 클러스터에서 실행되는 레플리카 인스턴스뿐이라면, 클러스터 레벨에서 리플리케이션 슬롯을 지원하는 리플리케이션 슬롯 기능을 활용할 수 있어요. 이 기능은 `replicationSlots.highAvailability` 옵션으로 활성화할 수 있어요 (자세한 내용은 ["Replication" 섹션](replication.md#replication-slots-for-high-availability) 참고).

리플리케이션 슬롯이나 연속 백업이 없는 상태에서 `wal_keep_size` 또는 `wal_keep_segments`를 구성하는 것이 스탠바이가 동기화에서 벗어나는 것을 보호하는 유일한 방법이에요.
스탠바이가 동기화에서 벗어나면 다음과 같은 오류 메시지가 생겨요:
`"could not receive data from WAL stream: ERROR: requested WAL segment ************************ has already been removed"`.
이 경우 스트리밍 리플리케이션 목적을 위해 이전 WAL 세그먼트를 유지하도록 `PGDATA`의 일부 또는 WAL 파일 저장 전용 볼륨을 할애해야 해요.

:::

다음 파라미터는 **고정(fixed)**이며 오퍼레이터가 독점적으로 제어해요:

archive_command = '/controller/manager wal-archive %p'
hot_standby = 'true'
listen_addresses = '*'
port = '5432'
restart_after_crash = 'false'
ssl = 'on'
ssl_ca_file = '/controller/certificates/client-ca.crt'
ssl_cert_file = '/controller/certificates/server.crt'
ssl_key_file = '/controller/certificates/server.key'
unix_socket_directories = '/controller/run'

고정 파라미터는 마지막에 추가되므로 사용자가 YAML 구성으로 재정의할 수 없어요. 이 파라미터들은 올바른 WAL 아카이빙과 리플리케이션에 필요해요.

Write-Ahead 로그 레벨 (Write-Ahead Log Level)

PostgreSQL의 wal_level 파라미터는 Write-Ahead 로그(WAL)에 기록되는 정보의 양을 결정해요. 다음 값을 허용해요:

  • minimal: 크래시 복구에 필요한 정보만 기록해요.
  • replica: WAL 아카이빙과 스트리밍 리플리케이션을 지원하기에 충분한 정보를 추가하며, 스탠바이 인스턴스에서 읽기 전용 쿼리 실행 기능을 포함해요.
  • logical: replica의 모든 정보에 더해 로지컬 디코딩과 리플리케이션에 필요한 추가 정보를 포함해요.

기본적으로 업스트림 PostgreSQL은 wal_level을 replica로 설정해요. 반면 CloudNativePG는 로지컬 리플리케이션을 기본적으로 사용할 수 있도록 wal_level을 logical로 설정해요. 이렇게 하면 외부 PostgreSQL 서버에서의 마이그레이션 같은 사용 사례를 지원하기가 더 쉬워져요.

클러스터에 로지컬 리플리케이션이 필요하지 않다면 WAL 볼륨과 오버헤드를 줄이기 위해 wal_level을 replica로 설정하는 것이 좋아요.

마지막으로 CloudNativePG는 WAL 아카이빙이 비활성화된 단일 인스턴스 클러스터에서만 wal_level을 minimal로 설정하는 것을 허용해요.

리플리케이션 설정 (Replication Settings)

primary_conninfo, restore_command, recovery_target_timeline 파라미터는 인스턴스가 클러스터 내에서 담당하는 역할에 따라 오퍼레이터가 자동으로 관리해요. 이 파라미터들은 인스턴스가 레플리카로 동작할 때만 실제로 적용돼요.

primary_conninfo = 'host=<PRIMARY> user=postgres dbname=postgres tcp_user_timeout=5000'
recovery_target_timeline = 'latest'

:::info[Important] 기본적으로 모든 스탠바이는 위와 같이 tcp_user_timeout을 5초로 설정해요. 이 파라미터는 전송된 데이터가 TCP 연결이 강제로 닫히기 전에 확인되지 않은 채 남아 있을 수 있는 시간을 정의해요. 이를 조정하면 스탠바이가 네트워크 문제에 얼마나 빨리 반응하는지 제어할 수 있어요. 기본값이 요구사항을 충족하지 않으면 STANDBY_TCP_USER_TIMEOUT 오퍼레이터 구성 옵션을 사용해 오퍼레이터가 관리하는 모든 스탠바이에 대해 재정의할 수 있어요. tcp_user_timeout에 대한 추가 세부 내용은 PostgreSQL 문서를 참고해 주세요. :::

로그 제어 설정 (Log control settings)

오퍼레이터는 PostgreSQL이 로그를 CSV 형식으로 출력할 것을 요구하며, 인스턴스 매니저가 이를 자동으로 파싱해 JSON 형식으로 출력해요. 결과적으로 이 섹션에 나열된 일부 PostgreSQL 로그 설정은 고정되어 수정할 수 없어요.

자세한 내용은 "Logging(로깅)" 섹션을 참고해 주세요.

공유 프리로드 라이브러리 (Shared Preload Libraries)

PostgreSQL의 shared_preload_libraries 옵션은 쉼표로 구분된 목록 형태로 서버 시작 시 하나 이상의 공유 라이브러리를 프리로드하도록 지정하는 데 존재해요. 일반적으로 전체 시스템에서 대부분의 데이터베이스 세션에 사용 가능해야 하는 확장(예: pg_stat_statements)을 로드하는 데 사용돼요.

CloudNativePG에서 shared_preload_libraries 옵션은 기본적으로 비어 있어요. shared_preload_libraries의 내용을 재정의할 수는 있지만, 전문 Postgres 사용자만 이 옵션을 활용할 것을 권장해요.

:::info[Important] 지정된 라이브러리를 찾지 못하면 서버가 시작에 실패해 CloudNativePG의 어떤 자가 치유 시도도 막고 수동 개입이 필요해져요. 내용을 직접 관리할 계획이라면 확장과 shared_preload_libraries 설정을 모두 항상 테스트하세요. :::

CloudNativePG는 가장 많이 사용되는 일부 PostgreSQL 확장에 대해 shared_preload_libraries 옵션의 내용을 자동으로 관리할 수 있어요 (자세한 내용은 아래 "관리되는 확장" 섹션 참고).

구체적으로 오퍼레이터는 구성 파라미터가 관리되는 라이브러리 중 하나를 요구하는 것을 알아차리는 즉시 필요한 라이브러리를 자동으로 추가해요. 그리고 실제 파라미터가 더 이상 요구하지 않게 되면 라이브러리도 제거해요.

:::info[Important] shared_preload_libraries에서 라이브러리를 제거하려면 효과를 보기 위해 클러스터의 모든 인스턴스를 재시작해야 한다는 점을 항상 기억하세요. :::

.spec.postgresql.shared_preload_libraries를 문자열 목록으로 제공해 추가 shared_preload_libraries를 지정할 수 있어요: 오퍼레이터는 이를 자동으로 관리하는 것들과 병합해요.

관리되는 확장 (Managed extensions)

이전 섹션에서 예고했듯이, CloudNativePG는 잘 알려지고 지원되는 일부 확장에 대해 shared_preload_libraries의 내용을 자동으로 관리해요. 현재 목록은 다음과 같아요:

  • auto_explain
  • pg_stat_statements
  • pgaudit
  • pg_failover_slots

이 라이브러리들 중 일부는 사용 전에 데이터베이스에 추가 객체(보통 CREATE EXTENSION 명령으로 데이터베이스에서 실행되는 뷰 및/또는 함수)도 필요로 해요 (DROP EXTENSION 명령은 일반적으로 그 객체들을 제거해요).

이런 라이브러리에 대해 CloudNativePG는 클러스터에서 연결을 수락하는 모든 데이터베이스에서 확장의 생성과 제거를 자동으로 처리해요. 이는 다음 쿼리로 식별돼요:

SELECT datname FROM pg_database WHERE datallowconn

:::note 위 쿼리는 template1 같은 템플릿 데이터베이스도 포함해요. :::

:::info[Important] Database CRD에서 선언적 확장이 도입되면서 이제 확장을 직접 관리할 수 있어요. 결과적으로 관리되는 확장 기능은 CloudNativePG의 향후 버전에서 크게 변경될 수 있고, 일부 기능은 deprecated될 수 있어요. :::

auto_explain 활성화 (Enabling auto_explain)

auto_explain 확장은 수동으로 EXPLAIN을 실행하지 않고도 느린 문의 실행 계획을 자동으로 로깅하는 수단을 제공해요 (최적화되지 않은 쿼리를 추적하는 데 유용함).

다음 예시 발췌처럼 구성에 auto_explain.으로 시작하는 파라미터를 추가해 auto_explain을 활성화할 수 있어요 (완료하는 데 10초 이상 걸리는 쿼리의 실행 계획을 자동으로 로깅함):

  # ...
  postgresql:
    parameters:
      auto_explain.log_min_duration: "10s"
  # ...

:::note auto_explain을 활성화하면 성능 문제가 발생할 수 있어요. auto explain 문서를 참고해 주세요. :::

pg_stat_statements 활성화 (Enabling pg_stat_statements)

pg_stat_statements 확장은 PostgreSQL에서 쿼리 실시간 모니터링에 사용할 수 있는 가장 중요한 기능 중 하나예요.

다음 예시 발췌처럼 구성에 pg_stat_statements.으로 시작하는 파라미터를 추가해 pg_stat_statements를 활성화할 수 있어요:

  # ...
  postgresql:
    parameters:
      pg_stat_statements.max: "10000"
      pg_stat_statements.track: all
  # ...

앞서 설명한 대로 오퍼레이터는 shared_preload_libraries에 pg_stat_statements를 자동으로 추가하고 각 데이터베이스에서 CREATE EXTENSION IF NOT EXISTS pg_stat_statements를 실행해 pg_stat_statements 뷰에 대한 쿼리를 실행할 수 있게 해줘요.

pgaudit 활성화 (Enabling pgaudit)

pgaudit 확장은 표준 PostgreSQL 로깅 기능을 통해 세부적인 세션 및/또는 객체 감사 로깅을 제공해요.

CloudNativePG는 PostgreSQL 클러스터에서 PGAudit을 투명하고 네이티브하게 지원해요. 자세한 내용은 "PGAudit" 로그 섹션을 참고해 주세요.

다음 예시 발췌처럼 구성에 pgaudit.으로 시작하는 파라미터를 추가해 pgaudit를 활성화할 수 있어요:

#
postgresql:
  parameters:
    pgaudit.log: "all, -misc"
    pgaudit.log_catalog: "off"
    pgaudit.log_parameter: "on"
    pgaudit.log_relation: "on"
#

pg_failover_slots 활성화 (Enabling pg_failover_slots)

EDB의 pg_failover_slots 확장은 로지컬 리플리케이션 슬롯이 페일오버 시나리오에서도 살아남을 수 있도록 보장해요. 페일오버는 일반적으로 CloudNativePG의 경우처럼 물리적 스트리밍 리플리케이션을 사용해 구현돼요.

다음 예시 발췌처럼 구성에 pg_failover_slots.으로 시작하는 파라미터를 추가해 pg_failover_slots를 활성화할 수 있어요: 위에서 설명한 대로 오퍼레이터는 이에 따라 shared_preload_libraries 옵션의 pg_failover_slots 항목을 투명하게 관리해요.

이 확장에 대한 자세한 내용은 pg_failover_slots 문서를 참고해 주세요.

또한 pg_failover_slots와 함께 사용하려는 각 데이터베이스에 대해 각 레플리카가 primary에 연결할 수 있게 하는 항목을 pg_hba 섹션에 추가해야 해요. 예를 들어 app 데이터베이스를 pg_failover_slots와 함께 사용하려면 pg_hba 섹션에 다음 항목을 추가해야 해요:

  postgresql:
    pg_hba:
      - hostssl app streaming_replica all cert

pg_hba 섹션 (The pg_hba section)

pg_hba는 파드가 사용하는 pg_hba.conf를 만드는 데 사용되는 PostgreSQL 호스트 기반 인증 규칙 목록이에요.

:::info[Important] pg_hba.conf에 대한 자세한 내용은 PostgreSQL 문서를 참고해 주세요. :::

인증에는 첫 번째 일치 규칙이 사용되므로, 오퍼레이터가 생성하는 pg_hba.conf 파일은 네 부분으로 구성된 것으로 볼 수 있어요:

  1. 고정 규칙
  2. 사용자 정의 규칙
  3. 선택적 LDAP 섹션
  4. 기본 규칙

고정 규칙:

local all all peer

hostssl postgres streaming_replica all cert map=cnpg_streaming_replica
hostssl replication streaming_replica all cert map=cnpg_streaming_replica
hostssl all cnpg_pooler_pgbouncer all cert map=cnpg_pooler_pgbouncer

기본 규칙:

host all all all <default-authentication-method>

PostgreSQL 14부터 password_encryption 데이터베이스 파라미터의 기본값은 scram-sha-256으로 설정돼요. 때문에 이 PostgreSQL 버전부터 기본 인증 방법은 scram-sha-256이에요.

PostgreSQL 13 이하에서는 기본 인증 방법으로 md5를 사용해요.

결과적인 pg_hba.conf는 다음과 같아요:

local all all peer

hostssl postgres streaming_replica all cert map=cnpg_streaming_replica
hostssl replication streaming_replica all cert map=cnpg_streaming_replica
hostssl all cnpg_pooler_pgbouncer all cert map=cnpg_pooler_pgbouncer

<user defined rules>
<user defined LDAP>

host all all all scram-sha-256 # (or md5 for PostgreSQL version <= 13)

클러스터 매니페스트 내에서 pg_hba 줄은 .spec.postgresql.pg_hba의 목록 항목으로 추가돼요. 예를 들어:

  postgresql:
    pg_hba:
      - hostssl app app 10.244.0.0/16 md5

위 예시에서는 보안 채널(hostssl)을 통해 MD5 비밀번호 인증(scram-sha-256을 선호한다면 사용 가능)을 사용해 app 사용자에게 app 데이터베이스에 대한 접근을 활성화하고 있어요.

podSelectorRefs를 통한 동적 주소 해석 (Dynamic address resolution with podSelectorRefs)

Kubernetes에서 파드 IP는 임시적이에요. 클라이언트 파드가 재시작될 때마다 pg_hba 규칙을 수동으로 업데이트하는 것은 지속 불가능해요. .spec.podSelectorRefs 옵션은 오퍼레이터가 최신 IP 주소로 해석하는 명명된 라벨 선택자를 정의할 수 있게 함으로써 이를 자동화해요.

작동 방식 (How it Works)

  1. 선택자 정의: 파드용 표준 Kubernetes labelSelector에 친숙한 이름을 매핑해요.
  2. 선택자 참조: pg_hba 규칙에서 ${podselector:NAME} 자리표시자(placeholder)를 사용해요.
  3. 자동 확장: 오퍼레이터는 일치하는 파드 IP를 해석하고 인스턴스 매니저가 각 참조를 pg_hba.conf 내의 개별 CIDR 항목(/32 for IPv4, /128 for IPv6)으로 확장해요.

구성 예시 (Configuration Example)

다음 발췌는 애플리케이션과 모니터링 파드용 선택자를 정의한 다음 PostgreSQL 접근 규칙에 적용해요:

podSelectorRefs:
  - name: app-pods
    selector:
      matchLabels:
        app: myapp
  - name: monitoring
    selector:
      matchLabels:
        role: monitoring
postgresql:
  pg_hba:
    - "hostssl mydb myuser ${podselector:app-pods} scram-sha-256"
    - "hostssl postgres monitor ${podselector:monitoring} scram-sha-256"

IP 확장 매핑 (IP Expansion Mapping)

오퍼레이터가 IP가 10.0.0.5, 10.0.0.12(App) 및 10.0.1.3(Monitoring)인 파드를 감지하면 인스턴스 매니저가 템플릿을 다음과 같이 변환해요:

# Expanded from: hostssl mydb myuser ${podselector:app-pods} scram-sha-256
hostssl mydb myuser 10.0.0.5/32 scram-sha-256
hostssl mydb myuser 10.0.0.12/32 scram-sha-256
# Expanded from: hostssl postgres monitor ${podselector:monitoring} scram-sha-256
hostssl postgres monitor 10.0.1.3/32 scram-sha-256

주요 제약 및 동작 (Key Constraints & Behavior)

  • 범위: 선택자는 보안상 클러스터와 같은 네임스페이스로 제한돼요. 크로스-네임스페이스 조회는 지원되지 않아요.
  • 배치: ${podselector:NAME} 구문은 호스트 유형 항목(host, hostssl, hostnossl, hostgssenc, hostnogssenc)의 주소 필드에서만 유효해요.
  • 반응성: 오퍼레이터는 파드 라이프사이클 이벤트(생성, 삭제, 또는 IP 업데이트)를 감시해요. 업데이트는 자동 구성 재생성과 PostgreSQL reload를 트리거해요.
  • 검증: 선택자 이름은 ^[a-z]([a-z0-9_-]*[a-z0-9])?$ 패턴을 따라야 하고, pg_hba 규칙의 각 ${podselector:NAME} 참조는 podSelectorRefs에 정의된 항목과 일치해야 해요. 웹훅이 두 제약을 모두 검증해요.

:::warning 선택자가 0개의 파드와 일치하면 이를 참조하는 해당 pg_hba 줄은 pg_hba.conf에서 생략돼요. 기본 규칙이 적절한 폴백 접근을 제공하는지 확인하세요. :::

전체 예시는 cluster-example-pod-selector-refs.yaml을 참고해 주세요.

LDAP 구성 (LDAP Configuration)

클러스터 스펙의 postgres 섹션 아래에는 pg_hba.conf 파일에 추가될 규칙으로 변환할 LDAP 구성을 정의할 수 있는 선택적 ldap 섹션이 있어요.

이는 두 가지 모드를 지원해요: LDAP 섹션에 server, prefix, suffix를 지정해야 하는 simple bind 모드와 server, baseDN, binDN, 그리고 ldap 비밀번호를 담은 시크릿인 bindPassword를 지정해야 하는 search+bind 모드예요. 또한 search+bind 모드에서는 searchFilter 또는 searchAttribute를 지정하는 옵션이 있어요. searchAttribute를 지정하지 않으면 기본값인 uid가 사용돼요.

또한 두 모드 모두 ldapscheme용 scheme과 port를 지정할 수 있어요. 그러나 scheme과 port는 모두 필수는 아니에요.

search+bind용으로 채워진 이 섹션은 다음과 같아요:

postgresql:
  ldap:
    server: 'openldap.default.svc.cluster.local'
    bindSearchAuth:
      baseDN: 'ou=org,dc=example,dc=com'
      bindDN: 'cn=admin,dc=example,dc=com'
      bindPassword:
        name: 'ldapBindPassword'
        key: 'data'
      searchAttribute: 'uid'

pg_ident 섹션 (The pg_ident section)

pg_ident는 CloudNativePG가 데이터 디렉토리 안의 ident 맵 파일(known as pg_ident.conf)을 생성하고 유지 관리하는 데 사용하는 PostgreSQL 사용자 이름 맵 목록이에요.

:::info[Important] pg_ident.conf에 대한 자세한 내용은 PostgreSQL 문서를 참고해 주세요. :::

오퍼레이터가 작성하는 pg_ident.conf 파일은 다음 두 부분으로 구성돼요:

  1. 고정 규칙
  2. 사용자 정의 규칙

현재 오퍼레이터가 자동으로 생성하는 유일한 고정 규칙은 다음과 같아요:

local <postgres system user> postgres

인스턴스 매니저는 PostgreSQL 인스턴스를 실행하는 사용자를 감지하고 이를 데이터베이스의 postgres 사용자에 매핑하는 규칙을 자동으로 추가해요.

컨테이너 안에서 postgres 사용자가 제대로 구성되지 않으면 인스턴스 매니저는 모든 로컬 사용자가 연결하도록 허용한 다음 다음과 같은 경고 메시지를 기록해요:

Unable to identify the current user. Falling back to insecure mapping.

결과적인 pg_ident.conf는 다음과 같아요:

local <postgres system user> postgres

<user defined lines>

클러스터 매니페스트 내에서 pg_ident 줄은 .spec.postgresql.pg_ident의 목록 항목으로 추가돼요. 예를 들어:

  postgresql:
    pg_ident:
      - "mymap /^(.*)@mydomain\\.com$ \\1"

구성 변경 (Changing configuration)

Cluster 리소스의 postgresql 섹션을 편집해 구성 변경을 적용할 수 있어요.

변경 후 클러스터 인스턴스는 변경 사항을 적용하기 위해 구성을 즉시 리로드해요. 변경이 재시작이 필요한 파라미터를 포함하면 오퍼레이터는 롤링 업그레이드를 수행해요.

ALTER SYSTEM 활성화 (Enabling ALTER SYSTEM)

CloudNativePG는 PostgreSQL 클러스터의 구성을 변경하는 유일한 방법으로 Cluster 매니페스트를 사용하는 것을 강력히 주장해요. 이 접근 방식은 전체 고가용성 클러스터에 걸쳐 일관성을 보장하고 Infrastructure-as-Code의 모범 사례와 일치해요.

CloudNativePG에서 기본 구성은 새 Postgres 클러스터에서 ALTER SYSTEM 사용을 비활성화해요. 이 결정은 이 명령과 관련된 잠재적 위험에 대한 인식에 기반해요. ALTER SYSTEM 사용을 활성화하려면 .spec.postgresql.enableAlterSystem을 명시적으로 true로 설정할 수 있어요.

:::warning ALTER SYSTEM을 사용할 때는 주의를 기울이세요. 이 명령은 연결된 인스턴스에 직접 작동하며 복제를 거치지 않아요. CloudNativePG는 일부 고정 파라미터에 대해 책임지고 다른 것들에 대해 완전한 제어를 하므로 신중한 고려가 필요함을 강조해요. :::

PostgreSQL 17부터 .spec.postgresql.enableAlterSystem 설정은 PostgreSQL의 allow_alter_system GUC를 직접 제어해요—이 기능은 CloudNativePG가 PostgreSQL에 직접 기여한 것이에요.

PostgreSQL 17 이전에는 .spec.postgresql.enableAlterSystem이 false로 설정되면 postgresql.auto.conf 파일이 읽기 전용이 돼요. 결과적으로 ALTER SYSTEM 명령을 실행하려는 모든 시도는 오류를 발생시켜요. 오류 메시지는 다음과 같을 수 있어요:

ERROR:  could not open file "postgresql.auto.conf": Permission denied

동적 공유 메모리 설정 (Dynamic Shared Memory settings)

PostgreSQL은 dynamic_shared_memory_type 구성 옵션을 통해 동적 공유 메모리를 관리하는 몇 가지 구현을 지원해요. CloudNativePG에서는 다음 두 값 중 하나로 제한할 것을 권장해요:

  • posix: shm_open을 사용해 할당되는 POSIX 공유 메모리에 의존 (기본 설정)
  • sysv: shmget을 통해 할당되는 System V 공유 메모리에 기반

PostgreSQL에서 이 설정은 병렬 쿼리의 메모리 할당에 특히 중요해요. 자세한 내용은 pgsql-general 메일링 리스트 스레드를 참고해 주세요.

POSIX 공유 메모리 (POSIX shared memory)

기본 설정인 posix는 대부분의 경우 충분할 거예요. 오퍼레이터가 /dev/shm 아래에 memory-bound EmptyDir 볼륨인 shm을 자동으로 마운트하기 때문이에요. 실행 중인 Postgres 컨테이너 안에서 그 볼륨의 크기를 다음으로 확인할 수 있어요:

mount | grep shm

다음과 비슷한 출력이 나올 거예요:

shm on /dev/shm type tmpfs (rw,nosuid,nodev,noexec,relatime,size=******)

shm 볼륨의 최대 크기를 설정하려면 Cluster 리소스에서 .spec.ephemeralVolumesSizeLimit.shm 필드를 설정하면 돼요. 예를 들어:

spec:
  ephemeralVolumesSizeLimit:
    shm: 1Gi

System V 공유 메모리 (System V shared memory)

Kubernetes 클러스터의 SHMMAX와 SHMALL 파라미터 값이 충분히 높다면 다음을 설정할 수도 있어요:

dynamic_shared_memory_type: "sysv"

PostgreSQL 컨테이너 안에서 다음을 실행해 SHMMAX/SHMALL을 확인할 수 있어요:

ipcs -lm

예를 들어:

------ Shared Memory Limits --------
max number of segments = 4096
max seg size (kbytes) = 18014398509465599
max total shared memory (kbytes) = 18014398509481980
min seg size (bytes) = 1

보시다시피 매우 높은 max total shared memory 값은 dynamic_shared_memory_type을 sysv로 설정할 것을 권장해요.

대체 방법으로 다음을 실행할 수도 있어요:

cat /proc/sys/kernel/shmall
cat /proc/sys/kernel/shmmax

고정 파라미터 (Fixed parameters)

일부 PostgreSQL 구성 파라미터는 오퍼레이터가 독점적으로 관리해야 해요. 오퍼레이터는 웹훅을 사용해 사용자가 설정하지 못하게 해요.

사용자는 postgresql 섹션에서 다음 구성 파라미터를 설정할 수 없어요:

  • allow_alter_system
  • allow_system_table_mods
  • archive_cleanup_command
  • archive_command
  • archive_mode
  • bonjour
  • bonjour_name
  • cluster_name
  • config_file
  • data_directory
  • data_sync_retry
  • event_source
  • external_pid_file
  • hba_file
  • hot_standby
  • ident_file
  • jit_provider
  • listen_addresses
  • log_destination
  • log_directory
  • log_file_mode
  • log_filename
  • log_rotation_age
  • log_rotation_size
  • log_truncate_on_rotation
  • logging_collector
  • port
  • primary_conninfo
  • primary_slot_name
  • promote_trigger_file
  • recovery_end_command
  • recovery_min_apply_delay
  • recovery_target
  • recovery_target_action
  • recovery_target_inclusive
  • recovery_target_lsn
  • recovery_target_name
  • recovery_target_time
  • recovery_target_timeline
  • recovery_target_xid
  • restart_after_crash
  • restore_command
  • shared_preload_libraries
  • ssl
  • ssl_ca_file
  • ssl_cert_file
  • ssl_crl_file
  • ssl_dh_params_file
  • ssl_key_file
  • ssl_passphrase_command
  • ssl_passphrase_command_supports_reload
  • ssl_prefer_server_ciphers
  • stats_temp_directory
  • synchronous_standby_names
  • syslog_facility
  • syslog_ident
  • syslog_sequence_numbers
  • syslog_split_messages
  • unix_socket_directories
  • unix_socket_group
  • unix_socket_permissions