カスタムイメージを基にスケールするVMSSと2種類のロードバランサを一括構築
ども、最近更新が、、、さぁAzureブログがんばるぞー!!
今回のテーマはVirtual Machine Scale Set!略してVMSS。
といってもVMSSをデプロイして自動スケールスゲー!!な話はするつもり
はなく、もちっと実用的なもの(?))を用意してみました。
VMSSをベースにL4LBであるALBとL7LBであるApplication Gateway
(以下AppGW)の2つを上段に構え、Inbound通信はAppGW経由、Outbound
通信はALB経由にし、VMSSの各ノードはカスタムイメージから持ってきた
nginx(CentOS7)が起動している状態のものを展開しつつ、なおかつ
AutoscalesettingsでCPU60%以上になったらVM数を増やす、50%以下
になったら1VMずつ減らす、という環境をARM templateで一括作成
しちゃえというものです。
・・・。
文章で記載するとさっぱり伝わらないですね(はぅ
どんな要件だとこれに行きつくのか、、という話をしたほうがよさげですね。
〇サーバー負荷に応じて自動でVMを増やしたいし減らしたい
〇セッションアフィニティの管理やWAFの機能も併用したい
〇外向けのOutbound通信はStaticなIPとして固定化し、受け皿側では
StaticなIPで許可設定をいれたい。
〇スケールする度に毎回WEBサーバーの構築とかだるいからヤダ
なんとなく初めてクラウドを利用される方が描く期待の構成っぽく
聞こえますが、そんなご要望に応える環境を試してみました。
とりあえずブツは以下のgithubに配置しておきました。
手っ取りばやく試したい方はこれをテンプレートデプロイで
azureにぶち込むとわかります。
ちなみにARM templateは便利ですが、中身を理解していない状態で
利用すると応用もきかずエラーが出た時にアタフタしますので
軽くポイントだけ説明しておきます。
まずparametersの個所から。
sshKeyData変数の部分はssh-rsaの文字列の後ろに半角スペースを入れた後、
公開キーの文字列をベタっと張り付けてください。
このsshKeyData変数はresourcesの個所で処理していますが、CentOSに
作成したユーザー(ここではazure01ユーザ)の/home/.ssh/ディレクトリ配下
にauthorized_keysというファイル名で格納しています。公開鍵認証する際に
照合する場所ですね。
addressPrefix = vNETのアドレスセグメント
subnetPrefix = 上記vNET配下のサブネットを1つ
appGwSubnetPrefix = application gateway用サブネット(上記vNET内)
defaultvalueでは192.168.0.0/16のvNET配下に/24を2つ指定していますが
間違えても異なるvNETアドレスセグメントの範囲をサブネットに入れない
でください。(デプロイ検証は成功しますが、デプロイ開始後にエラーに
なります)
imageNameにカスタムイメージで保管してあるresource idをベタっと
はりつけます。
defaultvalueで指定した文字列の中で'-'で括った大文字部分は利用する人
の状況に合わせて差し替えてください。
SubscriptionIDやイメージが保管されているResourceGroupやイメージ名です。
カスタムイメージの作成方法は以下がわかりやすくて良いと思います。
CentOSだとOS内のコマンド一発とAzure Portalの操作だけで完結します。
Check! Azure 仮想マシンで、Linux ベースのカスタムイメージを作成する - Qiita
また、カスタムイメージのresource idはAzure Portalの概要から文字列が確認
できますので、それをコピペすると楽ちんです。
次にvariablesです。
こちらは固定定義となる部分ですが、必要に応じてparametersへ移動して
ください。ここでは様々なコンポーネントの名前を全て固定で入れてます。
AppGWに付けるPublicIPは80port/tcpのみ許可する設定を入れてます。
InstanceCountは2にしていますので、VMSSの初期ノード数は2VMです。
こちらは変更しないでください。任意な初期台数で指定できるresourcesの
書き方にはしていませんので。(VMSSでネットワーク定義している
NiCの数は2本固定で入れてますから)
最後resourcesです。
利用しているtypeとAPI versionは以下です。
Microsoft.Network/virtualNetworks 2017-04-01
Microsoft.Network/publicIPAddresses 2017-04-01
Microsoft.Network/applicationGateways 2017-04-01
Microsoft.Network/loadBalancers 2017-04-01
Microsoft.Compute/virtualMachineScaleSets 2017-03-30
Microsoft.Insights/autoscaleSettings 2015-04-01
Public IPのみ2か所定義しています。ALB用とAppGW用の2本です。
AppGWに付けるPublic IPはDynamic(動的アドレス)しか付けられない仕様ですが
ALBに付けるPublic IPはStatic(固定アドレス)で定義しています。
これでVMSSから見たoutbound通信は固定のグローバルアドレスとします。
AppGWではフロントエンドのポートを定義し、バックエンドプール(VMSS側へ
振り分ける対象ノードを定義しています。
大丈夫ですよ、後で確認画面見せますが、3台目、4台目とスケールアウトしても
ちゃんとAppGWから振り分け対象に自動的に入りますし、sshログインも増加した
サーバーへ入ることができますから。
VMSS側では以下のようにイメージのresource idを指定します。
イメージを一般化(Generalize)する前に、systemctl enable nginx(CentOS7.x)を
しておかないとOS起動時にnginxは起動されませんので注意ください。
冒頭でも触れた公開キーの埋め込み方法です。
公開キーはAzureから発行することは現状できませんので、puttyGenなどで自作
してくださいね。
autoscalesettingsは閾値や台数のスケール管理をする部分です。
VMSSノードは最低2台、最大5台としてます。また、CPUの平均値(5分だった
かな)が60%以上続く場合は1台ずつ増加させ、50%以下平均になると1台ずつ
減少させるように記載しています。
全てのデプロイは15分程度で終わります。ちなみにARM templateは40分で
タイムアウトしますので全ての処理は40分以内に終わる処理でなければ
いけません。もちろん各コンポーネントは非同期で処理実行されるため、タイム
アウトした後はできたところまでで切り離され、ロールバックする概念は
ありません。そこんとこ厳しいある。
デプロイが終わると各リソースはこんな風に見えます。
ではVMSS側にsshログインするので、ALB(上ではLoad balancer)を開きます。
※今回はsandbox環境を用意していないので、直接ALBにつけたPublic IPから
SSHログインします。(22ではなく50000ポートでログインします)
英語表記になっちゃってますが、受信NAT規則なるタブから2台のVMのPublic IPと
ポート番号が確認できます。
TeraTermでログインしてみます。
ちゃんとnginxが起動した状態になっていますね。カスタムイメージから
展開されていることがわかります。
ちなみに省略しますが、このVMSSノードからcurlやwgetで他のグローバル
アドレスへ通信した場合、受け側のWebエンジンのaccess_logからSource IP
がALBにつけたPublic IP(static)になっていることがわかります。
これで受け側での許可フィルタリングも問題なくできます。
では次にAppGWのリソースを覗き、AppGWについたPublicIP(+ domain)を
確認します。
軽くマスクしておきましたが、このドメイン or IPアドレスをブラウザで確認
してみましょう。
はい、ちゃんとnginxの初期ページが表示されていますね。
念のためVMSSノード側の/var/log/nginx/access_logを見てみましょう。
192.168.1.11 - - [13/Sep/2017:10:52:09 +0000] "GET / HTTP/1.1" 304 0
"-" "Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; Touch; rv:11.0)
like Gecko" "106.73.2.64:5436"
はい、何度かブラウザアクセスするとわかりますが、2台のどちらにも
上記ログが振り分けられて吐き出されていることがわかります。
VMSS側から見るとAppGWに付けたSubnetのプライベートアドレス
から振り分けられていることがわかりますね。
では最後に意図的にCPU負荷をかけてVMSSがスケールするか、
スケールしたノードへログインでき、AppGWから振り分けされる
状態になっているか、を確認してみましょう。
まずはVMSSの現状を見ておきます。
CPU負荷もまったくかかっていない状態ですので、初期ノード数の2台が
いることがわかります。
負荷かけてみましょう。
cd /var/tmp
wget http://ftp.tu-chemnitz.de/pub/linux/dag/redhat/el7/en/x86_64/rpmforge/RPMS/stress-1.0.2-1.el7.rf.x86_64.rpm
rpm -ivh stress-1.0.2-1.el7.rf.x86_64.rpm
stress -c 1
stressコマンドはCentOS7.xにプリインストールされていないため
盛ってきました。また、今回のVMサイズはStandard_A1でやってますので
vCPUは1つです。なのでstressコマンドの引数に -c 1を指定しています。
CPU Percentageのグラフが追い付いていませんが(笑)、ちゃんと
CPUの負荷を検知し3台目を追加しようと動き始めていますね。ステキ。
ちなみにこの状態で焦って3台目にログインしようとしてはいけません。
まだデプロイ中なのでsshログインできません。もう少し待ちましょう。
ALBの受信NAT規則を見ると3台目(どころか4台目まできてますねw)の
振り分け先が追加され、ポートも50003番で追加されているのがわかります。
はい、増加した3台目にログインでき、nginxが起動している状態が確認
できました。
ちゃんと/var/log/nginx/access_logをtailで見ながらブラウザでnginxの初期
画面を更新していると、振り分けられているログを確認することができ
ました。
192.168.1.7 - - [13/Sep/2017:11:27:34 +0000] "GET / HTTP/1.1" 304 0 "-" "Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; Touch; rv:11.0) like Gecko" "106.73.2.64:62770"
以上になりますが、いかがでしょうかね。
そもそもステートレスな環境にステートフルなものを組み合わせていること
事態に違和感を覚えなくもないですが(笑)、割とエンタープライズな
お客様を相手にしていると、こういった構成じゃないと要件を満たすことが
難しい場合もあります。ご参考まで。