[Docker] docker-compose를 이용해 DB이중화(master-slave) 구성하기

rekv·2025년 3월 20일

Docker

목록 보기
9/12

패키지 구조

project-root/

├── master_db/ # 마스터 DB 관련 폴더
│ ├── data/ # 마스터 DB 데이터 저장 폴더 (볼륨 매핑)
│ ├── conf.d/ # 마스터 DB 설정 파일 (my.cnf 등)
│ │ └── my.cnf
│ └── init-master.sh

├── slave_db/ # 슬레이브 DB 관련 폴더
│ ├── data/ # 슬레이브 DB 데이터 저장 폴더 (볼륨 매핑)
│ ├── conf.d/ # 슬레이브 DB 설정 파일 (my.cnf 등)
│ │ └── my.cnf
│ └── init-slave.sh

└── docker-compose.yml # 마스터-슬레이브를 정의한 Compose 파일

혹은 아래처럼 volumes를 따로 구성해도 좋다.

project-root/
├── master_db/
│ ├── conf.d/
│ └── docker-entrypoint-initdb.d/
├── slave_db/
│ ├── conf.d/
│ └── docker-entrypoint-initdb.d/
├── volumes/
│ ├── master_data/
│ └── slave_data/
└── docker-compose.yml

폴더/파일 설명

폴더/파일설명
master_db/data//var/lib/mysql에 마운트되는 디렉토리. 실제 데이터 파일 저장소
master_db/conf.d/my.cnf/etc/mysql/conf.d/에 마운트되어서 마스터 관련 설정을 넣는 곳 (예: replication 관련 설정)
slave_db/...master_db와 동일한 구조지만 슬레이브 전용 설정이 들어감
docker-compose.yml전체 마스터/슬레이브 서비스를 정의하고 네트워크, 볼륨 매핑 등을 설정하는 파일

여기서 만약 테스트를 하면서 DB가 잘못 구성되면 data패키지는 꼭 지우고 파일을 재실행해야 한다. 그렇지 않으면 초기화 설정이 제대로 동작 안 함 (data 패키지 자체를 지워도 docker-compose를 실행할 때 자동으로 생성되므로 기왕이면 data 패키지 자체를 지워버리자)

.cnf

master.cnf

[mariadb]
log-bin
server_id=1

slave.cnf

[mariadb]
server_id=2

init.sh

master-init.sh

#!/bin/bash

chmod 644 /etc/mysql/conf.d/master.cnf

mariadb -uroot -pqwer1234 -e "CREATE USER 'slave_user'@'%' IDENTIFIED BY 'qwer1234'"
mariadb -uroot -pqwer1234 -e "GRANT REPLICATION SLAVE ON *.* TO 'slave_user'@'%';"
mariadb -uroot -pqwer1234 -e "FLUSH PRIVILEGES;"

만약 docker-compose파일에서 ./db/master/conf:/etc/mysql/conf.d:ro 로 read-only 설정을 했다면 chmode는 빼도 된다.

slave-init.sh

#!/bin/bash

sleep 10

# 마스터 서버의 로그 파일과 포지션 가져오기
echo "Getting master log info..."
master_log_file=$(mariadb -h db_master -uroot -pqwer1234 -e "SHOW MASTER STATUS\G" | grep File: | awk '{print $2}')
master_log_pos=$(mariadb -h db_master -uroot -pqwer1234 -e "SHOW MASTER STATUS\G" | grep Position: | awk '{print $2}')

# 레플리케이션 설정
mariadb -uroot -pqwer1234 -e "
CHANGE MASTER TO
  MASTER_HOST='db_master',
  MASTER_USER='slave_user',
  MASTER_PASSWORD='qwer1234',
  MASTER_LOG_FILE='${master_log_file}',
  MASTER_LOG_POS=${master_log_pos},
  MASTER_PORT=3306;"

# 슬레이브 시작
echo "Starting slave..."
mariadb -uroot -pqwer1234 -e "START SLAVE;"

시작에 sleep 10을 주는 이유는 docker-compose에서 depends_on을 설정했다 하더라도 slave가 켜질 때까지 master container의 세팅이 덜 끝나면 MASTER_HOST를 받아오지 못할 가능성이 있으므로 여유 시간을 주는 것이다.

docker-compose.yml

version: "3.3"
services:
  db_master:
    image: mariadb:latest
    environment:
      MARIADB_ROOT_PASSWORD: qwer1234
    volumes:
      - ./db/master/conf:/etc/mysql/conf.d:ro
      - ./db/master/data:/var/lib/mysql
      - ./db/master/master-init.sh:/docker-entrypoint-initdb.d/master-init.sh
    ports:
      - "3308:3306"
  db_slave:
    image: mariadb:latest
    environment:
      MARIADB_ROOT_PASSWORD: qwer1234
    volumes:
      - ./db/slave/conf:/etc/mysql/conf.d:ro
      - ./db/slave/data:/var/lib/mysql
      - ./db/slave/slave-init.sh:/docker-entrypoint-initdb.d/slave-init.sh
    ports:
      - "3309:3306"
    depends_on:
      - db_master

0개의 댓글