Docker 上で MariaDB Server を Primary / Replica 構成でデプロイ

はじめに

MariaDB Community Server の公式 Docker イメージは以下のURLで Docker Hub 上で公開されています。

https://hub.docker.com/r/mariadb/server

今回は Docker 上で Primary / Replica 構成で MariaDB Community Server をデプロイしてみます。

テスト環境

  • Docker 18.06.3-ce, build d7080c1
  • MariaDB Community Server 10.4.11
  • MariaDB MaxScale 2.4.4

docker-compose.yml

GitHub の maxscale-docker レポジトリにある docker-compose.yml を元に以下の docker-compose.yml を作成しました。

version: '3.1'
services:
  primary:
    image: mariadb/server:latest
    environment:
      MYSQL_ALLOW_EMPTY_PASSWORD: 'Y'
    volumes:
      - ./sql/primary:/docker-entrypoint-initdb.d
    command: mysqld --log-bin=mariadb-bin --binlog-format=ROW --server-id=1 --character-set-server=utf8mb4
    ports:
      - "4001:3306"

  replica1:
    image: mariadb/server:latest
    depends_on:
      - primary
    environment:
      MYSQL_ALLOW_EMPTY_PASSWORD: 'Y'
    volumes:
      - ./sql/replica:/docker-entrypoint-initdb.d
    command: mysqld --log-bin=mariadb-bin --binlog-format=ROW --server-id=2 --log-slave-updates --character-set-server=utf8mb4
    ports:
      - "4002:3306"

  replica2:
    image: mariadb/server:latest
    depends_on:
      - primary
    environment:
      MYSQL_ALLOW_EMPTY_PASSWORD: 'Y'
    volumes:
      - ./sql/replica:/docker-entrypoint-initdb.d
    command: mysqld --log-bin=mariadb-bin --binlog-format=ROW --server-id=3 --log-slave-updates --character-set-server=utf8mb4
    ports:
      - "4003:3306"

  maxscale:
    image: mariadb/maxscale:latest
    depends_on:
      - primary
      - replica1
      - replica2
    volumes:
      - ./maxscale.cnf.d:/etc/maxscale.cnf.d
    ports:
      - "3306:3306" # read/write split
      - "8989:8989" # REST API

docker-compose.yml 等のファイル一式は こちらの GitHub レポジトリで公開しております。

MariaDB Server / MaxScale コンテナのデプロイ

Docker 実行環境で以下のコマンドを実行し,各コンテナをデプロイします。

git clone https://github.com/goto-satoru/docker-maxscale-primary-replica mxs
cd mxs
docker swarm init
docker stack deploy -c docker-compose.yml mxs

docker service ls で各サービスの稼働状態が確認できます。

$ docker service ls
ID                  NAME                MODE                REPLICAS            IMAGE                     PORTS
rdxax843b6gm        mxs_maxscale        replicated          1/1                 mariadb/maxscale:latest   *:3306->3306/tcp, *:8989->8989/tcp
y73vwfw9vz64        mxs_primary         replicated          1/1                 mariadb/server:latest     *:4001->3306/tcp
e6e9wupkhcdm        mxs_replica1        replicated          1/1                 mariadb/server:latest     *:4002->3306/tcp
wamcyncj0dcj        mxs_replica2        replicated          1/1                 mariadb/server:latest     *:4003->3306/tcp

docker ps で各コンテナのIDを確認します。

$ docker ps
CONTAINER ID        IMAGE                     COMMAND                  CREATED             STATUS              PORTS               NAMES
eaad50c4c802        mariadb/server:latest     "docker-entrypoint.s…"   4 minutes ago       Up 4 minutes        3306/tcp            mxs_replica2.1.2gwib5pixpwa1sdj9hpg5n6qu
d26f95267a5c        mariadb/server:latest     "docker-entrypoint.s…"   4 minutes ago       Up 4 minutes        3306/tcp            mxs_replica1.1.up0deb6xdwdg7xhkfhya5yv2j
13d70cdbaaad        mariadb/server:latest     "docker-entrypoint.s…"   4 minutes ago       Up 4 minutes        3306/tcp            mxs_primary.1.wszclbhqiroiy6bomqyvix6gh
cd22453c8005        mariadb/maxscale:latest   "docker-entrypoint.s…"   4 minutes ago       Up 4 minutes                            mxs_maxscale.1.o0zq4b58x49y5h9kxh29cbllh

MaxScale コンテナ上で maxctrl list servers を実行,各 MariaDB Server インスタンスの状態を確認します。
(docker service ls で表示される サービスID/サービス名は docker exec で利用できません)

$ docker exec cd22453c8005 maxctrl list servers
┌─────────┬──────────┬──────┬─────────────┬─────────────────┬───────┐
│ Server  │ Address  │ Port │ Connections │ State           │ GTID  │
├─────────┼──────────┼──────┼─────────────┼─────────────────┼───────┤
│ server1 │ primary  │ 3306 │ 0           │ Master, Running │ 0-1-5 │
├─────────┼──────────┼──────┼─────────────┼─────────────────┼───────┤
│ server2 │ replica1 │ 3306 │ 0           │ Slave, Running  │ 0-1-5 │
├─────────┼──────────┼──────┼─────────────┼─────────────────┼───────┤
│ server3 │ replica2 │ 3306 │ 0           │ Slave, Running  │ 0-1-5 │
└─────────┴──────────┴──────┴─────────────┴─────────────────┴───────┘

正常に primary の status が “`Master, running“` となっています。

自動フェイルオーバのテスト

Master(Primary)となっている server1 を 稼働停止し,自動フェイルオーバするか確認してみます。

docker stop 13d70cdbaaad

このときの MaxScale のログは以下のようになりました。

$ docker logs -f (MaxScale_container_id)
2019-12-07 12:42:47   error  : Monitor was unable to connect to server server1[primary:3306] : 'Can't connect to MySQL server on 'primary' (115)'
2019-12-07 12:42:47   notice : Server changed state: server1[primary:3306]: master_down. [Master, Running] -> [Down]
2019-12-07 12:42:47   warning: [mariadbmon] Master has failed. If master status does not change in 4 monitor passes, failover begins.
2019-12-07 12:42:48   notice : [mariadbmon] Selecting a server to promote and replace 'server1'. Candidates are: 'server2', 'server3'.
2019-12-07 12:42:48   warning: [mariadbmon] Slave 'server2' has gtid_strict_mode disabled. Enabling this setting is recommended. For more information, see https://mariadb.com/kb/en/library/gtid/#gtid_strict_mode
2019-12-07 12:42:48   warning: [mariadbmon] Slave 'server3' has gtid_strict_mode disabled. Enabling this setting is recommended. For more information, see https://mariadb.com/kb/en/library/gtid/#gtid_strict_mode
2019-12-07 12:42:48   notice : [mariadbmon] Selected 'server2'.
2019-12-07 12:42:48   notice : [mariadbmon] Performing automatic failover to replace failed master 'server1'.
2019-12-07 12:42:48   notice : [mariadbmon] Redirecting 'server3' to replicate from 'server2' instead of 'server1'.
2019-12-07 12:42:48   notice : [mariadbmon] All redirects successful.
2019-12-07 12:42:49   notice : [mariadbmon] All redirected slaves successfully started replication from 'server2'.
2019-12-07 12:42:49   notice : [mariadbmon] Failover 'server1' -> 'server2' performed.
2019-12-07 12:42:49   notice : Server changed state: server2[replica1:3306]: new_master. [Slave, Running] -> [Master, Running]

今回テストのために MariaDB Monitor の monitor_interval をデフォルトの 2000 ms ではなく,200 ms に変更していますので,2 秒ほどで server2 (replica1) が 新たな Master(Primary) に昇格しています。

2019-12-07 12:43:07   notice : Server changed state: server1[primary:3306]: server_up. [Down] -> [Running]
2019-12-07 12:43:07   notice : [mariadbmon] Directing standalone server 'server1' to replicate from 'server2'.
2019-12-07 12:43:07   notice : [mariadbmon] Slave connection from server1 to [replica1]:3306 created and started.
2019-12-07 12:43:07   notice : [mariadbmon] 1 server(s) redirected or rejoined the cluster.
2019-12-07 12:43:07   notice : Server changed state: server1[primary:3306]: new_slave. [Running] -> [Slave, Running]

しばらくして server1 のコンテナが自動再起動し,Slave Running というステータスになりました。

ここで,maxctrl list servers を実行すると,

┌─────────┬──────────┬──────┬─────────────┬─────────────────┬──────────┐
│ Server  │ Address  │ Port │ Connections │ State           │ GTID     │
├─────────┼──────────┼──────┼─────────────┼─────────────────┼──────────┤
│ server1 │ primary  │ 3306 │ 0           │ Slave, Running  │ 0-1-7244 │
├─────────┼──────────┼──────┼─────────────┼─────────────────┼──────────┤
│ server2 │ replica1 │ 3306 │ 0           │ Master, Running │ 0-1-7244 │
├─────────┼──────────┼──────┼─────────────┼─────────────────┼──────────┤
│ server3 │ replica2 │ 3306 │ 0           │ Slave, Running  │ 0-1-7244 │
└─────────┴──────────┴──────┴─────────────┴─────────────────┴──────────┘

のようになりました。server2 が Primary(Master) となり,その他のコンテナが Replica(Slave)となっていることが確認できます。

まとめ

今回は Docker 上で MariaDB Communty Server を Primary / Replica 構成でデプロイしてみました。非常に簡単に MariaDB Server のテスト環境が構築可能なことが確認頂けたかと存じます。
なお,MaxScale の最新版 2.4 は 2023-10-29 に GPL v2 に移行する BSLライセンスされています。
テスト環境ではライセンス購入は必要ありませんが,プロダクション環境で MariaDB Server インスタンスが 3 以上であると有償となりますので留意願います。

また,以下の URL で公開されているイメージは Docker, Inc. でビルドしているものですので留意願います。

https://hub.docker.com/_/mariadb