도커를 이용한 PostgreSQL (원격) <-> PostgreSQL (로컬) 연동
by Cori원격 서버에 저장된 PostgreSQL 데이터베이스의 데이터를 로컬로 가져올 필요가 있어 방법을 정리한다.
원격 서버의 PostgreSQL DB 접속
- 원격 서버 -
원격 서버에서 PostgreSQL의 5432 포트가 외부에서 접근 가능하도록 방화벽 규칙을 설정해준다.
sudo ufw allow 5432/tcp
PostgreSQL 컨테이너를 실행하고, 해당 컨테이너로 진입하자.
docker run -it --name postgres-container -p 5432:5432 [PostgreSQL Docker Image]
docker exec -it postgres-container /bin/bash
컨테이너 내부에서 PostgreSQL 설정 파일(postgresql.conf 및 pg_hba.conf)을 수정해주어야 한다.
각 파일은 '/var/lib/postgresql/data/' 경로 상에 위치해있을 확률이 높다.
'''postgres.conf'''
listen_addresses = '*'
'''pg_hba.conf'''
host all all 0.0.0.0/0 md5
파일이 보이지 않는다면, echo $PGDATA로 위치를 확인할 수 있다.
파일 수정을 완료하고 나면, 컨테이너를 재시작해줘야 한다.
docker restart my_postgres_container # postgresql 컨테이너 재실행
- 로컬 호스트 -
위 설정을 모두 마쳤다면, 로컬 PostgreSQL 컨테이너에서 서버의 PostgreSQL 컨테이너로 원격 접속할 수 있다.
psql -h [server ip] -U [user name] -d [db name] -p 5432
원격 PostgreSQL 데이터베이스 실시간 동기화
PostgreSQL에서는 Master - Slave 개념으로 데이터베이스 이중화를 지원한다.
Master 서버의 데이터베이스는 데이터를 읽고 쓰는 것이 가능하며, Slave 서버의 데이터베이스는 읽기만 가능하다.
구현하는 과정에서 상당한 삽질을 했지만, 여기서는 성공한 방법만 소개하고, 삽질 로그는 생략하려 한다.
우선 PostgreSQL 도커 컴포즈 파일이 필요한데, Master 도커 파일과 Slave 도커 파일을 따로 작성했다.
'''docker-compose-master.yaml'''
version: "3"
services:
postgresql-master:
image: bitnami/postgresql
restart: always
ports:
- '5432:5432'
volumes:
- [volume name]:/bitnami/postgresql
- ./00_init.sql:/docker-entrypoint-initdb.d/db.sql # init.sql 파일을 컨테이너 내부의 init 파일과 매핑
environment:
- POSTGRESQL_PGAUDIT_LOG=READ,WRITE
- POSTGRESQL_LOG_HOSTNAME=true
- POSTGRESQL_REPLICATION_MODE=master
- POSTGRESQL_REPLICATION_USER=[replication user id]
- POSTGRESQL_REPLICATION_PASSWORD=[replication user password]
- POSTGRESQL_USERNAME=[db user name]
- POSTGRESQL_PASSWORD=[db user password]
- POSTGRESQL_DATABASE=[db name]
- ALLOW_EMPTY_PASSWORD=yes
networks:
- [network name]
volumes:
[volume name]: # 서버에 도커 볼륨이 있는 경우 해당 볼륨 사용
external: true
networks:
[network name]: # 서버에 도커 네트워크가 있는 경우 해당 네트워크 사용
external: true
docker-compose-master 파일에서는 다음을 신경써줘야 한다.
- 데이터베이스 기본 세팅을 위한 init.sql 파일을 volume으로 전달
- 데이터를 저장하기 위한 volume 지정
- 다른 컨테이너와 통신하기 위한 network 지정
* 서버에 이미 생성되어 있는 네트워크와 볼륨을 사용하기 위해, external: true 옵션으로 명시해주었다.
'''docker-compose-slave.yaml'''
version: "3"
services:
postgresql-slave:
image: bitnami/postgresql
restart: always
volumes:
- [volume name]:/bitnami/postgresql
ports:
- '5432:5432'
environment:
- POSTGRESQL_PASSWORD=[PostgreSQL Password]
- POSTGRESQL_MASTER_HOST=[Master 서버의 IP 주소]
- POSTGRESQL_PGAUDIT_LOG=READ
- POSTGRESQL_LOG_HOSTNAME=true
- POSTGRESQL_REPLICATION_MODE=slave
- POSTGRESQL_REPLICATION_USER=[replication user id]
- POSTGRESQL_REPLICATION_PASSWORD=[replication user password]
- POSTGRESQL_MASTER_PORT_NUMBER=5432 # [Master server postgres port]
- ALLOW_EMPTY_PASSWORD=yes
networks:
- [network name]
volumes:
[volume name]:
external: true
networks:
[network name]:
external: true
docker-compose-slave.yaml 파일은 master 서버의 세팅을 사용하기에, 따로 init 파일을 만들지 않아도 된다.
파일 작성을 완료하였다면, 우선 docker-compose.master.yaml 파일을 컴포즈하고, 접속하자.
docker compose -f docker-compose-master.yaml up -d postgresql-slave
docker exec -u root -it postgres_postgresql-master_1 /bin/bash
master 서버에서는 두가지 파일 (postgresql.conf, pg_hba.conf)을 수정해야 한다.
postgresql.conf 파일에서는 복제 관련, pg_hba.conf 파일에서는 슬레이브 서버 접속 허용을 설정한다.
'''postgresql.conf'''
wal_level = replica
max_wal_senders = 3
wal_keep_size = 64
listen_addresses = '*'
'''pg_hba.conf'''
host replication your_user 슬레이브_IP/32 md5
설정이 완료되었다면, 슬레이브 서버를 컴포즈하고 접속해보자.
docker compose -f docker-compose-slave.yaml up -d postgresql-slave
docker exec -u root -it docker-postgresql-slave-1 /bin/bash
slave 컨테이너에서, master 컨테이너의 데이터를 조회할 수 있다.
추가적인 설정을 따로 하지 않아도, 실시간으로 반영된다 !
슬레이브 서버에서 데이터를 조작하려고 하면, 다음과 같이 오류가 발생하는 것을 볼 수 있다.
원격 PostgreSQL 데이터베이스 백업하기
PostgreSQL 서버가 실행 중일 때 직접 복사하는 것보다는 pg_dump 같은 백업 도구를 사용하는 것이 더 안전하다.
pg_dump -h [원격 서버 ip] -U [user name] -d [db name] > [local/backup/your_db_backup.sql]
백업 파일은 다음과 같이 복원할 수 있다.
psql -U [user name] -d postgres -c "CREATE DATABASE restored_db;"
psql -U [user name] -d restored_db -f [백업 파일 경로.sql]
참고자료
'CS > Database' 카테고리의 다른 글
다른 컴퓨터에서 MySQL 서버 원격 접속 설정하기 (0) | 2024.05.24 |
---|---|
MySQL 찍먹하기 !! (feat.pymysql) (2) | 2024.01.30 |
블로그의 정보
코딩하는 오리
Cori