【Docker】もう悩まない!MySQLのフェイルオーバーをdocker-composeで爆速構築
概要
- MHA, master1, master2, slave1, slave2 それぞれのコンテナで動かしdocker-composeでオーケストレーション
- MHAコンテナがMySQLのmasterコンテナのを監視し、障害発生時などにフェイルオーバーを行う
フェイルオーバーとは
- 稼働中のシステム(master1)に障害が発生した際に、代替システム(master2)がその機能を自動的に引き継ぎ、処理を続行する仕組み。企業の情報システムなどで、サーバの信頼性を高めるためによく用いられる
- AWSのRDSのマルチAZがこれ
レプリケーションとは
- レプリケーションとは、あるデータベースとまったく同じ内容の複製(レプリカ)を別のコンピュータ上(slave)に作成し、常に内容を同期させる機能。 負荷分散や耐障害性の向上などを目的に行われる。
経緯
- 1から構築すると時間がかかる
- MySQL MHAを使ったフェイルオーバーの環境構築サイトはいくつかあったので、理解のついでにdocker-composeでオーケストレーションをしたかった
- レプリケーションが組めるdocker-composeのサンプルなどはすでにあったが、フェイルオーバーまでなかった
- MySQLレベルの向上のため
- docker普及のため
- 最終的には、Rancherでの運用を目指す
MySQL MHA
MySQL MHAとは
- (Master High Availability Manager and tools for MySQL) の略
- MySQLマスタ障害発生時に、MySQLマスタの自動フェイルオーバーを行い高可用性を実現するオープンソースツール
- Perlで実装されている
- MySQLのマスタをフェイルオーバーさせ、スレーブをマスタに昇格させる作業を短時間(10〜30秒程度)で実行できる
主な機能
フェイルオーバー機能
自動
- MHAマネージャがマスタを監視し、マスタに障害が発生するとフェイルオーバーさせます。最新のDB情報を反映しているスレーブから、その他のスレーブに対して差分を適用する動作を行うため、スレーブ間のデータ整合性が保証されます。
- MHA自身では、MySQLのサービス監視せず、監視作業を他の監視ソフトウェアで行い、監視ソフトウェアからの通知によりフェイルオーバーを実行します。
手動
- 手動でのマスタフェイルオーバーも可能
#### マスタ切り替え機能
- オンラインでマスタを別ホストに切り替える機能です。0.5〜2秒ほどの書き込みブロックのみで切り替え可能です。
マスタ昇格指定機能
- 「特定スレーブのマスタ昇格(昇格不可)指定」が可能です。
動作条件
- rootで各ノード間でのSSH公開鍵認証が可能であること (私はこれを見逃していた...)
- MySQL 5.0 以降のみサポート
- マスタ昇格候補のサーバでlog-binがenableであること
- マスタ昇格候補サーバにレプリケーション用ユーザが存在すること
- ステートメントベースレプリケーションでは「LOAD DATA INFILE」の使用は禁止
結論
- 「各ノード間でのSSH公開鍵認証が可能」というところを見ていなく、ハマってしまった。結局、時間(見積もり)が足りず期待させておいて未完成です。ごめんなさい
- 「いいね」で応援していただければ励みになります泣
- てっきりlinksでどうにかなるものかと思っていたところが誤算
- 修正次第、更新します。(現在進行中!!)
ベースimageを作る
- ベースimageを元に、フェイルオーバー環境を構築できるよう設計
docker image
- 今回は各コンテナにはperl環境が必要
- master, slaveにはmha-nodeがinstallされていないといけない
0.基本環境(vvdocker/base-perl)
FROM ubuntu
RUN apt-get -y update
RUN apt-get -y install wget git
# MHA NODE
RUN apt-get -y install build-essential devscripts dh-make fakeroot dpkg-dev debhelper libdbi-perl libmysqlclient-dev zlib1g-dev
RUN apt-get -y install libmodule-install-perl
RUN wget http://archive.ubuntu.com/ubuntu/pool/universe/libd/libdbd-mysql-perl/libdbd-mysql-perl_4.033.orig.tar.gz
RUN wget http://archive.ubuntu.com/ubuntu/pool/universe/libd/libdbd-mysql-perl/libdbd-mysql-perl_4.033-1build2.debian.tar.xz
RUN git clone https://github.com/yoshinorim/mha4mysql-node
WORKDIR mha4mysql-node
RUN perl Makefile.PL
RUN make
RUN make install
1.MHA(vvdocker/manager)
FROM vvdocker/base-perl
RUN apt-get install -y libconfig-tiny-perl liblog-dispatch-perl libparallel-forkmanager-perl
# MHA manager
RUN apt-get install -y libconfig-tiny-perl liblog-dispatch-perl libparallel-forkmanager-perl
RUN git clone https://github.com/yoshinorim/mha4mysql-manager.git
WORKDIR mha4mysql-manager
RUN perl Makefile.PL
RUN make
RUN make install
RUN mkdir -p /var/log/masterha/mysql/
RUN cat /usr/local/share/perl/5.20.2/MHA/ServerManager.pm
RUN cp -p samples/scripts/master_ip_failover /usr/local/bin/
RUN chmod 555 /usr/local/bin/master_ip_failover
RUN mkdir -p /etc/masterha/conf
#サンプル----------------------------------------
ADD test.conf /etc/mha.conf
#----------------------------------------------
2.node(vvdocker/node)
FROM vvdocker/base-perl
RUN mkdir work
RUN cp libdbd-mysql-perl_4.033.orig.tar.gz work
WORKDIR work
RUN tar xf libdbd-mysql-perl_4.033.orig.tar.gz
RUN mv DBD-mysql-4.033 libdbd-mysql-perl_4.033
RUN tar xf ../libdbd-mysql-perl_4.033-1build2.debian.tar.xz -C libdbd-mysql-perl_4.033
RUN cd libdbd-mysql-perl_4.033 && dpkg-buildpackage -us -uc
RUN dpkg -i libdbd-mysql-perl_4.033-1build2_amd64.deb
#mysql5.6
RUN wget http://dev.mysql.com/get/Downloads/MySQL-5.6/mysql-5.6.14-debian6.0-x86_64.deb
RUN dpkg -i mysql-5.6.14-debian6.0-x86_64.deb
RUN apt-get -y upgrade
RUN apt-get install -y libaio1 m4
RUN install -d /data/mysql
RUN /opt/mysql/server-5.6/scripts/mysql_install_db --datadir=/data/mysql
ENV PATH "/opt/mysql/server-5.6/bin:$PATH"
ENV MANPATH "/opt/mysql/server-5.6/man:$MANPATH"
RUN mysql --version
これらをdocker-hubあたりにpushしておく
$ docker push vvdocker/manager
$ docker push vvdocker/node
実行
- 実際に環境を作りたいときはここからできるようにと
docker-compose.yml
mha:
image: vvdocker/manager:dev22
links:
- master1:master_1
- master2:master_2
- slave1:slave_1
- slave2:slave_2
command: masterha_check_repl --conf=/etc/mha.conf && masterha_manager --conf=/etc/mha.conf
master1:
build: master
environment:
- MYSQL_USER=repl
- MYSQL_PASSWORD=replpass
- MYSQL_ROOT_PASSWORD=root
master2:
build: slave
environment:
- MYSQL_USER=repl
- MYSQL_PASSWORD=replpass
- MYSQL_ROOT_PASSWORD=root
links:
- master1:master_1
slave1:
build: slave
environment:
- MYSQL_USER=repl
- MYSQL_PASSWORD=replpass
- MYSQL_ROOT_PASSWORD=root
links:
- master1:master_1
- master2:master_2
slave2:
build: slave
environment:
- MYSQL_USER=repl
- MYSQL_PASSWORD=replpass
- MYSQL_ROOT_PASSWORD=root
links:
- master1:master_1
- master2:master_2
master(vvdoker/master)
FROM vvdocker/node
# my.cnf
COPY conf.d/my.cnf.in my.cnf.in
RUN m4 -DMASTERID=`date +%s` my.cnf.in > /etc/mysql/conf.d/my.cnf
COPY init.d/startup.sql /docker-entrypoint-initdb.d/startup.sql
startup.sql
GRANT REPLICATION SLAVE ON *.* TO 'repl'@'%' IDENTIFIED BY 'replpass';
FLUSH PRIVILEGES;
my.cnf.in
[mysqld]
~~~~~~~~~~省略~~~~~~~~~~~~~~~~
server-id = MASTERID
log_bin = /var/log/mysql/mysql-bin.log
bind-address = 0.0.0.0
~~~~~~~~~~省略~~~~~~~~~~~~~~~~
slave(vvdocker/slave)
FROM vvdocker/node
# my.cnf
COPY conf.d/my.cnf.in my.cnf.in
RUN m4 -DSERVERID=`date +%s` my.cnf.in > /etc/mysql/conf.d/my.cnf
COPY init.d/startup.sql /docker-entrypoint-initdb.d/startup.sql
startup.sql
CHANGE MASTER TO MASTER_HOST='master_1', MASTER_USER='repl',MASTER_PASSWORD='replpass', MASTER_LOG_FILE='mysql-bin.000001', MASTER_LOG_POS=120;
FLUSH PRIVILEGES;
my.cnf.in
[mysqld]
~~~~~~~~~~省略~~~~~~~~~~~~~~~~
server-id = SERVERID
log_bin = /var/log/mysql/mysql-bin.log
bind-address = 0.0.0.0
~~~~~~~~~~省略~~~~~~~~~~~~~~~~