docker-compose 는 docker container를 생성하기 위한 명령어들을 미리 적어놓은 문서라고 할 수 있습니다.
이번 글에서는 docker-compose 를 활용하여 mysql master - slave replication 구성된 container들을 올리는 방법을 공유하겠습니다.
본문에서 사용하는 mysql image 는 개인적으로 생성하여 사용하는 이미지이기 때문에 다른 이미지를 사용하는 경우엔 그에 맞게 설정 확인이 필요합니다.
구성
- docker-compose
- mysql_master
- Dockerfile
- docker-entrypoint.sh
- Dockerfile
- mysql_slave
- Dockerfile
- docker-entrypoint.sh
- Dockerfile
- mysql_master
docker-compose.yml
version: '3'
services:
mysql_master:
image: mysql_image:master
user: root
build:
context: ./master
dockerfile: Dockerfile
stdin_open: true
tty: true
ports:
- 13306:3306
networks:
dock_net:
ipv4_address: 172.16.0.10
container_name: mysql_master
restart: always
mysql_slave:
image: mysql_image:slave
build:
context: ./slave
dockerfile: Dockerfile
user: root
stdin_open: true
tty: true
ports:
- 13307:3306
networks:
dock_net:
ipv4_address: 172.16.0.11
depends_on:
- mysql_master
container_name: mysql_slave
networks:
dock_net:
networks:
dock_net:
driver: bridge
ipam:
config:
- subnet: 172.16.0.0/16
- services: 아래로는 이 docker-compose.yml file을 통해 실행하려는 container를 정의함
- mysql_master: 정의하려는 container 서비스의 이름을 mysql_master로 설정
- image: mysql_image:master : container를 띄울 때 사용할 image
- build: image를 build 할 때 Dockerfile을 사용하는 경우 Dockerfile의 위치와 파일명을 기재함
- stdin_open: 사용하는 이미지가 OS 이미지 위에 올린 이미지인 경우 입출력 옵션을 켜줌
- tty: 위와 동일
- port: 외부에 노출할 포트, 여기서 13306 은 호스트의 포트, 3306은 컨테이너의 포트
- netowrks: container 들이 사용할 network 대역을 설정함 ipv4_address를 옵션을 사용하는 경우 container 의 ip를 고정시킬 수 있음
- container_name: container의 이름 설정
- restart: container stop 되면 자동 재기동하도록 설정
Dockerfile
FROM mysql_image:master
MAINTAINER kimdubi
USER root
RUN echo "master" > master.txt
ADD my.cnf /engn001/mysql/
ADD docker-entrypoint.sh /usr/local/bin
RUN chmod 640 /engn001/mysql/my.cnf
RUN chmod 755 /usr/local/bin/docker-entrypoint.sh
ENTRYPOINT ["/usr/local/bin/docker-entrypoint.sh"]
- FROM : build 할 이미지
- USER : 아래 커맨드를 수행할 os user
- ADD : host의 파일이나 디렉토리를 container로 복사
- RUN : container에서 수행할 커맨드
- ENTRYPOINT : container가 생성될 때 처음 수행할 명령어나 스크립트 설정
docker-entrypoint.sh - master
#!/bin/bash
set -e
/engn001/mysql/bin/mysqld --defaults-file=/engn001/mysql/my.cnf &
## create user
sleep 20
/engn001/mysql/bin/mysql -uroot -p'qhdks123' -S /engn001/mysql/data/mysql.sock -e "create user 'replUser'@'172.16.0.%' identified with mysql_native_password"
/engn001/mysql/bin/mysql -uroot -p'qhdks123' -S /engn001/mysql/data/mysql.sock -e "alter user 'replUser'@'172.16.0.%' identified by 'qhdks123'"
/engn001/mysql/bin/mysql -uroot -p'qhdks123' -S /engn001/mysql/data/mysql.sock -e "grant replication slave on *.* to 'replUser'@'172.16.0.%'"
/engn001/mysql/bin/mysql -uroot -p'qhdks123' -S /engn001/mysql/data/mysql.sock -e "flush privileges"
/bin/bash
docker-entrypoint.sh - slave
#!/bin/bash
set -e
rm -rf /engn001/mysql/data/auto.cnf
/engn001/mysql/bin/mysqld --defaults-file=/engn001/mysql/my.cnf &
sleep 30
## create user
/engn001/mysql/bin/mysql -uroot -p'qhdks123' -S /engn001/mysql/data/mysql.sock -e "create user 'replUser'@'172.16.0.%' identified with mysql_native_password"
/engn001/mysql/bin/mysql -uroot -p'qhdks123' -S /engn001/mysql/data/mysql.sock -e "alter user 'replUser'@'172.16.0.%' identified by 'qhdks123'"
/engn001/mysql/bin/mysql -uroot -p'qhdks123' -S /engn001/mysql/data/mysql.sock -e "grant replication slave on *.* to 'replUser'@'172.16.0.%'"
## get status
master_log_file=`/engn001/mysql/bin/mysql -uroot -p'qhdks123' -h 172.16.0.10 -S /engn001/mysql/data/mysql.sock -e"show master status\G" | grep mysql-bin`
re="[a-z]*-bin.[0-9]*"
if [[ ${master_log_file} =~ $re ]];then
master_log_file=${BASH_REMATCH[0]}
fi
master_log_pos=`/engn001/mysql/bin/mysql -uroot -p'qhdks123' -h 172.16.0.10 -S /engn001/mysql/data/mysql.sock -e"show master status\G" | grep Position`
re="[0-9]+"
if [[ ${master_log_pos} =~ $re ]];then
master_log_pos=${BASH_REMATCH[0]}
fi
query="change master to master_host='172.16.0.10', master_user='replUser', master_password='qhdks123', master_log_file='${master_log_file}', master_log_pos=${master_log_pos}, master_port=3306"
mysql -uroot -p'qhdks123' -S /engn001/mysql/data/mysql.sock -e "${query}"
mysql -uroot -p'qhdks123' -S /engn001/mysql/data/mysql.sock -e "start slave"
/bin/bash
실행
- docker-compose 수행 시의 로그
kimdubi:mysql_docker nhn$ ls
clean.sh docker-compose.yml master slave
kimdubi:mysql_docker nhn$ docker-compose -f ./docker-compose.yml up -d --build
Building mysql_master
Step 1/9 : FROM mysql_image:master
---> 0a6c038fd48c
Step 2/9 : MAINTAINER kimdubi
---> Running in 2f7f90ab2a38
Removing intermediate container 2f7f90ab2a38
---> 906a816a4af1
Step 3/9 : USER root
---> Running in f674d01b67b9
Removing intermediate container f674d01b67b9
---> 28837372b10e
Step 4/9 : RUN echo "master" > master.txt
---> Running in ea82391d1d95
Removing intermediate container ea82391d1d95
---> 9cb24b538774
Step 5/9 : ADD my.cnf /engn001/mysql/
---> 3eeebb30422f
Step 6/9 : ADD docker-entrypoint.sh /usr/local/bin
---> 18c0520d5084
Step 7/9 : RUN chmod 640 /engn001/mysql/my.cnf
---> Running in 6c968200e8f3
Removing intermediate container 6c968200e8f3
---> 4c6bfc727322
Step 8/9 : RUN chmod 755 /usr/local/bin/docker-entrypoint.sh
---> Running in 8ac72794f96a
Removing intermediate container 8ac72794f96a
---> 2a37ab0055e4
Step 9/9 : ENTRYPOINT ["/usr/local/bin/docker-entrypoint.sh"]
---> Running in 35ece071e51d
Removing intermediate container 35ece071e51d
---> bcbb9b452b74
Successfully built bcbb9b452b74
Successfully tagged mysql_image:master
Building mysql_slave
Step 1/8 : FROM mysql_image:slave
---> b8eed6c4ccd7
Step 2/8 : MAINTAINER kimdubi
---> Running in a59a8a4dccb3
Removing intermediate container a59a8a4dccb3
---> fb088cfa9516
Step 3/8 : USER root
---> Running in 3405bd1bbaba
Removing intermediate container 3405bd1bbaba
---> 2587b0fbbfc0
Step 4/8 : RUN echo "slave" > slave.txt
---> Running in ca9ad91a7f2d
Removing intermediate container ca9ad91a7f2d
---> e3b52b559e58
Step 5/8 : ADD my.cnf /engn001/mysql/
---> f6a9c3883d80
Step 6/8 : ADD docker-entrypoint.sh /usr/local/bin/docker-entrypoint.sh
---> e84c90cf387b
Step 7/8 : RUN chmod +x /usr/local/bin/docker-entrypoint.sh
---> Running in b2582b17136c
Removing intermediate container b2582b17136c
---> 89fd212c6919
Step 8/8 : ENTRYPOINT ["/usr/local/bin/docker-entrypoint.sh"]
---> Running in add9a60b740f
Removing intermediate container add9a60b740f
---> 97f13bbfae1e
Successfully built 97f13bbfae1e
Successfully tagged mysql_image:slave
Creating mysql_master ... done
Creating mysql_slave ... done
- 결과
kimdubi:mysql_docker nhn$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
7f5f62616ef3 mysql_image:slave "/usr/local/bin/dock…" 25 seconds ago Up 24 seconds 0.0.0.0:13307->3306/tcp mysql_slave
243fc530c1e2 mysql_image:master "/usr/local/bin/dock…" 26 seconds ago Up 25 seconds 0.0.0.0:13306->3306/tcp mysql_master
kimdubi:engn001 nhn$ de mysql_slave /bin/bash
[root@7f5f62616ef3 /]# mysql -uroot -p
Enter password:
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MySQL connection id is 15
Server version: 8.0.17 MySQL Community Server - GPL
Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
MySQL [(none)]>
MySQL [(none)]> show slave status\G;
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 172.16.0.10
Master_User: replUser
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: mysql-bin.000008
Read_Master_Log_Pos: 1085
Relay_Log_File: relay-bin.000002
Relay_Log_Pos: 322
Relay_Master_Log_File: mysql-bin.000008
Slave_IO_Running: Yes
Slave_SQL_Running: Yes