【Docker】MySQLのフェイルオーバーをdocker-composeで構築

【Docker】MySQLのフェイルオーバーをdocker-composeで構築

自己紹介

はじめまして、入社新米のおかむーです🍙
  • 23歳です
  • clでサーバーサイドを担当しています
  • 絶賛勉強中です
  • 初めての投稿なので、お手柔らかにお願いします。

概要

  • MHA, master1, master2, slave1, slave2 それぞれのコンテナをdocker-composeでオーケストレーション
  • MHAコンテナがMySQLのmasterコンテナのを監視し、障害発生時などにフェイルオーバーを行う

image

経緯

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

現状

  • mysqlコンテナは4つ立つ
  • sshでMHAからmysqlへのアクセスができてないので、フェイルオーバーができていない。

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

  • 負荷をかけたり
  • 手動昇格確認などしたかった

課題点

  • 見積もり不足で時間が足りなかった
  • MHAの仕様を把握できていなかった
  • 知識不足!ベストプラクティスがわからない

感想

  • 良い勉強になった
  • 12月って忙しい!!!

参考サイト

次回予告

  • 次回はキーボードで有名な長田さんです、とても楽しみにしています!

追記

年末までにできなかったところを、検証しました

github.com に最終バージョンがあります

実際に

$ cd sample
$ docker-compose up

すると

f:id:okamuro:20161231162435p:plain

こんな感じになりました

$ docker psでmhaにexecしたあとに

mhaコンテナ内で

#  masterha_check_repl --conf=/etc/mha.conf 

を叩くと、レプリケーションのチェックをしてくれます