LinuxユーザーがイジるはじめてのAzure

LinuxユーザーがMicrosoft Azureを使いこなせるように応援するブログです

カスタムイメージを基にスケールする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の文字列の後ろに半角スペースを入れた後、

公開キーの文字列をベタっと張り付けてください。

f:id:akazure:20170912194103j:plain

 

この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をベタっと

はりつけます。

f:id:akazure:20170912194704j:plain

 

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本です。

f:id:akazure:20170913114825j:plain

 

AppGWに付けるPublic IPはDynamic(動的アドレス)しか付けられない仕様ですが

ALBに付けるPublic IPはStatic(固定アドレス)で定義しています。

これでVMSSから見たoutbound通信は固定のグローバルアドレスとします。

 

AppGWではフロントエンドのポートを定義し、バックエンドプール(VMSS側へ

振り分ける対象ノードを定義しています。

f:id:akazure:20170913115153j:plain

大丈夫ですよ、後で確認画面見せますが、3台目、4台目とスケールアウトしても

ちゃんとAppGWから振り分け対象に自動的に入りますし、sshログインも増加した

サーバーへ入ることができますから。

 

VMSS側では以下のようにイメージのresource idを指定します。

f:id:akazure:20170913115521j:plain

イメージを一般化(Generalize)する前に、systemctl enable nginx(CentOS7.x)を

しておかないとOS起動時にnginxは起動されませんので注意ください。

 

冒頭でも触れた公開キーの埋め込み方法です。

f:id:akazure:20170913115832j:plain

公開キーはAzureから発行することは現状できませんので、puttyGenなどで自作

してくださいね。

 

autoscalesettingsは閾値や台数のスケール管理をする部分です。

f:id:akazure:20170913120013j:plain

 

VMSSノードは最低2台、最大5台としてます。また、CPUの平均値(5分だった

かな)が60%以上続く場合は1台ずつ増加させ、50%以下平均になると1台ずつ

減少させるように記載しています。

 

全てのデプロイは15分程度で終わります。ちなみにARM templateは40分で

タイムアウトしますので全ての処理は40分以内に終わる処理でなければ

いけません。もちろん各コンポーネントは非同期で処理実行されるため、タイム

アウトした後はできたところまでで切り離され、ロールバックする概念は

ありません。そこんとこ厳しいある。

 

デプロイが終わると各リソースはこんな風に見えます。

f:id:akazure:20170913120911j:plain

 

ではVMSS側にsshログインするので、ALB(上ではLoad balancer)を開きます。

※今回はsandbox環境を用意していないので、直接ALBにつけたPublic IPから

 SSHログインします。(22ではなく50000ポートでログインします)

 

f:id:akazure:20170913194124j:plain

 

英語表記になっちゃってますが、受信NAT規則なるタブから2台のVMのPublic IPと

ポート番号が確認できます。

 

TeraTermでログインしてみます。

f:id:akazure:20170913194312j:plain

 

f:id:akazure:20170913194417j:plain

 

ちゃんとnginxが起動した状態になっていますね。カスタムイメージから

展開されていることがわかります。

 

ちなみに省略しますが、このVMSSノードからcurlwgetで他のグローバル

アドレスへ通信した場合、受け側のWebエンジンのaccess_logからSource IP

がALBにつけたPublic IP(static)になっていることがわかります。

これで受け側での許可フィルタリングも問題なくできます。

 

では次にAppGWのリソースを覗き、AppGWについたPublicIP(+ domain)を

確認します。

f:id:akazure:20170913194955j:plain

 

軽くマスクしておきましたが、このドメイン or IPアドレスをブラウザで確認

してみましょう。

 

f:id:akazure:20170913195105j:plain

はい、ちゃんと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の現状を見ておきます。

f:id:akazure:20170913200343j:plain

 

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台目を追加しようと動き始めていますね。ステキ。

f:id:akazure:20170913200901j:plain

 

ちなみにこの状態で焦って3台目にログインしようとしてはいけません。

まだデプロイ中なのでsshログインできません。もう少し待ちましょう。

 

ALBの受信NAT規則を見ると3台目(どころか4台目まできてますねw)の

振り分け先が追加され、ポートも50003番で追加されているのがわかります。

f:id:akazure:20170913201325j:plain

 

はい、増加した3台目にログインでき、nginxが起動している状態が確認

できました。

f:id:akazure:20170913202705j:plain

 

ちゃんと/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"

 

 

以上になりますが、いかがでしょうかね。

そもそもステートレスな環境にステートフルなものを組み合わせていること

事態に違和感を覚えなくもないですが(笑)、割とエンタープライズ

お客様を相手にしていると、こういった構成じゃないと要件を満たすことが

難しい場合もあります。ご参考まで。