LoginSignup
0
1

More than 1 year has passed since last update.

alphineLinuxを用いたk8s構築(web/ap/dbサーバ)~MySQLレプリケーション(docker-compose構築)編~

Last updated at Posted at 2023-04-29

目的

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/

以上になります。

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1