目的
AlpineLinux3.17をベースで、MySQLdockerカスタムイメージを構築し、
Kubernetes構築を実施前に、予め以下構成で、レプリケーション構成を構築できるかをテストするのが目的となります。
- MySQL Masterコンテナ(1つ)
- MySQL Slaveコンテナ(1つ)
※今回は、自動フェイルオーバー機能はつけず、純粋にデータが複製できるかの観点を確認します。(今後確認予定です。)
構築準備・事前作業
構築観点として、イメージをdocker-composeでビルドし、MySQLのMasterとSlaveのDockerコンテナを起動します。
イメージをビルドする際、MySQLのalpineイメージはないので、
AlpineLinuxのdockerイメージをベースとし、MySQLをインストールします。
初期状態のデータベースでは、レプリケーションは自動開始しないので、
適切な設定(後述)をし、レプリケーションを行います。
- docker-compose.yml
version: '3.7'
services:
master:
container_name: t_kyn_001_mysql_master
build:
context: .
dockerfile: ./Dockerfile
volumes:
- ./master/conf/:/conf
- ./mastersetup.sh:/usr/local/bin/setup.sh
- ./master_log/:/var/log/mysql/
- ./master_db:/var/lib/mysql
- ./master/conf/my.cnf:/etc/my.cnf
tty: true
environment:
TZ: 'Asia/Tokyo'
MYSQL_USER: 'mysql'
MYSQL_PASSWORD: '★!秘密!★'
MYSQL_ROOT_PASSWORD: 'master'
command: >
/bin/sh -c "
cp /conf/my.cnf /etc/ &&
chmod 644 /etc/my.cnf &&
chmod 755 /entrypoint.sh &&
/entrypoint.sh mysqld"
networks:
- demo-network
slave:
container_name: t_kyn_001_mysql_slave
build:
context: .
dockerfile: ./Dockerfile
volumes:
- ./slave/conf/:/conf
- ./slavesetup.sh:/usr/local/bin/setup.sh
- ./slave_log/:/var/log/mysql/
- ./slave_db:/var/lib/mysql
- ./slave/conf/my.cnf:/etc/my.cnf
tty: true
environment:
TZ: 'Asia/Tokyo'
MYSQL_USER: 'mysql'
MYSQL_PASSWORD: '★!秘密!★'
MYSQL_ROOT_PASSWORD: 'slave'
command: >
/bin/sh -c "
cp /conf/my.cnf /etc/ &&
chmod 644 /etc/my.cnf &&
chmod 755 /entrypoint.sh &&
/entrypoint.sh mysqld"
networks:
- demo-network
volumes:
master_db: {}
master_log: {}
slave_db: {}
slave_log: {}
networks:
demo-network:
driver: bridge
- entrypoint.sh
MySQLコマンドを実行し以下を定義します。- データベースのインストールディレクトリ先の指定
- mysqld_safeで起動し、MySQLポートでの疎通確認
- MYSQL_ROOT_PASSWDをルートアカウント用のパスワードに設定
- MySQL再起動反映
- ログ出力先の権限変更
※「★!秘密!★」のところはMySQLのパスワードなので、参考にする場合は良しなに変更頂ければと思います。
#! /bin/sh
mysql_install_db --user=mysql --datadir=/var/lib/mysql
sed -i "s|.*skip-networking.*|#skip-networking|g" /etc/my.cnf.d/mariadb-server.cnf
mysqld_safe --datadir=/var/lib/mysql/ &
nc -zv 0.0.0.0 3306 &> /dev/null
while [[ $? == 1 ]]
do
nc -zv 0.0.0.0 3306 &> /dev/null
done
apk del netcat-openbsd
export MYSQL_ROOT_PASSWD='★!秘密!★'
mysql -e "use mysql;select User, host from mysql.user;grant all privileges on *.* to 'root'@'%' identified by '$MYSQL_ROOT_PASSWD' with grant option;flush privileges;"
mysqladmin shutdown
mysqld_safe --datadir=/var/lib/mysql
chown -R mysql:mysql /var/log/mysql/
chmod 777 /var/log/mysql/
chmod 640 /var/log/mysql/*
- mastersetup.sh
Master構成のdockerの/etc/my.cnfに対して、server-idを自動割り振りするスクリプトです。
#!/bin/sh
OCTETS=`hostname -i | tr -s '.' ' '`
i=3
set $OCTETS
if [ $i -ge 10 ]
then
i=`expr $i - 9`
shift 9
fi
v1="v1=\$$i"
eval $v1
i=4
if [ $i -ge 10 ]
then
i=`expr $i - 9`
shift 9
fi
v2="v2=\$$i"
eval $v2
MYSQL_SERVER_ID=`expr $v1 \* 256 + $v2`
sed -i -e "/# START/,/# END/ s/SERVER_ID/$MYSQL_SERVER_ID/g" /etc/my.cnf
sed -i -e '/# START/,/# END/ s/# server_id/server_id/g' /etc/my.cnf
sed -i -e '/# START/,/# END/ s/# log_bin/log_bin/g' /etc/my.cnf
- slavesetup.sh
SLAVE構成のdockerの/etc/my.cnfに対して、server-idを自動割り振りするスクリプトです。
mastersetup.shと内容同じなので、分ける必要もなかったのですが、今後自動フェイルオーバの検証も行うことを視野に入れたので、いったんは分離しています。
#!/bin/sh
OCTETS=`hostname -i | tr -s '.' ' '`
i=3
set $OCTETS
if [ $i -ge 10 ]
then
i=`expr $i - 9`
shift 9
fi
v1="v1=\$$i"
eval $v1
i=4
if [ $i -ge 10 ]
then
i=`expr $i - 9`
shift 9
fi
v2="v2=\$$i"
eval $v2
MYSQL_SERVER_ID=`expr $v1 \* 256 + $v2`
sed -i -e "/# START/,/# END/ s/SERVER_ID/$MYSQL_SERVER_ID/g" /etc/my.cnf
sed -i -e '/# START/,/# END/ s/# server_id/server_id/g' /etc/my.cnf
sed -i -e '/# START/,/# END/ s/# log_bin/log_bin/g' /etc/my.cnf
イメージ作成・docker-compose実行
docker-composeコマンドで実行します。
[root@t_kyn029 mysqldocker]# docker-compose up -d
Creating network "mysqldocker_demo-network" with driver "bridge"
Creating volume "mysqldocker_master_db" with default driver
Creating volume "mysqldocker_master_log" with default driver
Creating volume "mysqldocker_slave_db" with default driver
Creating volume "mysqldocker_slave_log" with default driver
Building master
Step 1/6 : FROM alpine:3.17
---> 9ed4aefc74f6
Step 2/6 : RUN apk update && apk add --no-cache mysql mysql-client netcat-openbsd bash
---> Using cache
---> adbc751cf7a4
Step 3/6 : EXPOSE 3306
---> Using cache
---> 25512abf06cd
Step 4/6 : COPY ./entrypoint.sh /entrypoint.sh
---> 2373650f235f
Step 5/6 : ENTRYPOINT sh entrypoint.sh
---> Running in b0e175661d7f
Removing intermediate container b0e175661d7f
---> a268564e1443
Step 6/6 : VOLUME /var/lib/mysql:/var/lib/mysql
---> Running in 0fcb19283f5e
Removing intermediate container 0fcb19283f5e
---> f1b5afdc83f8
Successfully built f1b5afdc83f8
Successfully tagged mysqldocker_master:latest
WARNING: Image for service master was built because it did not already exist. To rebuild this image you must use `docker-compose build` or `docker-compose up --build`.
Building slave
Step 1/6 : FROM alpine:3.17
---> 9ed4aefc74f6
Step 2/6 : RUN apk update && apk add --no-cache mysql mysql-client netcat-openbsd bash
---> Using cache
---> adbc751cf7a4
Step 3/6 : EXPOSE 3306
---> Using cache
---> 25512abf06cd
Step 4/6 : COPY ./entrypoint.sh /entrypoint.sh
---> Using cache
---> 2373650f235f
Step 5/6 : ENTRYPOINT sh entrypoint.sh
---> Using cache
---> a268564e1443
Step 6/6 : VOLUME /var/lib/mysql:/var/lib/mysql
---> Using cache
---> f1b5afdc83f8
Successfully built f1b5afdc83f8
Successfully tagged mysqldocker_slave:latest
WARNING: Image for service slave was built because it did not already exist. To rebuild this image you must use `docker-compose build` or `docker-compose up --build`.
Creating t_kyn_001_mysql_slave ...
Creating t_kyn_001_mysql_master ...
Creating t_kyn_001_mysql_slave ... done
Creating t_kyn_001_mysql_master ... done
[root@t_kyn029 mysqldocker]#
レプリケーション可能かの確認
初期状態ではデータベースは何も入っておらず、レプリケーションはされない状況となります。
レプリケーションをするための初期設定を行います。
ここで
- MasterのDocker内部に入り、データベースに接続し、
レプリケーション用のユーザ及びパスワードを設定します。
★!レプリケーション用パスワード!★は変更してください。
[root@t_kyn029 mysqldocker]# docker exec -it t_kyn_001_mysql_master mysql -u root -p mysql
Enter password:
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MariaDB connection id is 4
Server version: 10.6.12-MariaDB-log MariaDB Server
Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
(master) [mysql] > SHOW VARIABLES LIKE 'log_bin';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| log_bin | ON |
+---------------+-------+
1 row in set (0.001 sec)
(master) [mysql] > CREATE USER 'repl'@'%' IDENTIFIED BY '★!レプリケーション用パスワード!★';
Query OK, 0 rows affected (0.001 sec)
(master) [mysql] > GRANT REPLICATION SLAVE ON *.* TO 'repl'@'%' IDENTIFIED BY '★!レプリケーション用パスワード!★';
Query OK, 0 rows affected (0.001 sec)
(master) [mysql] > SHOW MASTER STATUS;
+--------------------+----------+--------------+------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+--------------------+----------+--------------+------------------+
| mariadb-bin.000003 | 706 | | |
+--------------------+----------+--------------+------------------+
1 row in set (0.000 sec)
(master) [mysql] > exit
Bye
[root@t_kyn029 mysqldocker]#
- レプリケーション先のSlaveのDocker内部に入り、データベースに接続します。
STOP SLAVEを実行し、レプリケーションを停止したうえで、以下を設定します。- Masterのホスト名:MASTER_HOST
- Masterのポート番号:MASTER_PORT
- Masterのユーザ:MASTER_USER(レプリケーション用のユーザ)
- Masterのパスワード:MASTER_PASSWORD(レプリケーション用のパスワード)
- Masterのログポジション:MASTER_LOG_POS
[root@t_kyn029 mysqldocker]# docker exec -it t_kyn_001_mysql_slave mysql -u root -p mysql
Enter password:
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MariaDB connection id is 3
Server version: 10.6.12-MariaDB MariaDB Server
Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
(slave) [mysql] > STOP SLAVE;
Query OK, 0 rows affected, 1 warning (0.000 sec)
(slave) [mysql] > CHANGE MASTER TO MASTER_HOST='t_kyn_001_mysql_master', MASTER_PORT=3306 ,MASTER_USER='repl',MASTER_PASSWORD='★!レプリケーション用パスワード!★' , MASTER_LOG_FILE='mariadb-bin.000003', MASTER_LOG_POS=706;
Query OK, 0 rows affected (0.062 sec)
(slave) [mysql] > START SLAVE;
Query OK, 0 rows affected (0.002 sec)
(slave) [mysql] > show slave status\G;
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: t_kyn_001_mysql_master
Master_User: repl
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: mariadb-bin.000003
Read_Master_Log_Pos: 706
Relay_Log_File: mysqld-relay-bin.000002
Relay_Log_Pos: 557
Relay_Master_Log_File: mariadb-bin.000003
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
Replicate_Do_DB:
Replicate_Ignore_DB:
Replicate_Do_Table:
Replicate_Ignore_Table:
Replicate_Wild_Do_Table:
Replicate_Wild_Ignore_Table:
Last_Errno: 0
Last_Error:
Skip_Counter: 0
Exec_Master_Log_Pos: 706
Relay_Log_Space: 867
Until_Condition: None
Until_Log_File:
Until_Log_Pos: 0
Master_SSL_Allowed: No
Master_SSL_CA_File:
Master_SSL_CA_Path:
Master_SSL_Cert:
Master_SSL_Cipher:
Master_SSL_Key:
Seconds_Behind_Master: 0
Master_SSL_Verify_Server_Cert: No
Last_IO_Errno: 0
Last_IO_Error:
Last_SQL_Errno: 0
Last_SQL_Error:
Replicate_Ignore_Server_Ids:
Master_Server_Id: 1
Master_SSL_Crl:
Master_SSL_Crlpath:
Using_Gtid: No
Gtid_IO_Pos:
Replicate_Do_Domain_Ids:
Replicate_Ignore_Domain_Ids:
Parallel_Mode: optimistic
SQL_Delay: 0
SQL_Remaining_Delay: NULL
Slave_SQL_Running_State: Slave has read all relay log; waiting for more updates
Slave_DDL_Groups: 0
Slave_Non_Transactional_Groups: 0
Slave_Transactional_Groups: 0
1 row in set (0.001 sec)
ERROR: No query specified
(slave) [mysql] > exit
Bye
[root@t_kyn029 mysqldocker]#
データがレプリケーションされるか確認
データがSlave側にレプリケーションされるか確認します。
Master側のDocker内部に入り、データベースに接続します。
適当にデータベース作成、テーブルを作成します。
[root@t_kyn029 mysqldocker]# docker exec -it t_kyn_001_mysql_master mysql -u root -p mysql
Enter password:
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MariaDB connection id is 6
Server version: 10.6.12-MariaDB-log MariaDB Server
Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
(master) [mysql] > create database unkomandbrepltest;
Query OK, 1 row affected (0.001 sec)
(master) [mysql] > use unkomandbrepltest
Database changed
(master) [unkomandbrepltest] > create table unkomantable (id int);insert into unkomantable values (1) ;insert into unkomantable values (2);sel ect * from unkomantable;
Query OK, 0 rows affected (0.008 sec)
Query OK, 1 row affected (0.003 sec)
Query OK, 1 row affected (0.002 sec)
+------+
| id |
+------+
| 1 |
| 2 |
+------+
2 rows in set (0.001 sec)
(master) [unkomandbrepltest] > exit
Bye
[root@t_kyn029 mysqldocker]#
- レプリケーション先(SlaveのDockerの内部)に入り、データベースに接続します。
Master側で作成したデータベース、テーブルが作成されていることが確認できます。
[root@t_kyn029 mysqldocker]# docker exec -it t_kyn_001_mysql_slave mysql -u root -p mysql
Enter password:
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MariaDB connection id is 6
Server version: 10.6.12-MariaDB MariaDB Server
Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
(slave) [mysql] > show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sys |
| test |
| unkomandbrepltest |
+--------------------+
6 rows in set (0.001 sec)
(slave) [mysql] > use unkomandbrepltest;
Database changed
(slave) [unkomandbrepltest] > select * from unkomantable;
+------+
| id |
+------+
| 1 |
| 2 |
+------+
2 rows in set (0.001 sec)
(slave) [unkomandbrepltest] > exit
Bye
[root@t_kyn029 mysqldocker]#
事後作業
後続のKubernetesでの構築を行うため、
docker-composeしたコンテナ及び関連するボリュームやネットワークは不要となるため、削除します。
- docker-composeしたコンテナを削除
[root@t_kyn029 mysqldocker]# docker-compose down --rmi all --volumes --remove-orphans
Stopping t_kyn_001_mysql_master ...
Stopping t_kyn_001_mysql_slave ...
Stopping t_kyn_001_mysql_slave ... doneStopping t_kyn_001_mysql_master ... doneRemoving t_kyn_001_mysql_master ...
Removing t_kyn_001_mysql_slave ...
Removing t_kyn_001_mysql_master ... doneRemoving t_kyn_001_mysql_slave ... doneRemoving network mysqldocker_demo-network
Removing volume mysqldocker_master_db
Removing volume mysqldocker_master_log
Removing volume mysqldocker_slave_db
Removing volume mysqldocker_slave_log
Removing image mysqldocker_master
Removing image mysqldocker_slave
[root@t_kyn029 mysqldocker]#
また、docker自体のログやデータベースファイルは残ってしまうので、通り削除します。
[root@t_kyn029 mysqldocker]# rm -rfv ./master_log ./master_db ./slave_log/ ./slave_db
[root@t_kyn029 mysqldocker]# mkdir -pvm 777 ./master_log ./slave_log/
以上になります。