일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | ||||
4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 |
Tags
- RHEL
- 라떼판다 우분투
- Windows 10 Home
- Packstack
- 자작 NAS
- ubuntu
- MySQL
- WireGuard
- MSA
- CentOS 8
- Rocky Linux 8
- RHEL 7
- RHEL 8
- centos 7
- CentOS
- MariaDB
- Rocky Linux
- PostgreSQL
- podman
- Kubernetes
- LattePanda Ubuntu
- haproxy
- Openstack Rocky
- LattePanda
- LattePanda NAS
- RDP Wrap
- 라떼판다
- nextcloud
- openstack
- 라떼판다 NAS
Archives
- Today
- Total
간마늘작업소
[PGSQL] PostgreSQL 이중화 구성 – Repmgr 이용 본문
0.개요
- PostgreSQL 이중화(HA) 구성 방안 중 Repmgr을 이용한 구성 진행.
- PostgreSQL의 이중화 솔루션 중 가장 보편적인 방법은 PGPool-II을 이용하는 것이 있음.
- 다만, 공식 문서 미비 등으로 사용하는데 상당히 불친절함.
- 따라서, PostgreSQL 기반 엔터프라이즈 DBMS 개발사인 EDB에서 제작한 Repmgr을 이용.
- EDB에서 개발 및 지원하지만 Repmgr은 오픈소스로서 배포됨.
- 공식 Github : https://github.com/EnterpriseDB/repmgr
- 공식 사이트 : https://repmgr.org/
1.기본 정보
- OS 방화벽(Firewalld, iptables)과 SELinux는 비활성화 상태로 설정.
- DB Node 정보
- 192.168.0.16 - DB Node 1, Hostname : ha001
- 192.168.0.17 - DB Node 2, Hostname : ha002
- 192.168.0.15 - HA VIP
- PostgreSQL는 PostgreSQL 14로 진행하며 이미 설치되어 있는 것으로 가정.
- 하단 명령어 중 적색 글씨는 DB Node 1에만 적용.
- 하단 명령어 중 청색 글씨는 DB Node 2에만 적용.
2.사전 환경 구성
2.1.Hosts 파일 수정
2.1.1.Hosts 파일 수정
vi /etc/hosts
192.168.0.16 ha001
192.168.0.17 ha002
- DB Node 정보 추가 후 저장.
2.2.SSH Key 생성
su - postgres
cd ~/.ssh
mkdir -p ~/.ssh
cd ~/.ssh
ssh-keygen -t rsa
- 서버의 DB 운영 계정에 대한 SSH Key 생성.
- 기본 값 : postgres
cat id_rsa.pub >> authorized_keys
- SSH Key 변환.
cat authorized_keys
- DB Node 1과 DB Node 2에서 실행한 값이 다름.
- 이 두 값을 복사해서 하나로 합친다음 다시 넣어줘야함.
vi authorized_keys
ssh-rsa (cat authorized_keys 명령어로 확인한 엄청 긴 KEY 값) postgres@ha001
ssh-rsa (cat authorized_keys 명령어로 확인한 엄청 긴 KEY 값) postgres@ha002
- 양 Node에 동일하게 저장.
ssh ha001
ssh ha002
- 계정 비밀번호 없이 로그인이 되는지 확인.
- 확인 후 root 계정으로 전환.
2.3.Sudoers 권한 부여
vi /etc/sudoers
(전략)
postgres ALL=NOPASSWD: /sbin/ip, \
/usr/bin/systemctl start repmgr-14.service, \
/usr/bin/systemctl stop repmgr-14.service
- sudoers 파일 최하단에 내용 추가.
- 서버의 DB 운영 계정이 IP 설정을 root 권한 없이 수정할 수 있도록 하는 설정.
- Failover 시 VIP 할당을 위해서 설정해야함.
- 서버의 DB 운영 계정이 Repmgr을 root 권한 없이 기동/종료할 수 있도록 하는 설정.
- 서버의 DB 운영 계정이 IP 설정을 root 권한 없이 수정할 수 있도록 하는 설정.
2.4.Repmgr 이용을 위한 PostgreSQL 설정
su - postgres
pg_ctl restart -mf
psql
- PostgreSQL 14 기동.
- PostgreSQL 14 Shell 접속.
\du
- 현재 생성되어 있는 계정 및 Role 정보 확인.
- PostgreSQL 12 이상에서 해당 포스트대로 따라했다면 replication 계정이 존재함.
- 해당 계정을 그대로 이용함.
CREATE ROLE replication WITH replication PASSWORD 'password' LOGIN;
- 계정이 존재하지 않거나 다른 계정을 원할 경우 위 SQL 문으로 생성.
- 계정 : replication, PW : password (PW는 선택 사항.)
ALTER USER replication WITH superuser;
CREATE database replication OWNER replication;
- Repmgr 계정에 대한 DB 슈퍼유저 권한 부여.
- Repmgr에서 사용할 파라미터 DB 생성 및 Repmgr 계정을 사용자로 지정.
\l+ replication
\du
- Repmgr 파라미터 DB 정보 확인.
- 현재 생성되어 있는 계정 및 Role 정보에서 Repmgr 계정에 슈퍼유저와 복제 권한이 부여되어 있는지 확인.
cd /data/pgdata/
vi postgresql.conf
(전략)
shared_preload_libraries='repmgr'
- postgresql.conf 파일 하단에 내용 추가.
vi pg_hba.conf
(전략)
# IPv4 local connections:
(중략)
host all all 192.168.0.16/32 trust
host all all 192.168.0.17/32 trust
host all all 0.0.0.0/0 md5
(후략)
- pg_hba.conf 파일 하단에 위치한 '# IPv4 local connections:' 부분에 내용 추가 후 저장.
- 주의사항
- 0.0.0.0/0 설정이 있다면 꼭 그 위의 행에 추가할 것.
- 설정을 위에서부터 읽기 때문에 0.0.0.0/0 설정 아래에 추가한다면 비밀번호를 물어봄.
- 0.0.0.0/0이 md5나 scram-sha-256가 아닌 trust로 되어있다면 상관이 없음.
- md5, scram-sha-256 : 비밀번호 암호화 방식. 로그인시 비밀번호 확인함.
- trust : 로그인시 비밀번호 확인하지 않음.
- 다만, 이렇게 되면 모든 외부 환경에서 비밀번호 없이 접속할 수 있으므로 0.0.0.0/0은 사실상 trust로 설정하지 않음.
- 0.0.0.0/0이 md5나 scram-sha-256가 아닌 trust로 되어있다면 상관이 없음.
- Repmgr은 각 Node 간 비밀번호 없이 접속할 수 있도록 요구함.
3.Repmgr 설치
- Repmgr 버전에 따른 지원 PostgreSQL 버전은 다음과 같음.
- 출처 : Repmgr 공식 문서
yum install repmgr_14*
- PostgreSQL 설치를 위한 공식 사이트 리포지토리 연결시 다운로드 받을 수 있음.
- 위 명령어의 패키지 명 중 '14' 부분에 PostgreSQL 버전을 입력하면 됨.
- ex) PostgreSQL 15를 기반으로 한다면 패키지 명은 'repmgr_15*'로 변경.
cd /etc/repmgr/14
mkdir old
mv repmgr.conf old/repmgr.conf_first
vi repmgr.conf
node_id=1
node_name='ha001'
conninfo='host=ha001 dbname=replication user=replication connect_timeout=2'
data_directory='/data/pgdata'
service_start_command = '/usr/pgsql-14/repmgr/repmgr-pg_ctl.sh start'
service_stop_command = '/usr/pgsql-14/repmgr/repmgr-pg_ctl.sh stop'
service_restart_command = '/usr/pgsql-14/repmgr/repmgr-pg_ctl.sh restart'
service_reload_command = '/usr/pgsql-14/repmgr/repmgr-pg_ctl.sh reload'
failover=automatic
promote_command='/usr/pgsql-14/bin/repmgr standby promote'
follow_command='/usr/pgsql-14/bin/repmgr standby follow --upstream-node-id=%n'
repmgrd_service_start_command = 'sudo systemctl start repmgr-14.service'
repmgrd_service_stop_command = 'sudo systemctl stop repmgr-14.service'
log_file='/usr/pgsql-14/repmgr/repmgr.log'
reconnect_attempts=3
reconnect_interval=3
#monitoring_history=yes
#monitor_interval_secs=10
event_notification_command='/usr/pgsql-14/repmgr/promote.sh %n %e'
event_notifications='standby_promote'
- Repmgr 설정
- node_id : Repmgr에서 사용하는 Node의 고유 ID 값. Node들 끼리 겹치면 안됨.
- node_name : DB Node 이름. 혼동 방지를 위해 Hostname을 권고.
- conninfo :
- host : DB Node의 Hostname.
- dbname : Repmgr이 사용할 파라미터 DB.
- user : Repmgr 계정.
- data_directory : DB 디렉토리 위치.
- service_*_command : PostgreSQL 실행/중지/재시작/리로드 명령어.
- log_file : log 파일 생성 위치.
- event_notification_command : Failover 발생시 실행할 명령어.
4.Repmgr 스크립트 작성
su - postgres
mkdir -p /usr/pgsql-14/repmgr
cd /usr/pgsql-14/repmgr
- Repmgr 동작 중 사용할 스크립트들을 배치할 디렉토리 생성.
vi repmgr-pg_ctl.sh
#!/bin/bash
REPMGR_USER=postgres
PGUSER_HOME=`cat /etc/passwd | grep ${REPMGR_USER} | cut -d: -f6`
. ${PGUSER_HOME}/*_env.sh
UNAME=`id -u -n`
while true
do
case "$1" in
start)
pg_ctl start
exit 0
;;
restart)
pg_ctl restart -mf
exit 0
;;
stop)
pg_ctl stop -mf
exit 0
;;
reload)
pg_ctl reload
exit 0
;;
*)
echo "잘못된 명령입니다."
exit 0
;;
esac
done
- repmgr-pg_ctl.sh : root 계정으로 PostgreSQL을 실행할 때 사용하는 스크립트.
- repmgr.conf에 지정되어 있음.
vi promote.sh
#!/bin/bash
UP_NODEID=$1
EVENT_TYPE=$2
if [ ${EVENT_TYPE} == 'standby_promote' ]; then
declare -A servers
if [ ${UP_NODEID} == 1 ] ; then
UP_NODENUM=1
DOWN_NODENUM=2
else
UP_NODENUM=2
DOWN_NODENUM=1
fi
SERVERS[2]=ha002
SERVERS[1]=ha001
sudo /sbin/ip addr add 192.168.0.15/32 dev eth0:1
SSH_CONNETION=`ssh -o ConnectTimeout=5 postgres@${SERVERS[${DOWN_NODENUM}]} echo ok 2>&1`
while [[ "$SSH_CONNETION" != "ok" ]]
do
sleep 2
echo "Failed node ${SERVERS[${DOWN_NODENUM}]} is not reachable" >> /usr/pgsql-14/repmgr/repmgr.log
unset SSH_CONNETION
SSH_CONNETION=`ssh -o ConnectTimeout=5 postgres@${SERVERS[${DOWN_NODENUM}]} echo ok 2>&1`
done
bash /usr/pgsql-14/repmgr/session_kill.sh &
sleep 1
ssh postgres@${SERVERS[${DOWN_NODENUM}]} '/usr/pgsql-14/repmgr/failover-restore.sh'
fi
- promote.sh : Failover 발생시 Repmgr 프로세스가 자동으로 실행할 스크립트.
- 기존 Standby Node에서 실행됨.
- Repmgr이 Standby Node를 신규 Primary Node로 변경했으므로 VIP를 추가함.
- 장애 발생 Node를 SSH 접속 시도를 하며 2초 간격으로 상태를 체크.
- 장애 발생 Node의 상태가 확인되면 SSH로 접속하여 신규 Standby Node로 전환하는 스크립트 실행.
- '${UP_NODEID} == 1'에서 1은 DB Node 1의 node_id를 의미.
- node_id 값을 1, 2가 아닌 다른 숫자로 했다면 여기에 맞춰서 UP_NODENUM 값과 DOWN_NODENUM 값을 변경해줘야함.
- DB Node 2에서 스크립트를 작성한다 하더라도 기준은 DB Node 1의 node_id에 맞춰서 작성.
- 해당 부분은 DB Node 1과 DB Node 2의 내용이 같아야함.
- 기존 Standby Node에서 실행됨.
vi failover-restore.sh
#!/bin/bash
UNAME=`id -u -n`
REPMGR_USER=postgres
PGDATA=/data/pgdata
PGUSER_HOME=`cat /etc/passwd | grep ${REPMGR_USER} | cut -d: -f6`
. ${PGUSER_HOME}/*_env.sh
if [ e$UNAME != "e$REPMGR_USER" ]
then
echo "Use ${REPMGR_USER} account to start Script..."
exit;
fi
sleep 1
sudo /sbin/ip addr del 192.168.0.15/32 dev eth0:1
pg_ctl stop -mf
sleep 2
rm -rf ${PGDATA}
ls -l ${PGDATA}/..
sleep 2
repmgr -h @@상대 노드@@ -U replication -d replication standby clone
sleep 2
pg_ctl start
sleep 1
repmgr standby register -F
sudo systemctl stop repmgr-14.service
sleep 1
sudo systemctl start repmgr-14.service
- failover-restore.sh : Failover 발생시 장애 발생 Node를 Standby Node로 전환해주는 스크립트.
- 신규 Primary Node가 SSH로 장애 발생 Node로 접속해 실행.
- 등록되어 있던 VIP 해제.
- 기존 PostgreSQL DB 디렉토리 제거
- Repmgr을 이용하여 Primary Node에서 새롭게 DB 디렉토리 다운로드.
- @@상대 노드@@에다 자기 자신이 아닌 상대 Node의 IP 혹은 Hostname 등록.
- 신규 Primary Node가 SSH로 장애 발생 Node로 접속해 실행.
vi session_kill.sh
#!/bin/bash
while true
do
PGSQL_STATUS=`/usr/pgsql-14/bin/repmgr cluster show | grep @@상대 노드@@ | awk -F'|' '{print $3}' | awk -F' ' '{print $1}'`
if [ "${PGSQL_STATUS}" == "" ]; then
unset PGSQL_STATUS
sleep 5
else
SSH_PID=`ps -ef | grep -v grep | grep ssh | grep failover | awk '{print $2}'`
if [ "${SSH_PID}" != "" ]; then
SHUTDOWN_PID=`ps -ef | grep -v grep | grep repmgr | grep 'standby promote' | awk '{print $2}'`
sleep 30
kill -9 ${SSH_PID} ${SHUTDOWN_PID}
exit 0
else
unset SSH_PID
sleep 5
fi
fi
done
- session_kill.sh : 필자가 구성하는 과정에서 promote.sh 실행 후 장애 발생 Node로 SSH 접속을 했고 장애 발생 Node가 정상적으로 신규 Standby Node가 되었음에도 불구하고 SSH 접속 프로세스가 정리되지 않아서 이를 해결하기 위해 작성한 스크립트.
- 장애 발생 Node가 정상적으로 신규 Standby Node가 된 것을 백그라운드에서 5초 간 체크.
- 신규 Standby Node를 확인하면 30초 이후 SSH 접속 프로세스와 Repmer의 Failover 프로세스를 정리.
- @@상대 노드@@에다 자기 자신이 아닌 상대 Node의 IP 혹은 Hostname 등록.
chmod +x *.sh
- 작성한 4개의 스크립트에 대한 실행 권한 부여.
5.Repmgr 실행
- Primary Node : DB Node 1
- Standby Node : DB Node 2
5.1.Primary Node
su - postgres
pg_ctl restart -mf
ps -ef | grep -v grep | grep -v ps | grep -v su | grep -v bash | grep postgres
- PostgreSQL 재시작.
- PostgreSQL 프로세스 확인.
repmgr primary register
- Repmgr Cluster에 Primary Node로 등록.
repmgr cluster show
sudo systemctl start repmgr-14.service
- Repmgr Cluster 확인.
- Repmgr 프로세스 기동.
sudo /sbin/ip addr add 192.168.0.15/32 dev eth0:1
ip addr
- VIP 등록.
- VIP 등록 확인.
5.2.Standby Node
su - postgres
cd /data
rm -rf pgdata
- 기존 생성되어 있던 DB 디렉토리 삭제.
repmgr -h ha001 -U replication -d replication standby clone
- Repmgr을 이용하여 Primary Node에서 새롭게 DB 디렉토리 다운로드.
pg_ctl start
ps -ef | grep -v grep | grep -v ps | grep -v su | grep -v bash | grep postgres
- PostgreSQL 시작.
- PostgreSQL 프로세스 확인.
repmgr standby register -F
- Repmgr Cluster에 Standby Node로 등록.
repmgr cluster show
sudo systemctl start repmgr-14.service
- Repmgr Cluster 확인.
- Repmgr 프로세스 기동.
6.Failover Test 시나리오
6.1.DB 서비스 종료
pg_ctl stop -mf
repmgr cluster show
- DB Node 1의 PostgreSQL 서비스를 종료.
- 이후 repmgr cluster show로 Repmgr Cluster 상태 확인.
- DB Node 2가 Primary Node가 되고 DB Node 1이 Standby Node가 되면 정상.
- VIP 전환 확인.
6.2.서버 재부팅
- PostgreSQL 서비스를 종료하지 않고 Primary Node의 서버를 재부팅.
- 이후 Standby Node에서 repmgr cluster show로 Repmgr Cluster 상태 확인.
- 기존 Standby Node가 Primary Node가 되고 장애 발생 Node가 재부팅된 이후에 Standby Node가 되면 정상.
- VIP 전환 확인.
6.3.Primary - Standby 전환
su - postgres
repmgr standby switchover
- Standby Node에서 명령어 실행.
- 기존 Standby Node가 Primary Node가 되고 Primary Node가 Standby Node가 되면 정상.
- VIP 전환 확인.
7.참고 문서
'Linux > 31.PostgreSQL' 카테고리의 다른 글
[PGSQL] PostgreSQL 11 – 02.Replication(복제) 설정 (0) | 2022.07.05 |
---|---|
[PGSQL] PostgreSQL 14 – 02.Replication(복제) 설정 (0) | 2022.07.04 |
[PGSQL] PostgreSQL 15 – 01.설치 (0) | 2022.07.04 |
Comments