MySQL on Docker Series
1. Master-Slave Replication 구성하기
2. Bridge Network를 이용한 Replication 구성하기
해당 포스팅은 컨테이너 환경에서 MySQL 서버 3대(Master DB 1대, Slave DB 2대)를 구축 것이 목표이다.
Mac OS에 도커를 설치하여 아래와 같이 MySQL 5.7.30 서버 3대를 실행할 예정인데, 볼륨 마운트를 사용할 예정이다.
따라서 마운트할 호스트 디렉토리는 아래와 같다.
// db001 (Master DB)
$ ~/db/db001/data
$ ~/db/db001/conf, ~/db/db001/conf/my.cnf
$ ~/db/db001/log
// db002 (Slave DB-1)
$ ~/db/db002/data
$ ~/db/db002/conf, ~/db/db002/conf/my.cnf
$ ~/db/db002/log
// db003 (Slave DB-2)
$ ~/db/db003/data
$ ~/db/db003/conf, ~/db/db003/conf/my.cnf
$ ~/db/db003/log
MySQL 서버별 각 my.cnf 파일은 아래와 같다.
# Master DB(db001)
[mysqld]
log_bin = mysql-bin
binlog_format = ROW
gtid_mode = ON
enforce-gtid-consistency = true
server-id = 100
log_slave_updates
datadir = /var/lib/mysql
socket = /var/lib/mysql/mysql.sock
symbolic-links = 0
log-error = /var/log/mysql/mysqld.log
pid-file = /var/run/mysqld/mysqld.pid
report_host = db001
[mysqld_safe]
pid-file = /var/run/mysqld/mysqld.pid
socket = /var/lib/mysql/mysql.sock
nice = 0
# Slave DB-1(db002)
[mysqld]
log_bin = mysql-bin
binlog_format = ROW
gtid_mode = ON
enforce-gtid-consistency = true
server-id = 200
log_slave_updates
datadir = /var/lib/mysql
socket = /var/lib/mysql/mysql.sock
symbolic-links = 0
log-error = /var/log/mysql/mysqld.log
pid-file = /var/run/mysqld/mysqld.pid
report_host = db002
[mysqld_safe]
pid-file = /var/run/mysqld/mysqld.pid
socket = /var/lib/mysql/mysql.sock
nice = 0
# Slave DB-2(db003)
[mysqld]
log_bin = mysql-bin
binlog_format = ROW
gtid_mode = ON
enforce-gtid-consistency = true
server-id = 300
log_slave_updates
datadir = /var/lib/mysql
socket = /var/lib/mysql/mysql.sock
symbolic-links = 0
log-error = /var/log/mysql/mysqld.log
pid-file = /var/run/mysqld/mysqld.pid
report_host = db003
[mysqld_safe]
pid-file = /var/run/mysqld/mysqld.pid
socket = /var/lib/mysql/mysql.sock
nice = 0
위처럼 구성을 완료했으면 docker run 명령어를 실행하여 MySQL 서버 3대를 모두 데몬으로 실행한다.
# db001 (Master DB)
$ docker run -it --name db001 -p 3306:3306 \
-v ~/db/db001/data:/var/lib/mysql \
-v ~/db/db001/log:/var/log/mysql \
-v ~/db/db001/conf:/etc/percona-server.conf.d \
-e MYSQL_ROOT_PASSWORD="root" \
-d percona:5.7.30
# db002 (Slave DB-1)
$ docker run -it --name db002 -p 3307:3306 \
-v ~/db/db002/data:/var/lib/mysql \
-v ~/db/db002/log:/var/log/mysql \
-v ~/db/db002/conf:/etc/percona-server.conf.d \
-e MYSQL_ROOT_PASSWORD="root" \
-d percona:5.7.30
# db003 (Slave DB-2)
$ docker run -it --name db003 -p 3308:3306 \
-v ~/db/db003/data:/var/lib/mysql \
-v ~/db/db003/log:/var/log/mysql \
-v ~/db/db003/conf:/etc/percona-server.conf.d \
-e MYSQL_ROOT_PASSWORD="root" \
-d percona:5.7.30

Replication 설정
Replication user 생성(db001)
USER를 생성하기 전에 Master DB(db001)에 접속한다.
$ docker exec -it -uroot db001 /bin/bash
$ mysql -uroot -p # 패스워드는 docker run 명령어 실행 시 설정한 "root"
이후 아래의 명령어를 실행하여 USER 생성한다.
mysql > CREATE USER 'repl'@'%' IDENTIFIED BY 'repl';
mysql > GRANT REPLICATION SLAVE ON *.* TO 'repl'@'%';
그리고 Master DB (db001) 컨테이너의 IP를 알아두자.

Replication user 생성(db002, db003)
Slave DB 2대는 모두 동일한 Master DB를 바라보고 있어야 한다.
따라서 설정은 동일하니 db002, db003 한꺼번에 진행하기로 한다.
Master DB에와 마찬가지로 USER를 생성하기 전에 Slave DB에 접속한다.
# Slave DB-1(db002)
$ docker exec -it -uroot db002 /bin/bash
$ mysql -uroot -p # 패스워드는 docker run 명령어 실행 시 설정한 "root"
# Slave DB-2(db003)
$ docker exec -it -uroot db003 /bin/bash
$ mysql -uroot -p # 패스워드는 docker run 명령어 실행 시 설정한 "root"
이후 각 Slave DB에서 Master DB에 연결한다.
# SlaveDB 2대 동일하게 아래 명령어를 실행
mysql> reset master;
mysql> CHANGE MASTER TO MASTER_HOST='172.17.0.2', \
MASTER_USER='repl', \
MASTER_PASSWORD='repl', \
MASTER_AUTO_POSITION=1;
mysql> START SLAVE;
mysql> show slave status\G

만약 Master DB의 IP 주소가 변경된다면?
MySQL Master DB 컨테이너가 재실행되면서 IP 주소가 변경될 수도 있다.
Master DB 컨테이너의 IP 주소가 변경되면 Slave DB에 각각 접속해서 IP를 수정해야 하는 번거로움이 생긴다.
이러한 문제는 docker bridge network를 이용하여 Replication 구성을 통해 해결할 수 있다.
참고
해당 포스팅은 인프런 인강을 듣고 정리한 내용입니다.