MySQL
Docker
MHA
docker-compose
Docker2Day 8

【未完成】【Docker】もう悩まない!MySQLのフェイルオーバーをdocker-composeで爆速構築

More than 1 year has passed since last update.


【Docker】もう悩まない!MySQLのフェイルオーバーをdocker-composeで爆速構築


概要


  • MHA, master1, master2, slave1, slave2 それぞれのコンテナで動かしdocker-composeでオーケストレーション

  • MHAコンテナがMySQLのmasterコンテナのを監視し、障害発生時などにフェイルオーバーを行う

image


フェイルオーバーとは


  • 稼働中のシステム(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されていないといけない

IMG_8767.JPG

手書きです。ごめんなさい!


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
~~~~~~~~~~省略~~~~~~~~~~~~~~~~


参考サイト