Docker MariaDB의 Master-Slave 자동설정

busybean3·2021년 9월 7일
0

데이터베이스

목록 보기
6/6

이전 포스팅은 Master-Slave 구조를 가지는 Database를 도커를 통해서 수동설정하는 방법을 알아보았습니다.

이번 포스팅은 docker-compose를 통해서 한번에 Master-Slave 구조를 가질 수 있도록 DB container를 생성하고, shell script를 통해서 replication할 DB를 생성과 master slave 구조를 가지도록 하겠습니다. (자동화)

git : [https://github.com/YouJaeBeom/DB_Master-Slave_dockercompose]

🐳 Master-Slave Replication (docker)

해당 디렉토리의 구조를 보도록 하겠습니다.

디렉토리의 구성과 각자 용도

디렉토리의 구성과 각자 용도는 아래와 같습니다.

  • docker-compose.yml : mariadb image를 통해서 Master - Slave DB container를 생성합니다.
  • mariadb_root_password.txt : DB container의 root 비밀번호를 저장하는 파일입니다.
  • master : Master DB container 관련된 데이터가 저장된 파일입니다.
    - master/config/my.cnf*8 : Master DB container를 만들때의 설정 파일입니다.
    -
    master/mysql-init-files/create.sql** : Master DB container를 만들때의 DB 생성 및 권한 설정 등 역할을 하는 파일입니다.
  • slave : Slave DB container 관련된 데이터가 저장된 파일입니다.
    - slave/config/my.cnf : Slave DB container를 만들때의 설정 파일입니다.
    - slave/mysql-init-files/create.sql : Slave DB container를 만들때의 DB 생성 및 권한 설정 등 역할을 하는 파일입니다.
  • run.sh : 전체적으로 docker container를 띄우고 각 DB생성 몇 권한 설정등을 한번에 하는 파일입니다.

🚴단계별로 이제 하나씩 알아보겠습니다.

🔫 1. docker-compose.yml

version: "3.3"

services:
  db_master:
    image: mariadb:10.6.3-focal
    container_name: db_master
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD_FILE: /run/secrets/mariadb_root_password
    volumes:
      - ./master/data:/var/lib/mysql
      - ./master/config/:/etc/mysql/conf.d
      - ./master/mysql-init-files/:/docker-entrypoint-initdb.d/
    ports:
      - "33306:3306"
    secrets:
      - mariadb_root_password

  db_slave:
    image: mariadb:10.6.3-focal
    container_name: db_slave
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD_FILE: /run/secrets/mariadb_root_password
    volumes:
      - ./slave/data:/var/lib/mysql
      - ./slave/config/:/etc/mysql/conf.d
      - ./slave/mysql-init-files/:/docker-entrypoint-initdb.d/
    ports:
      - "43306:3306"
    secrets:
      - mariadb_root_password
    depends_on:
      - db_master

secrets:
  mariadb_root_password:
    file: ./mariadb_root_password.txt

services 내에 두개가 존재하는것을 확인 할 수 있습니다.

db_master 가 Master DB 역할을 하는 것이며, db_slave가 Slave DB 역할을 합니다.

각 옵션별로 살펴보면

  • image 는 mariadb:10.6.3-focal 라는 image name은 mariadb, tag 는 10.6.3-focal 사용했습니다.
  • container_name : 말그대로 docker container를 띄울때의 이름이 됩니다.
  • restart : 이 옵션은 다시 작동할 수 있도록 해줍니다.
  • environment/MYSQL_ROOT_PASSWORD_FILE : container 생성 후 root의 비밀번호를 저장한 파일을 설정함으로서 root 비밀번호를 설정합니다.
  • volumes/./master/data:/var/lib/mysql : 각종 log와 index등이 volume이 저장되는 디렉토리 설정입니다.
  • volumes/./master/config/:/etc/mysql/conf.d : 이전에 나왔던 ./master/config/my.cnf 를 써줌으써 설정을 reference해줍니다.
  • ./master/mysql-init-files/:/docker-entrypoint-initdb.d/ : 이 파일은 이전에 /master/mysql-init-files/create.sql 을 referecnes 해줌으로서 초기에 DB를 생성하고 권한을 설정하도록 해줍니다.
  • ports : 이 옵션은 docker engine에게 각 container에게 포트를 수동으로 설정하게 해줍니다. master 는 33306으로 했고, slave 는 43306 으로 설정햇습니다.
  • depends_on : 이 옵션은 slave 에게만 쓰여져 있는데 이건 slave가 master container를 참조한다는 내용입니다.

🔫 2. master container 설정

기본 디렉토리에서 master 로 이동합니다.

그 후 총 2가지의 파일들을 알아보겠습니다.

master/config/my.cnf

[mysqld]
log-bin=mysql-bin
server-id=1

위와 같이 Master DB container는 설정해줍니다.

master/mysql-init-files/create.sql

CREATE DATABASE dbname; 

##create masteruser and grant privileges
grant all privileges on dbname.* to dbname@'%' identified by 'password';

#replication
grant replication slave on *.* to 'dbname'@'%';

## flushj
flush privileges;

첫번째로는 복제할 데이터베이스를 생성하고, 해당 DB에 권한을 설정합니다.

그 다음 slave에게 replication할 권한을 주고, 저장합니다.

여기서 사용자들은 dbname 이나 password 등만 수정하면 됩니다.

🔫 3. Slave container 설정

기본 디렉토리에서 slave 로 이동합니다.

그 후 총 2가지의 파일들을 알아보겠습니다.

slave/config/my.cnf

[mysqld]
log-bin=mysql-bin
server-id=2
relay-log=relaylog
log-slave_updates=1

위와 같이 Slave DB container는 설정해줍니다.

master/mysql-init-files/create.sql

CREATE DATABASE dbname;

#create masteruser and grant privileges
create user dbname@'%' identified by 'password';
grant all privileges on dbname.* to dbname@'%' identified by 'password';

## flush
flush privileges;

여기서 DB를 만드는 이유는 첫 replication하기 위해서 싱크를 맞추기 위함입니다.

한마디로 master에서 설정한 dbname 과 password를 똑같이 써줍니다.

🔫 4. run.sh

run.sh 이라는 shell script는 이제 모든 과정을 자동화하는 파일입니다.

#!/bin/bash
docker-compose -f ./docker-compose.yml up -d

sleep 5

master_log_file=`mysql -h127.0.0.1 --port 33306 -uroot -ppassword -e "show master status\G" | grep mysql-bin`
master_log_file=${master_log_file}



master_log_file=${master_log_file//[[:blank:]]/}

master_log_file=${${master_log_file}#File:}

echo ${master_log_file}

master_log_pos=`mysql -h127.0.0.1 --port 33306  -uroot -ppassword -e "show master status\G" | grep Position`
master_log_pos=${master_log_pos}


master_log_pos=${master_log_pos//[[:blank:]]/}

master_log_pos=${${master_log_pos}#Position:}

echo ${master_log_pos}


query="CHANGE MASTER TO MASTER_HOST='db_master', MASTER_USER='dbname', MASTER_PASSWORD='rootpassword', MASTER_LOG_FILE='${master_log_file}', MASTER_LOG_POS=${master_log_pos} ,master_port=33306"


mysql -h127.0.0.1 --port 43306 -uroot -psamjung -e "stop slave"
mysql -h127.0.0.1 --port 43306 -uroot -psamjung -e "${query}"
mysql -h127.0.0.1 --port 43306 -uroot -psamjung -e "start slave"

docker-compose.yml 파일을 실행 시켜줌으로서 Master-Slave가 될 DB container를 띄워주게 됩니다.

docker-compose -f ./docker-compose.yml up -d

그 다음은 Master DB container 내에 있는 DB 의 Log_file 값과 Log_position 값을 가져옵니다.

master_log_file=`mysql -h127.0.0.1 --port 33306 -uroot -ppassword -e "show master status\G" | grep mysql-bin`
master_log_file=${master_log_file}



master_log_file=${master_log_file//[[:blank:]]/}

master_log_file=${${master_log_file}#File:}

echo ${master_log_file}

master_log_pos=`mysql -h127.0.0.1 --port 33306  -uroot -ppassword -e "show master status\G" | grep Position`
master_log_pos=${master_log_pos}


master_log_pos=${master_log_pos//[[:blank:]]/}

master_log_pos=${${master_log_pos}#Position:}

echo ${master_log_pos}

그 다음 두개의 값을 slave DB container 내에 있는 DB에게 권한을 줌으로써 완성시키게 됩니다.

query="CHANGE MASTER TO MASTER_HOST='db_master', MASTER_USER='dbname', MASTER_PASSWORD='rootpassword', MASTER_LOG_FILE='${master_log_file}', MASTER_LOG_POS=${master_log_pos} ,master_port=33306"


mysql -h127.0.0.1 --port 43306 -uroot -psamjung -e "stop slave"
mysql -h127.0.0.1 --port 43306 -uroot -psamjung -e "${query}"
mysql -h127.0.0.1 --port 43306 -uroot -psamjung -e "start slave"

🏹 마무리

실행 명령어는 아래와 같습니다.

source run.sh

실행 후 이제 결과를 확인해봐야합니다.

Slave DB container에 접속하여 DB에 들어가도록 합니다.

 ## option 1
docker exec -it db_slave /bin/bash

mysql -u root -p
>> rootpassword

## option 2 
mysql mysql -h127.0.0.1 --port 43306 -uroot -prootpassword

데이터베이스에 들어온 후 아래와 같은 명령어를 사용합니다.

show slave status\G

사용하게 되면 아래와 같은 화면이 나오게 됩니다.

여기서 우리는 Last_Errno 는 0, Last_IO_Errno가 0이면 설정이 완료된것 입니다.

설정을 완료하게 되면 이제 Master container에서 복제설정한 DB에 데이터가 들어가거나 삭제되는경우 Slave DB에도 바로 적용되는 것을 확인 할 수 있습니다.

profile
엉덩이 무거운 개발자가 되기 위해서 몸무게를 찌웠다...

0개의 댓글