MySQLのActive-Standby構成を30分で構築する


# 概要
幾つかのCHEFクックブックを適用してMySQLサーバーのHA構成をSOFTLAYER上に構築します。HA構成といえば、サーバー構築作業の中でも時間のかかる面倒な作業ですが、CHEFを利用して高速かつ高品質な構築を実現する事ができます。

複数のサーバーから切り替えて利用するSOFTLAYERの共有ストレージには、エンデュランス・ストレージやパフォーマンス・ストレージを利用します。また、仮想IP(VIP)アドレスには、ポータブル・サブネットを利用します。

# 本クックブックの範囲

MySQLのアクティブ・スタンバイの HA (High Availability)構成を構築するために、4つのクックブックを利用します。
1. Pacemaker + corosync クックブック https://github.com/takara9/pm_corosync01
2. iSCSIストレージ クックブック https://github.com/takara9/iscsiStorage01
3. MySQL クックブック https://github.com/takara9/mysql01
4. Hostfile クックブック https://github.com/customink-webops/hostsfile

これら４つのクックブックで構築する範囲は、図の赤破線枠内です。各々のクックブックの説明は、それぞれのリンク先にあります。

![スクリーンショット 2015-11-23 20.21.30.png](https://qiita-image-store.s3.amazonaws.com/0/42829/48e9f1fe-ee5e-1af4-8eaa-4bbc757e2968.png)


# HA構成の動作

MySQLの主サーバーは、iSCSIストレージをext4ファイルシステムとしてマウントして、VIPを保持し、MySQLサーバーのプロセスを起動しています。アプリサーバーは、VIPにアクセスして、MySQLサーバーに接続しています。
MySQLの主サーバーが停止すると、待機サーバーがVIPを引き継ぎ、iSCSIストレージをマウントし、MySQLサーバーのプロセスを起動します。 ユーザーデータは、共有ディスクのiSCSIストレージに保存されているので、主サーバーが故障しても、待機サーバーがデータを引き継ぎMySQLのプロセスを起動します。
iSCSIストレージは、専用のストレージ装置であり、冗長化された単一障害点(SPOF)の無い装置ですから、可用性を高めるには、サーバーを２重化すれば良いことになります。この図のサーバーは仮想サーバーとなっていますが、もちろん、物理サーバー（ベアメタル）でも同じ事ができます。

![スクリーンショット 2015-11-23 20.23.41.png](https://qiita-image-store.s3.amazonaws.com/0/42829/41e5c3e4-0183-0979-2ebc-6e98206b0c44.png)


## CentOS 6.x/7.x での構築手順

MySQLのHA構成を構築する作業の流れを以下に列挙します。各サーバーにログインしてからの所用作業時間は、およそ３０分です。

1. ベアメアタル、または、仮想サーバーのオーダー
2. 共有ストレージのオーダー
3. VIP用サブネットのオーダー
4. 共有ストレージの認証設定
5. Chefのインストール
6. 必要なクックブックのダウンロード
7. VIPのアトリビュ−ト設定
8. iSCSIストレージのアトリビュ−ト設定
9. MySQLのアトリビュ−ト設定
10. クックブックの適用
11. 再起動
12. 動作確認

##1.サーバーのオーダー
SoftLayerカスタマーポータル(https://control.softlayer.com/) のメニューから「Account」 -> 「Place an Order」 -> 「Devices」に進み、仮想サーバーまたはベアメタルサーバーの主サーバーと待機サーバーの２つをオーダーします。この際の注意点としては、同じVLANにアクティブとスタンバイのサーバーを配置しなければなりません。

##2.共有ディスクのオーダー
SoftLayerカスタマーポータル(https://control.softlayer.com/) のメニューから「Storage」 -> 「Block Storage」 -> 「Order Block Storage」 に進みます。表示されらメニューの中から、「Endurance」または「Performance」ストレージを選択してオーダーします。「Location」は、サーバーと同じロケーションを選択します。

##3.VIP用サブネットのオーダー
SoftLayerカスタマーポータル(https://control.softlayer.com/) のメニューから「Network」->「IP Management」->「Subnets」->「Order IP Address」の順に進み、「Portable Private」の「16 Portable Private IP Addresses」を選択します。

##4.共有ストレージの認証設定
SoftLayerカスタマーポータル(https://control.softlayer.com/) のメニューから「Storage」->「Block Storage」->「LUN Name」->「Authorize Host」に進み、ストレージにアクセスを許可する主サーバーと待機サーバーを選択します。

##5.Chefのインストール
主サーバーと待機サーバーのそれぞれにログインして、以下のコマンドでChefクライアントをインストールします。ここでは Knife,Knife solo, Knife zero などのフロントエンド・コマンドを利用せずに、Chef-soloコマンドをスタンドアロンで利用します。 その理由は、CHEFのサーバーやワークセステーションが不要で、集中管理はできませんがシンプルで解りやすいためです。

```
# curl -L https://www.opscode.com/chef/install.sh | bash
```
もちろん、本章で利用するクックブックは、Knifeコマンドを使って効率よく集中管理することも可能です。


##6.必要なクックブックのダウンロード
それぞれのサーバーに、GitHubから次のクックブックを取得します。 最初のdummyは、/var/chef/cookbooksのディレクトリを作成するためで,mkdir コマンドでディレクトリを作成しても良いでしょう。

```
# knife cookbook create dummy -o /var/chef/cookbooks
# cd /var/chef/cookbooks
# git clone https://github.com/takara9/pm_corosync01
# git clone https://github.com/takara9/iscsiStorage01
# git clone https://github.com/customink-webops/hostsfile
# git clone https://github.com/takara9/mysql01
```

##7.VIPのアトリビュ−ト設定
/var/chef/cookbooks/pm_corosync01/attributes/default.rb を編集する。

```
default["network_addr"] = "10.132.253.0"
default["multicast_addr"] = "226.94.1.1"
default["multicast_port"] = "5405"
default["vip_ipaddr"] = "10.132.5.141"
default["vip_netmask"] = "26"
```
##8.iSCSIストレージのアトリビュ−ト設定
/var/chef/cookbooks/iscsiStorage01/attributes/default.rb を編集する
iSCSIのユーザーIDとパスワードは、サーバー毎に付与されるため、それぞれポータルから取得して設定する。

```
default["iscsi_target_ipaddr"] = ""
default["iscsi_user_name"]     = ""
default["iscsi_user_password"] = ""
default["initiator_name"]      = ""

default["multipath_device"]["name1"] = "/dev/mapper/iscsimp1"
default["multipath_device"]["mount1"] = "/data1"

default["iscsi_host"] = 'master'
```
スタンバイ側は以下の様に設定する

```
default["iscsi_host"] = 'standby'
```

##9.MySQLのアトリビュ−ト設定
/var/chef/cookbooks/mysql01/attributes/default.rb を編集する。

```
default["mysql"]["root_password"] = 'passw0rd'
default["mysql"]["db_name"] = 'testdb'
default["mysql"]["user"]["name"] = 'wordpress'
default["mysql"]["user"]["password"] = 'wordpress'
default["mysql"]["node"] = 'service'
```
スタンバイ側は以下の様に設定する

```
default["mysql"]["node"] = 'standby'
```

##10.クックブックの適用
ペースメーカーの設定実施

```
# chef-solo -o pm_corosync01
中略
Chef Client finished, 13/15 resources updated in 02 minutes 35 seconds
```
iSCSIストレージの設定実施

```
# chef-solo -o iscsiStorage01
中略
Chef Client finished, 19/22 resources updated in 24 seconds
```
MySQLサーバーの設定実施

```
# chef-solo -o mysql01
中略
Chef Client finished, 21/27 resources updated in 01 minutes 18 seconds
```

##11.再起動
アクティブ側サーバーとスタンバイ側サーバーをそれぞれ再起動します。そして、それぞれのサーバーで、以下の様な結果になれば正常稼動しています。

```
[root@mysql01 ~]# pcs resource 
 Resource Group: svc1
     vip1	(ocf::heartbeat:IPaddr2):	Started mysql01.takara.org 
     vfs1	(ocf::heartbeat:Filesystem):	Started mysql01.takara.org 
     mysql1	(ocf::heartbeat:mysql):	Started mysql01.takara.org 
```


##12.HA構成の動作テスト

###手動動作切り替え
次のコマンドで、手動でサービスノードを切り替えます。 

```
[root@mysql01 ~]# pcs resource move vip1 mysql02.takara.org
```
この設定では、vip1しか指定していませんが、同じグループに含まれるvfs1,mysql1も一緒に切り替わります。 ここで pcs resource move で指定したノードが、常にサービスノードになる様に動作するため、このままでは、mysql01 が停止して、mysql02 に切り替わった後に、mysql01 を起動すると、サービスが mysql01に戻ってきてしまいます。この move 指定をクリアしておく必要があります。

```
[root@mysql01 ~]# pcs resource clear vip1
```

###サーバーダウン時の動作
アプリサーバーに相当するサーバーから次の様に、ホスト名にVIPのIPアドレスを指定してmysqlコマンドでログインします。

```
$ mysql -u wordpress -pwordpress -h 10.132.5.141 testdb
```
主サーバーをrebootコマンドで、サービスノード停止から十数秒で、待機サーバーに切り替わる事が確認出来ます。 以下の例では、繰り返しSELECT文を実行しながら、サービスノードをリブートしたケースです。 待機系に切り替わり中に２回ほどエラーが出て、その後、正常な応答が返って来た事がわかります。

```
mysql> select engine from engines where engine like 'Inn%';
+--------+
| engine |
+--------+
| InnoDB |
+--------+
1 row in set (0.00 sec)

mysql> select engine from engines where engine like 'Inn%';
ERROR 2013 (HY000): Lost connection to MySQL server during query
mysql> select engine from engines where engine like 'Inn%';
ERROR 2006 (HY000): MySQL server has gone away
No connection. Trying to reconnect...
Connection id:    1
Current database: information_schema

+--------+
| engine |
+--------+
| InnoDB |
+--------+
1 row in set (0.07 sec)
```


# まとめ
今回はCHEFの環境設定に費やす時間を最小にするため、CHEFクライアントを直接インストールしましたが、Knife を組合わせることで、Run-Listを作り、Knifeコマンド一回で、設定を完了させる事も出来ます。