keepalived + MySQL-MHAでフェイルオーバー(その4 master_ip_failover_script編)

アドウェイズエンジニアのイシマルです。

1月の記事以来ですね。お久しぶりです。
少しタイトルを変えました。

アドウェイズに入社して、あと1ヶ月で1年になります。
西新宿のお店もだいぶ覚えてきましたが、

チームの飲み会の幹事で、予約した店とは違う店に引率した!
予定していたランチの店とは違う店に引率した!

など、色々と事件を起こしたりしています^^;。


では、本題のmaster_ip_failover_script編を紹介します。

サーバ構成、サーバ要件等は、前回までの

keepalived + MySQL-MHA + xtrabackupで自動フェイルオーバーと手動ファイルバック(その1 keepalived編)
keepalived + MySQL-MHA + xtrabackupで自動フェイルオーバーと手動フェイル(その2 MySQL-MHA編)
keepalived + MySQL-MHA + xtrabackupで自動フェイルオーバーと手動フェイル(その3 xtrabackup編)

を参照してください。

■今回の要旨

フェイルオーバー時に、Virtual IP Addressを切り替える方法を検証してみました。

■今回の詳細

MHAを用いたフェイルオーバーには、Masterのダウンの検知からフェイルオーバー完了までに、概ね数秒から数十秒かかります。
なので、フェイルオーバー完了後に、アプリケーションがアクセスするマスターDBを変更する必要があります。

MySQL-MHAでは、このフェイルオーバー完了後に実行するScript(master_ip_failover_script)が用意されています。

■master_ip_failover_scriptを記載する場所

MHA Managerの設定ファイルのserver_defaultの部分にmaster_ip_failover_scriptを追加します(詳細は、その2 MySQL-MHA編を参照)。
# vi /etc/app1.cnf

[server default]

master_ip_failover_script= /var/lib/mysql_mha/masterha/script/master_ip_failover


このスクリプトに、好きなコードを書けば良いのですが、サンプルスクリプトが以下に用意されていたので、それを書き換えることにしました。

/usr/local/src/mha4mysql-manager-0.55/samples/scripts/master_ip_failover

■master_ip_failover_scriptの仕様

最初は、このmaster_ip_failover_scriptって、

parameter名から、masteripfailoverした時に実行するscriptに見えるんですが、どうも違うようです。

最初、Scriptを自作で検証した時は、「挙動がおかしいぞ!」って思いましたが仕様のようで、以下の3回、このスクリプトが実行されます。

1. MHA-Manager起動時(--command=status)
2. Masterサーバシャットダウン時(--command=stop or stopssh)
3. フェイルオーバー完了時(--command=start)

マニュアルにも書いていますね。

サンプルスクリプトは、上記のケース毎に処理を記述するようになっているので、以下のような感じで編集しました(※最低限の情報だけ載せています)。

# vi /var/lib/mysql_mha/masterha/script/master_ip_failover

sub main {
  if ( $command eq "stop" || $command eq "stopssh" ) {
    exit 0;
  }
  elsif ( $command eq "start" ) {
    system("sh /var/lib/mysql_mha/masterha/script/change_virtual_ip.sh");
    exit 0;
  }
  elsif ( $command eq "status" ) {
    exit 0;
  }
  else {
    &usage();
    exit 1;
  }
}

# vi /var/lib/mysql_mha/masterha/script/change_virtual_ip.sh

#!/bin/sh

ssh -t mysql@192.168.0.101 sudo /etc/init.d/keepalived stop
ssh -t mysql@192.168.0.102 sudo /etc/init.d/keepalived start

※それぞれのサーバで、mysqlユーザーが、keepalivedコマンドをsudoできるように設定しておく必要があります。

# visudo
#末尾に
mysql ALL=(root) NOPASSWD: /etc/init.d/keepalived



■IPの付け替えについて

今回紹介した事例は、

アプリケーション側からは、Virtual IPへアクセスさせるようにし、
MasterDBサーバにVirtual IP付けて、DB側のMasterサーバが変わっても、
アプリケーション側を変更する必要が無いようなシステム構築を行なう事例です。

その1 keepalived編では、以下の図のように、priorityを付けて、全てのサーバでkeepalivedを起動しておくことを想定していましたが、この設定だと、master dbが落ちた瞬間にVirtual IPが切り替わってしまうので、駄目だということが判明しました。

blog1_2

そこで、keepalivedを起動しておくサーバは、Master DBのみに変更し、フェイルオーバー完了後に、

・旧Masterのkeepalivedをstop
・新Masterのkeepalivedをstart

の手順で、Virtual IPを切り替えるようにしました。

# vi /etc/keepalived/keepalived.conf
! Configuration File for keepalived

global_defs {
   notification_email {
     notice用のメールアドレス
   }
   notification_email_from notice用のメールの送信元アドレス
   smtp_server localhost
   smtp_connect_timeout 30
}

vrrp_instance vip_mysqld {

    state BACKUP

    # VIPを割り当てるNIC
    interface eth0

    grap_master_delay 5

    # 仮想ルーターのID
    virtual_router_id 1

    # 優先度
    priority 150

    #今起動しているのがなければ、マスタになり、マスタがいれば、スレーブ。
    nopreempt

    # VRRP信号を送出する間隔
    advert_int 1

    authentication {
        auth_type PASS
        auth_pass パスワード
    }
    virtual_ipaddress {
        192.168.0.100
    }
}


■IPの付け替えについて(補足)

今回、IPの切り替えは、記事の流れ上、keepalivedで行ないましたが、
keepalived上でVirtual IPを切り替えるのではなく、
MHAのmaster_ip_failover_scriptでVirtual IPを切り替えるようにしたので、
わざわざkeepalivedを使う必要はなさそうです。

IPを付け替えるだけであれば、IPにaliasを付けて、
ssh -t mysql@192.168.0.101 sudo ifconfig eth0:0 down
ssh -t mysql@192.168.0.102 sudo ifconfig eth0:0 192.168.0.100

こんな感じでも良いと思います。
/etc/sysconfig/network-scripts/内に、設定を書かなければ、Master DBがrebootした時にもalias設定は消えますしね。

他にも、アプリケーションからDBのMasterにアクセスさせる際に、DB Masterサーバのホスト名をアプリケーション側では指定して、

master_ip_failover_scriptでDNSレコードを更新するという方法でもいけそうですね。

master_ip_failover_script編は以上となります。