본문으로 건너뛰기
4.3 구성 3계층과 우선순위

4.3 구성 3계층과 우선순위

같은 설정 키라도 출처는 세 곳이다. DCS에 저장되어 전 노드가 공유하는 dynamic configuration, 노드마다 존재하는 patroni.yml(local configuration), 그리고 프로세스에 주입되는 PATRONI_* 환경변수(environment configuration)다. 셋이 겹치면 environment, local, dynamic 순으로 우선한다.

    flowchart TD
  ENV["environment<br/>PATRONI_* 환경변수"]
  LOCAL["local<br/>patroni.yml"]
  DYN["dynamic<br/>DCS의 config 키"]
  EFF["노드에 적용되는<br/>최종 설정"]
  ENV -->|1순위| EFF
  LOCAL -->|2순위| EFF
  DYN -->|3순위| EFF
  

단 하나의 예외가 있다. 4.4에서 다루는 Patroni 강제 제어 PostgreSQL 파라미터는 local이나 environment에 적어도 무시되고 DCS로만 바뀐다.

dynamic: 클러스터 전체가 공유하는 설정

dynamic configuration은 DCS의 /<namespace>/<scope>/config 키에 저장된다. ttl, loop_wait 같은 클러스터 공통 동작 파라미터와 PostgreSQL GUC가 여기에 들어간다. 변경 수단은 두 가지다.

patronictl -c /etc/patroni/patroni.yml edit-config

REST API의 /config 엔드포인트를 호출해도 된다(Part VIII). 변경은 각 노드의 다음 HA 루프에서 비동기로 반영되며 노드가 reload된다. 재시작이 필요한 파라미터가 바뀐 노드에는 pending_restart 플래그가 붙는다(4.4).

노드는 dynamic configuration이 바뀔 때마다 그 내용을 data directory의 patroni.dynamic.json 파일로 덤프해 둔다. DCS에서 설정이 완전히 사라지거나 깨졌을 때는 leader만 이 덤프에서 복원할 수 있다.

local: 노드별 설정 파일

patroni.yml이 local configuration이다. dynamic configuration보다 우선하므로, 특정 노드만 다른 값을 가져야 하는 설정은 이 계층에 둔다. 파일을 고친 뒤에는 세 가지 방법 중 하나로 재적용한다.

# 1) 시그널
kill -HUP <patroni PID>

# 2) REST API
curl -X POST http://10.0.0.21:8008/reload

# 3) patronictl
patronictl -c /etc/patroni/patroni.yml reload demo

설정을 단일 파일 대신 디렉토리로 지정하는 것도 지원된다. 디렉토리면 파일들을 정렬 순서로 읽고, 같은 키는 마지막 파일 값이 이긴다. 공통 설정 파일과 노드별 오버라이드 파일을 나눠 두는 구성에 쓴다.

environment: 컨테이너를 위한 최우선 계층

PATRONI_ 접두가 붙은 환경변수는 설정 파일 값을 덮어쓴다. Docker처럼 기동 전에 IP를 알 수 없는 환경에서, 이미지 안의 설정 파일은 그대로 두고 주소와 이름만 주입하는 용례가 대표적이다.

export PATRONI_NAME=node1
export PATRONI_SCOPE=demo
export PATRONI_POSTGRESQL_CONNECT_ADDRESS=10.0.0.21:5432
export PATRONI_RESTAPI_CONNECT_ADDRESS=10.0.0.21:8008

이름 규칙에 함정이 하나 있다. 접속 계정 변수는 POSTGRESQL 없이 PATRONI_SUPERUSER_USERNAME, PATRONI_REPLICATION_PASSWORD, PATRONI_REWIND_USERNAME 형태로 쓴다. list 값은 'item1','item2', dict 값은 {key: value} 형식으로 인코딩한다.

PATRONI_CONFIGURATION 환경변수에 설정 전체를 넣으면 그 값이 유일한 설정이 된다. 공식 문서는 이 경우 다른 어떤 환경변수도 고려되지 않는다고 명시한다. 개별 PATRONI_* 변수와 섞어 쓰는 구성은 동작하지 않는다.

계층에 묶인 키

모든 키가 세 계층을 자유롭게 오가는 것은 아니다.

  • DCS로 바꾸지 못하는 키: postgresql.listenpostgresql.data_dir는 설정 파일 또는 환경변수로만 지정한다. 노드마다 다를 수밖에 없는 값이기 때문이다.
  • dynamic 전용 키: ttl(기본 30), loop_wait(기본 10), retry_timeout(기본 10), maximum_lag_on_failover, max_timelines_history, check_timeline, postgresql.use_slots는 클러스터 공통 옵션으로 DCS에서만 관리된다.
  • 환경변수가 없는 섹션: watchdog, tags, bootstrap 섹션은 대응하는 PATRONI_* 변수가 없다. 컨테이너 환경에서도 이 셋은 파일로 구성한다.

bootstrap.dcs는 최초 1회

bootstrap.dcs 아래 내용은 새 클러스터를 처음 초기화한 노드가 DCS의 config 키에 기록하는 초기값이다. 즉 dynamic configuration의 씨앗일 뿐, 그 자체가 계속 살아 있는 설정이 아니다.

공식 문서는 클러스터가 한 번 초기화되어 설정이 DCS에 저장된 뒤에는 patroni.yml의 bootstrap.dcs를 어떻게 고쳐도 아무 효과가 없다고 명시한다. 운영 중인 클러스터의 dynamic configuration은 patronictl edit-config나 REST API /config로만 바뀐다. patroni.yml의 bootstrap.dcs를 고치는 것으로는 바뀌지 않는다.

bootstrap 전체 흐름은 Part V에서 다룬다.

정리

설정은 dynamic, local, environment 세 겹으로 쌓이고 뒤로 갈수록 우선한다. 클러스터 공통 동작은 DCS의 config 키로, 노드 고유 값은 patroni.yml로, 배포 시점에 정해지는 주소는 환경변수로 넣는 배치가 이 우선순위와 맞아떨어진다. bootstrap.dcs는 초기값일 뿐이므로 운영 중 변경은 언제나 edit-config다.