공부/Kubernetes

kubernetes 환경에서 Postgres streaming replication 설정

토고미 2022. 8. 18. 14:45

이전 글에서 이어진다.

https://togomi.tistory.com/76

 

kubernetes 환경에서 Postgres migration 백업 & 복원

들어가기에 앞서.. 이 글은 k8s 환경에서 postgres의 데이터를 migration 하는 방법입니다. 이하의 글은 수동으로 하는 방법이며, 쉘 스크립트를 이용해 자동으로 하고 싶다면 아래 github을 참고해주세

togomi.tistory.com

 

이전에는 파일을 통해 스냅샷 백업/복원이었다면, 이번에는 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');

replication 유저 생성

 

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

pg_hba.conf

 

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;

replicaiton 확인

분홍색 IP가 복원할 postgres POD ip가 맞다면 성공이다!

 

 

참고

https://integralzone.com/kubernetes-configure-postgresql-streaming-replication/