SoftLayer を利用して apache の mod_proxy_balancer によるロード・バランスをテストする

#0. はじめに
[「apacheのmod_proxy_balancerを使ってロードバランサを試してみる」]( http://djangoapplab.com/apache%E3%81%AEmod_proxy_balancer%E3%82%92%E4%BD%BF%E3%81%A3%E3%81%A6%E3%83%AD%E3%83%BC%E3%83%89%E3%83%90%E3%83%A9%E3%83%B3%E3%82%B5%E3%82%92%E8%A9%A6%E3%81%97%E3%81%A6%E3%81%BF%E3%82%8B/ )というブログを読んだので、早速、SoftLayer 上でテストしてみることにしました。
また、上記の記事では、同じ事前準備を各ホストで実施する部分があった為、SoftLayer の設定スクリプト(プロビジョニング･スクリプト)で作業を自動化してみました。設定スクリプトについてはこちらの[記事](http://www.gg-web.jp/document/ConfigGuide/01002_2/index.html)を参考にさせて頂きました。
今回のテストでは、1台のロード・バランサーへの http 要求を5台の Webサーバーへ振り分け、それぞれのホスト名を応答として検証用のPCへ返します。
![lb.PNG](https://qiita-image-store.s3.amazonaws.com/0/74185/782f6d62-d675-1c5b-82f8-1fa69e57e86a.png)


#1. 事前準備
1) Web サーバー用設定スクリプト作成
ロード・バランスされる Web サーバー側の設定スクリプトとして内容のファイルを作成します。

```
#!/bin/bash
#Provisioning script for Web servers
cat << EOS >> /etc/httpd/conf.d/vhosts.conf
NameVirtualHost *:80
<VirtualHost *:80>
  ServerName sample
  DocumentRoot /var/www/html/sample
</VirtualHost>
EOS
#change iptables setting
iptables -A INPUT -m state --state NEW -m tcp -p tcp --dport 80 -j ACCEPT
/etc/init.d/iptables save
#create sample directory
mkdir /var/www/html/sample
#create test.html
cat << EOS > /var/www/html/sample/test.html
<html>
<head><title>test</title></head>
<body>
<h1>`hostname -s`</h1>
</body>
</html>
EOS

#restart httpd
/etc/init.d/httpd restart
```

2) ロード･バランサー用設定スクリプト作成
次にロード･バランサーの設定スクリプトとして内容のファイルを用意します。

```
#!/bin/bash
#for LB
#get IP addresses for web servers from metadata to create balancer.conf
curl -v https://api.service.softlayer.com/rest/v3/SoftLayer_Resource_Metadata/UserMetadata.txt > /root/UserMetadata.txt
if [ -e /root/UserMetadata.txt ]
then
cat << EOS > /etc/httpd/conf.d/balancer.conf
ProxyPass / balancer://mycluster/
ProxyPassReverse / balancer://mycluster/
<Proxy balancer://mycluster/>
EOS
  cat /root/UserMetadata.txt | xargs -I{} echo "  BalancerMember http://{} loadfactor=10" >> /etc/httpd/conf.d/balancer.conf
  echo \<\/Proxy\> >> /etc/httpd/conf.d/balancer.conf
else
  echo Web servers IP addresses could not get from metadata.
fi

#create vhosts configuration file
cat << EOS >> /etc/httpd/conf.d/vhosts.conf
NameVirtualHost *:80
<VirtualHost *:80>
  ServerName sample
  DocumentRoot /var/www/html/sample
</VirtualHost>
EOS

#change iptables setting
iptables -A INPUT -m state --state NEW -m tcp -p tcp --dport 80 -j ACCEPT
/etc/init.d/iptables save

#create sample directory
mkdir /var/www/html/sample
#create test.html
cat << EOS > /var/www/html/sample/test.html
<html>
<head><title>test</title></head>
<body>
<h1>`hostname -s`</h1>
</body>
</html>
EOS

#restart httpd
/etc/init.d/httpd restart
```

3) 設定スクリプト配布用 Web サーバーの選定/準備
今回の検証では SoftLayer のプライベート・ネットワークにのみ接続するサーバーへ設定スクリプトを配布する為、 CentOS6 64bit LAMP 構成の仮想サーバーをオーダーし、インストールの完了後に、上記 1)、2) のファイルを /var/www/html に配置後、httpd を起動しました。
また、参考記事と同じように github を利用する方法や、「補足1」で述べるように、qiita 上に設定スクリプトを配置しておく方法もあります。

4) 設定スクリプトの登録
上記、3) での配布方法に応じて、カスタマー・ポータル上で設定スクリプト登録(Device->Manage->Provisioning Scripts->Add Provisioning Script)します。
今回は設定スクリプトを自動実行する為、 https (例. https://10.x.x.x/web.sh )を指定します。
一方、インストール完了後に、配布された設定スクリプトに対して、パラメーターを手動で与えたり、実行タイミングを調整して実行する場合には、http (例. http://10.x.x.x/web.sh )を指定します。

#2. Web サーバーのオーダー
ロード･バランサーの設定時に必要な、「ロード・バランスされる側の Web サーバーの IP アドレス」を確定させる為に、まず、Web サーバーをオーダーします。
プライベート・ネットワークのみに接続した CentOS6 64bit LAMP 構成の仮想サーバーを複数(今回のテストでは5台)、上記 1. の 4) で登録した設定スクリプトを指定してオーダーします。

#3. ロード・バランサーのオーダー
上記 2. の Webサーバーの IP アドレスの確定後に、ロード・バランサーをオーダーします。
パブリック、プライベート双方のネットワークに接続した CentOS6 64bit LAMP 構成の仮想サーバーを1台を上記 1. の 4) で登録した設定スクリプトを指定してオーダーします。
その際に「ロード･バランスされる側の Web サーバーの IP アドレス」を UserMetadata として指定します。
![キャプチャ.PNG](https://qiita-image-store.s3.amazonaws.com/0/74185/47012311-082e-9681-8d91-bf5a6865ce8b.png)

#4. 動作確認
全てがうまくいった場合には、「 http://ロード・バランサーのIPアドレス/test.html 」へアクセスすることで、ロード･バランス先となっている Web サーバーのホスト名がブラウザー上に順番に表示されます。

#5. まとめ
上記の様に比較的簡単にロード・バランス機能を確認することができました。
ブラウザー上に返されるテスト結果はごく簡単なものなので、あまりありがたみが無いですが、裏側では、5台の Webサーバーに要求が分散されいることまで思いを馳せると、すこしだけ自己満足が感じられると思います。
また、この構成では、ロード・バランサーに問題が発生すると Webサーバーは動作していても、全ての要求が処理できなくなるので、今後その点を改善できる方法が判れば、続編としてまとめたいと考えています。

#補足1. Qiita 上への設定スクリプトの配置
こちらの[記事](http://qiita.com/suin/items/2bdeef73b5413c5a1892)を参考して、上記 1. 3) で触れた様に設定スクリプトを qiita 上に配置することも可能です。
但し、設定スクリプトを利用するサーバーはインターネットに接続できる必要があります(今回のロード･バランス先のWebサーバーはプライベート・ネットワークにのみ接続していたので、利用しませんでした)。
Qiita の記事のタイトル部分を #!/bin/sh もしくは、#!/bin/bash を指定し、本文へマークアップの代わりに bash スクリプトを記載して、保管後、カスタマー・ポータル上に設定スクリプトへのURL として、"Qiita の記事の URL".md を指定することで、使用できるようになります。
可読性は非常に悪く、タイトルから内容が判別できないなどの問題がありますが、正常に設定スクリプトとして動作することを確認しています。

#参考
[apacheのmod_proxy_balancerを使ってロードバランサを試してみる](http://djangoapplab.com/apache%E3%81%AEmod_proxy_balancer%E3%82%92%E4%BD%BF%E3%81%A3%E3%81%A6%E3%83%AD%E3%83%BC%E3%83%89%E3%83%90%E3%83%A9%E3%83%B3%E3%82%B5%E3%82%92%E8%A9%A6%E3%81%97%E3%81%A6%E3%81%BF%E3%82%8B/)
[ソフトレイヤー活用ガイド 1.2.2 設定スクリプトの自動実行](http://www.gg-web.jp/document/ConfigGuide/01002_2/index.html)
[# Qiitaの投稿をシェルスクリプトとして実行する方法](http://qiita.com/suin/items/2bdeef73b5413c5a1892)