kubernetes 환경에서 Postgres streaming replication 설정
이전 글에서 이어진다.
이전에는 파일을 통해 스냅샷 백업/복원이었다면, 이번에는 postgres의 streaming replication 기능을 이용한 실시간 sync이다.
1. 원본 postgres에서 replication 유저 생성
원본 postgres 내부로 접속
kubectl -n {네임스페이스} exec -it {POD 이름} -- psql -U postgres
replication을 위한 유저 생성
SET password_encryption = 'scram-sha-256';
CREATE ROLE repuser WITH REPLICATION PASSWORD 'mypassword' LOGIN;
SELECT * FROM pg_create_physical_replication_slot('replica_1_slot');
2. 원본 컨테이너 → 노드 설정 파일 복사 및 수정
원본 postgres의 postgresql.conf와 pg_hba.conf 파일을 로컬 노드로 복사
kubectl -n {네임스페이스} cp {POD 이름}:/var/lib/postgresql/data/postgresql.conf postgresql.conf
kubectl -n {네임스페이스} cp {POD 이름}:/var/lib/postgresql/data/pg_hba.conf pg_hba.conf
postgresql.conf에 다음 설정 변경 혹은 추가
wal_level = replica
max_wal_senders = 2
max_replication_slots = 2
synchronous_commit = off
pg_hba.conf에 다음 설정 추가
host replication repuser 0.0.0.0/0 scram-sha-256
3. 원본 postgres 재배포
수정한 파일을 configmap으로 생성 (postgresql.conf와 pg_hba.conf 파일이 master라는 폴더에 있다고 가정)
kubectl -n {네임스페이스} create configmap master-conf-files --from-file master
initContainers를 이용해 수정한 conf 파일이 반영되도록 재배포
volumes:
- name: master-conf
configMap:
name: master-conf-files
initContainers:
- name: init
image: busybox:1.28
command: ['sh', '-c', ' cp /var/lib/postgresql/data/postgresql.main.conf /var/lib/postgresql/data/postgresql.conf && cp /var/lib/postgresql/data/pg_hba.main.conf /var/lib/postgresql/data/pg_hba.conf && chmod 600 /var/lib/postgresql/data/postgresql.conf && chmod 600 /var/lib/postgresql/data/pg_hba.conf']
volumeMounts:
- name: master-conf
mountPath: /var/lib/postgresql/data/postgresql.main.conf
subPath: postgresql.conf
- name: master-conf
mountPath: /var/lib/postgresql/data/pg_hba.main.conf
subPath: pg_hba.conf
4. 복원할 postgres 바닐라 배포 및 postgresql.conf 수정
복원할 postgres의 바닐라 버전 배포 후, postgresql.conf 파일 로컬 노드로 복사
kubectl -n {네임스페이스} cp {POD 이름}:/var/lib/postgresql/data/postgresql.conf postgresql.conf
postgres 12버전 전후로 설정 방법이 다르므로 주의
4-a postgres 11 버전 이하 설정
postgresql.conf 수정
hot_standby = on
wal_level = replica
max_wal_senders = 2
max_replication_slots = 2
synchronous_commit = off
recovery.conf 파일 생성, 원본 postgres의 연결 정보를 환경에 맞게 치환
standby_mode = on
primary_conninfo = 'host=<원본 DB host> port=5432 user=repuser password=mypassword application_name=r1'
primary_slot_name = 'replica_1_slot'
trigger_file = '/var/lib/postgresql/data/change_to_master'
4-b postgres 12 버전 이상 설정
postgresql.conf 수정, 원본 postgres의 연결 정보를 환경에 맞게 치환
hot_standby = on
wal_level = replica
max_wal_senders = 2
max_replication_slots = 2
synchronous_commit = off
primary_conninfo = 'host=<원본 DB host> port=5432 user=repuser password=changeme application_name=r1'
primary_slot_name = 'replica_1_slot' # Name of the replication slot we created on the master
promote_trigger_file = '/var/lib/postgresql/data/change_to_master'
standby.signal 파일 생성 (내용없이 파일만 존재하면 됨)
touch standby.signal
5. postgresql.conf 마운트하여 복원할 postgres 재배포
수정/생성한 파일을 configmap으로 생성 (위에서 생성한 파일이 standby라는 폴더에 있다고 가정)
kubectl -n {네임스페이스} create configmap standby-conf-files --from-file standby
initContainers를 이용해 해당 conf 파일을 적용시켜 복원할 postgres 재배포
5-a. postgres 11 버전 이하 설정
volumes:
- name: standby-config-mnt
configMap:
name: standby-conf-files
initContainers:
- name: init-standby-1
image: <동일한 postgres 이미지>
command: ['sh', '-c', 'PGPASSWORD="mypassword" pg_basebackup -h <원본 DB 호스트> -p 5432 -D /var/lib/postgresql/data -U repuser -vP ']
volumeMounts:
- name: data
mountPath: /var/lib/postgresql/data
subPath: postgres
- name: init-standby-2
image: <동일한 postgres 이미지>
command: ['sh', '-c', 'cp /var/lib/postgresql/data/postgresql.main.conf /var/lib/postgresql/data/postgresql.conf && chmod 600 /var/lib/postgresql/data/postgresql.conf && cp /var/lib/postgresql/data/recovery.main.conf /var/lib/postgresql/data/recovery.conf && chmod 600 /var/lib/postgresql/data/recovery.conf' ]
volumeMounts:
- name: standby-config-mnt
mountPath: /var/lib/postgresql/data/postgresql.main.conf
subPath: postgresql.conf
- name: standby-config-mnt
mountPath: /var/lib/postgresql/data/recovery.main.conf
subPath: recovery.conf
5-b. postgres 12 버전 이상 설정
volumes:
- name: standby-config-mnt
configMap:
name: standby-conf-files
initContainers:
- name: init-standby-1
image: <동일한 postgres 이미지>
command: ['sh', '-c', 'PGPASSWORD="mypassword" pg_basebackup -h <원본 DB 호스트> -p 5432 -D /var/lib/postgresql/data -U repuser -vP ']
volumeMounts:
- name: data
mountPath: /var/lib/postgresql/data
subPath: postgres
- name: init-standby-2
image: <동일한 postgres 이미지>
command: ['sh', '-c', 'cp /var/lib/postgresql/data/postgresql.main.conf /var/lib/postgresql/data/postgresql.conf && chmod 600 /var/lib/postgresql/data/postgresql.conf']
volumeMounts:
- name: standby-config-mnt
mountPath: /var/lib/postgresql/data/postgresql.main.conf
subPath: postgresql.conf
- name: standby-config-mnt
mountPath: /var/lib/postgresql/data/standby.signal
subPath: standby.signal
정상 구동 확인
원본 DB에서 아래 명령어를 입력했을 때 다음과 같이 나오면 성공
SELECT * FROM pg_stat_replication;
분홍색 IP가 복원할 postgres POD ip가 맞다면 성공이다!
참고
https://integralzone.com/kubernetes-configure-postgresql-streaming-replication/