Tag Archives

3 Articles

Azure設計プラクティス3: Traffic ManagerによるApp ServiceとVM間での負荷分散

前回に引き続き設計プラクティスです。

今回は前々回にLoadBalancerで複数のVMの負荷分散を行ったのに対し、TrafficManagerというものを利用してApp ServiceとVirtualMachine間で負荷分散を行います。

今回の構成はこのようになっています。

WebAppsとVirtualMachineの2つのWebホストへのアクセスをTrafficManagerによって分散します。

TrafficManagerはDNSレベルで動作し、*.trafficmanager.netに来たDNS要求に対し、ルールに基づいて決定したCNAMEを返します。

例えばgariweb1.azurewebsites.netにトラフィックをさばくべきだとTrafficManagerが判断すれば、DNSの名前解決要求が来た時にCNAMEレコードにgariweb1.azurewebsites.netを入れて返信します。

TrafficManagerの分散ルールは公式サイトにあるとおりです。

  • 優先順位: すべてのトラフィックにプライマリ サービス エンドポイントを使用し、プライマリ エンドポイントまたはバックアップ エンドポイントが使用できない場合に備えてバックアップを用意する場合は、”優先順位” を選択します。
  • 重み付け: 一連のエンドポイントに、均等にまたは定義した重みに従ってトラフィックを分散させる場合は、”重み付け” を選択します。
  • パフォーマンス: 複数のエンドポイントが地理的に異なる場所にあり、エンド ユーザーが、ネットワーク待ち時間が最も短いという意味で “最も近い” エンドポイントを使用できるようにする場合は、”パフォーマンス” を選択します。
  • 地理的: DNS クエリの発信元の地理的な場所に基づいてユーザーを特定のエンドポイント (Azure、外部または入れ子になっている) に割り当てる場合に “地理的” を選択します。 こうすることで、Traffic Manager の利用者は、ユーザーのリージョンを把握し、そのリージョンに基づいてユーザーをルーティングすることが重要なシナリオを実現できます。 データ主権規制、コンテンツおよびユーザー エクスペリエンスのローカライズ、さまざまなリージョンからのトラフィックの測定がその例に挙げられます。

今回は優先順位のルールを用いて負荷分散を行います。

AppServiceを作る

負荷分散されるインスタンスの1つを作ります。

今回はWebAppsにPHPのアプリを作るということとします。

Virtual Machineを作る

続いて負荷分散されるもう片方のインスタンスであるVirtualMachineを作成します。

UbuntuのVirtualMachineを作成します。

LoadBalancerではVirtualMachineのスペックは負荷分散が書いてあるものでないとダメでしたがTrafficManagerでは必要ありません。

今回はA0としました。

仮想ネットワーク、セキュリティグループ等、デフォルトでOKです。

VirtualMachineを作成できたら、紐付いているパブリックIPにDNS名をつけましょう。

パブリックIPの構成から好きなDNS名をつけます。

さらに紐付いているネットワークセキュリティグループの受信ルールからhttpの80番ポートを許可します。

TrafficManagerを作成する

続いて上記の2つのインスタンスの負荷分散を行うTrafficManagerを作成しましょう。

TrafficManagerはAzureで「TrafficManagerプロファイル」と検索すると出てきます。

ルーティング方法は今回は「優先度」とします。

TrafficManagerを作成することができたら、エンドポイントを追加します。

エンドポイントとはTrafficManagerが負荷分散した先のインスタンスとなります。

ですので作成したWebAppsとVirtualMachineを指定しましょう。

ターゲットリソースはWebAppsの場合「AppService」

VirtualMachineの場合、VMに紐付いているパブリックIPとしましょう。

(TrafficManagerはDNSレベルで動作するため、パブリックIPにDNS名をつけていないとここで指定することができません)

以上でTrafficManagerの設定は完了です。

アプリをデプロイする

ではWebアプリを配置していきましょう。

まずはAppServiceからです。

AppServiceの場合、様々なデプロイ方法がありますが今回はローカルgitリポジトリから配置します。

WebAppsの「デプロイオプション」からローカルGitリポジトリを選択します。

するとWebAppsの「概要」の部分にGitクローンURLというものができるのでこのURLをgit cloneしましょう。

その上にあるGit/デプロイメントユーザー名が何も表示されていない人は資格情報からデプロイユーザーを作成しましょう。

クローンできたら中にindex.phpを作成し、中身をこのようにしましょう。

index.phpを作成できたら git pushします。

WebAppsにアクセスしてこのように表示されればOKです。

つづいてVMに同じアプリをデプロイしましょう。

VMにsshでログインし、下記のコマンドを実行し、lamp環境を整えましょう。

lamp環境を整えることができたらindex.phpを作成しましょう。

index.phpの中身は以下のようにします。

VMのDNS名にアクセスすると以下のように表示されたらOKです。

TrafficManagerにアクセスする

ではアプリを配置できたので負荷分散ができているか試してみましょう。

VMの方のページが表示されました。

これは現在のTrafficManagerのルーティングルールが「優先度」であり、WebAppsの優先度が1、VMの優先度が2であるため、優先度が高いVMのほうが表示されています。

 

Azure設計プラクティス2: SQL Databaseのgeoレプリケーションによる冗長構成

Azure SQL Databaseはgeoレプリケーションをサポートしており管理ポータルから数クリックで冗長構成を実現できます。

レプリケーションとは同じデータを持つデータベース(レプリカ)を2つ以上別のデータセンターなどに配置しておくことによって、データを保証したり可用性を実現するものです。

例えば1つのデータベースに障害が発生したとき、同じデータを持つデータベースが別のサーバーにあれば即座に元のデータを復元できます。

さらに、データベースに障害が発生した時にレプリカのデータベースが障害が発生したデータベースの代わりにマスターDBになることでフェールオーバーを実現します。

geoレプリケーションとは地理的に離れたデータセンター間でデータをレプリケーションすることを指します。

今回はAzure SQL Databaseをつかってgeoレプリケーションを実現してみましょう。

今回の構成はこのようにします。

SQL Databaseは東日本リージョンと米国西部リージョンの2つでレプリケーションすることとし、App Serviceからのトランザクションをさばきます。

上記の構成では東日本リージョンにあるDBのみにデータを書き込むことができ、このようなDBをMaster(Azureの場合はプライマリ)と呼びます。

米国西部にあるリージョンは読み込み専用とし、App Serviceからの読み込みのみのトランザクションを受け付けます。このようなDBをSlave(Azureの場合はセカンダリ)と呼びます。

もし東日本リージョンで障害が発生し、Masterが機能しなくなったとき、SlaveのDBがMasterに昇格し、書き込み可能となることでフェールオーバーを実現します。

WebAppsを作る

まず最初に、DBにアクセスするためのWebアプリケーションを作成します。

リージョンは東日本とします。

Master DBを作る

東日本に置くMaster DBを作ります。

リージョンは東日本とし、サーバーも新しく作成してください。

価格レベルは一番安いもので大丈夫です。

Slave DBを作る

続いてレプリカ用のSlave DBを作ります。

先ほど作成したMaster DBの管理画面を開き、「geo レプリケーション」を選択します。

ターゲットリージョンから「米国西部」を選択します。

Slave DBの構成を聞かれますがMasterと同じ性能にしなければいけないのでそのままにします。

サーバーは米国西部に新しく作成します。

Slave DBを作成することができたらレプリケーションは完了です。

プライマリと表示されているのがMasterでセカンダリと表示されているのがSlave DBです。

ASP.net MVCから接続するアプリケーションを作る

ではこれらの冗長構成のSQL DatabaseのMaster DBにデータを入れるアプリをASP.netで作ってみます。

ASP.net MVCで新規プロジェクトを作成します。

NugetからEntityFrameworkを追加します。

Web.configを編集し、接続文字列を追加します。

接続文字列は作成したMaster DBの管理画面から取得することができます。

接続文字列の中にはユーザー名とパスワードが埋まっていないので自身のDBServerに設定したユーザー名とパスワードを設定します。

接続文字列の名前は後ほど作成するDbContextと同じものにする必要があります。今回はItemContextとしました。

Modelフォルダ内に下記のモデルを作成します。

今回はItemというモデルで1つのメッセージを管理します。

ItemContextは接続文字列と同じ名前にしてください。

下記の場合、データベースにItemsというテーブルができます。

HomeControllerを以下のようにします。

Indexは通常ページを返し、AddItemはajaxから呼び出され、DBに値を追加するアクションメソッドです。

Index.cshtmlを下記のようにします。

アクセスされるとDB内の値を表示し、buttonがクリックされるとAddItemアクションメソッドにajaxでアクセスしてデータベースに1つ値を追加します。

これでASP.netのアプリは完成です。

VisualStudioのメニューバー>[ビルド]>[{project名}の発行]から先ほど作成したWebAppsへデプロイを行いましょう。

データ追加を押すたびに[moge]が1つ増えます。

DBを見てみる

ではデータベースにデータが入っているかMaster DBを見てみましょう。

今回はDataGripというツールを使ってデータを見ていますがWindowsの方はSQL Server Management Serviceというツールを使うのが良いかと思います。

データが入っていました。

ではレプリケーション先のslaveのDBを見てみましょう。

データが入っていませんでした。

レプリケーションされているならslaveにも同じデータが入っているはずですがはいっていないのはとても気になります。

@Masayuki_Ozawa さんいわくレプリケーションには多少タイムラグがあるそうです。それが原因でまだ反映されてないと思われます。

数時間ほど待ったところ、無事レプリケーションできていました。

フェールオーバーしてみる

geoレプリケーションをしている場合、slave DBをボタン1つでMasterに昇格することができます。

セカンダリのDBの右端をクリックして「フェールオーバー」を押します。

セカンダリDBがプライマリDBへと昇格しました。

アプリケーションの接続文字列はMasterとSlaveで違うので切り替える必要があります。

Azure設計プラクティス1: LoadBalancerによるLinux仮想マシンの冗長構成

そういえばMicrosoft Azureを使っているとはいえPaaSの使い方を勉強していることが多く、クラウドらしくないとふと思いたったのでちゃんとクラウドらしいことをやってみようと思って公式ドキュメントを貪ってみたらあまりよい情報が載っていなかったので続くまで練習がてら書いてみようと思います。

対象はAzureにある程度課金できる人を想定しています。

 

今回の想定は以下のような構成です

インターネットからのアクセスをLoadBalancerで受け取り、VirtualNet内にある2つのVMに負荷分散しながらトラフィックをさばきます。

さらに2つのVMはSecurityGroupによって80番ポートが開放されています。

このような同じVirtualMachineを複数台用意し、負荷分散をすることを冗長構成と呼びます。

もし片方のマシンが障害で止まってしまったとしてもLoadBalancerによってもう片方のマシンにトラフィックを集め、ユーザーからのアクセスに的確に応答します。

今回はこのような冗長性のあるUbuntu Virtual Machineを構成し、ApacheでWebサイトを作ってみます。

ネットワークを構築する

まず、ロードバランサーへのアクセス先となるパブリックIPを一つ作成します。

このIPへのトラフィックがロードバランサーによって分散されることになります。

続いて2台のVMを包むVirtual Netを作成します。

サブネットのアドレス空間は192.168.0.0/24とします。

セキュリティグループを作成します。

このセキュリティグループはファイアウォールのような役割を果たし、特定のポート以外のアクセスを遮断します。

 

仮想マシンを作成する

負荷分散するAzure Virtual Machineを2台作成します。

OSはUbuntuとしてください。

この時、サイズは「負荷分散」のオプションが書いてあるものにしてください。Basicプランなどは負荷分散のオプションがありません。

今回は負荷分散がある中で一番安いA0 Standardとしました。

設定ではVirtual Networkとサブネット、ネットワーク・セキュリティグループは必ず先ほど作成したものを指定してください。

パブリックIPアドレスだけは新規作成してください(なぜなら前に作成したパブリックIPはロードバランサーに紐付けるものだからです)

作成時の設定では可用性セットを設定してください。

可用性セットとは複数のAzure Virtual Machineのグループの・ようなもので同一可用性セット内のVirtual MachineはAzureインフラないで分散配置されます。

分散配置されることによって、Azureのハードウエア的な障害や計画メンテナンスなどがおこなわれたとしても対象となっていないVirtualMachineが稼働し続けることができます。

何番のドメインにVMを配置するかは「障害ドメイン」と「更新ドメイン」の数字を切り替えて設定します。

2台目のVirtualMachineを作成します。同様のA0インスタンスでVirtualNetやネットワーク・セキュリティグループは前に作成したものを、パブリックIPアドレスは新規作成。可用性セットは先ほど作成した可用性セットを指定します。

VMを2つ、同一の可用性セット内に作成することができました。

ロードバランサーを作成する

続いてロードバランサーを作成します。

ロードバランサーとはネットワークのトラフィックを複数の機器に分散する負荷分散機です。

Azureには負荷分散装置として以下の3つがあります。

  • Azure Load Balancer
  • Application Gateway
  • Traffic Manager

それらの違いはこちらのページに書いてあります。

その中でもLoad BarancerはOSI参照モデルのトランスポート層で動作し、負荷分散先としてはAzure Virtual Machine か Cloud Serviceのどちらかとなります。

したがってApp Serviceなどに負荷分散をしたい場合はTraffic Managerを利用するのがよいと思われます。

今回はVirtual Machineに負荷分散するのでLoad Barancerで構築します。

ロードバランサーは作成時に「パブリック」か「内部」かを指定できます。

こちらはどこからくるトラフィックを分散するかという話になるので今回はインターネットからのトラフィックを負荷分散したいため、パブリックとします。

パブリックに指定した場合、Load BarancerにIPアドレスを紐付けなければいけません。

パブリックIPを最初に作成したロードバランサーに紐付けるパブリックIPアドレスを指定してください

ここまでの構成要素

ここまでで負荷分散を行うシステムの要素は揃いました。

ここまでで作成したものはすべて下図のようになります。

続いて構成要素の各種設定をしていきましょう。

ロードバランサーの設定をする

 

作成したロードバランサーを表示し、「バックエンドプール」を見ます。

バックエンドプールとは分散先の機器を登録するプールとなります。

追加を押し、先ほど作成した可用性セットを指定します。

ターゲットネットワークIPは必ず作成した2つのVirtualMachineのIPとします。

2つのターゲット仮想マシンを追加できたらOKです。

続いてロードバランサーの「正常性プローブ」を設定します。

「追加」から80番ポートの正常性プローブを追加します。

さらに「負荷分散規則」を設定します。「追加」から作成しましょう。

セキュリティグループで80番を開放する

今回はHttpリクエストを通したいのでセキュリティグループから80番ポートの受信トラフィックを許可します。

sshの22番ポートも開けておきます。

UbuntuにログインしてApacheを起動する

ロードバランサーにもパブリックIPアドレスは割り当てられていますが個々のVMにもパブリックIPが割り当てられています。

このIPアドレスを使ってsshでログインします。

紐付けられているIPアドレスはVirtualMachineの管理画面から見ることができます。

sshでログインします。

ログインできたら以下のコマンドを入力しLAMP環境を整えます。

今回は負荷分散の動作確認のためにHTMLでIPアドレスを表示してみましょう。

デフォルトのHTMLを削除します。

IPアドレスを表示するPHPのプログラムを書き込みます。

これでVirtualMachineの80番ポートにアクセスするとサーバーのIPアドレスを表示するようになりました。

以上の設定をもうひとつのVirtualMachineにも行いましょう。

アクセスしてみる

最初に作成したロードバランサーに紐付いているIPアドレスにブラウザーからアクセスしてみましょう。

IPアドレスが表示されればOKです。これは先ほど作成したPHPのプログラムの出力結果で、このIPアドレスで動作するVMがアクセスに応答を返していることになります。

では意図的に障害を発生させてみましょう。

表示されたIPアドレスをローカルのIPとして持つVirtualMachineを停止させてみます。

表示されているローカルIPアドレスはVMを包んでいるVirtual Netが管理しているためVirtual NetからたどればどのVMがそのIPかがわかります。

停止させます。

停止できたら再度ブラウザでアクセスしてみましょう。

先ほどと違い、もうひとつのVirtualMachineに紐付いているIPアドレスが表示されました。

以上から、ロードバランサーによって2つのVirtualMachineにトラフィックを分散できていることがわかります。

もし片方のVMが止まったとしてももう片方が動き続けるので可用性が高くなります。