Help us understand the problem. What is going on with this article?

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

More than 3 years have 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
~~~~~~~~~~省略~~~~~~~~~~~~~~~~

参考サイト

okamu_
no plan inc. CEO 元フリーランスエンジニア/ iOS / サーバーサイド / 共同創業 / 福岡出身 https://qiita.com/organizations/noplan-inc
https://twitter.com/okamu_ro
noplan-inc
no plan株式会社は、Webサイト、iOSアプリ、AndroidアプリなどWebサービス全般の開発から運用をワンストップで行っています。
https://noplan-inc.com
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away