Windows Azure アプリケーションの構成とか

Windows Azureのアプリケーションを作る際、どのようにロールを構成してエンドポイントを設定して…というのは結構悩みどころかなという気がするんですが皆様いかがでしょうか。

単純にSQL Azure(DB)+Webサーバーx n 台あればいいYO!という構成だと(インフラ的なところで)悩むところはあまりないのですが、Worker Role絡んだり、WebフロントエンドとバックエンドとDBと…とかになってくると意外とはまりそうですね。ええ、はまってますとも。

ということで今日はWindows Azureの構成とパッケージング、エンドポイントあたりをダラダラと考察したいと思います。

構成の基本

メインとなるサービスパッケージは複数のロールを含みます。ロールの数はサービスパッケージにつき5ロールまでです。
各ロールには5つのエンドポイントを定義できます。(Input/Internal問わず) またリモートデスクトップ接続を構成する場合は2つのエンドポイントを消費するので実質利用可能なエンドポイントは3つになります。

各ロールは指定した数のインスタンスを起動できます。但しSインスタンスが1コア扱いとなり、XLだと1インスタンスで8Core消費するので注意が必要です。1つの契約で通常20コアまで。(ただし申請すれば拡張できます)

ホストサービスはサブスクリプションによって最大数が変わります。制限範囲内であれば複数のホストサービスを定義できます。

各ホストサービスはWindows Azureの世界各地のいずれかのデータセンターに属します。
アフィニティグループを定義すれば、同一データセンター内でも同じアフィニティグループ内にあるホストサービス等はネットワーク上近くに配置されるようです。

アフィニティグループにはホストサービスとWindows Azure Storageを含めることができます。

ホストサービス外からの接続を受け付けるにはInputエンドポイントを定義します。
InputEndpointで定義したポートへアクセスがあると、ロードバランサーが内部のロールインスタンスに分散して接続させます。
※アフィニティはありませんので同一インスタンスにアクセスする保証はありません。

Internalエンドポイントはロードバランスされません。(接続する場合、ロールインスタンスを指定する必要があります)
また、Internalエンドポイントはホストサービス外からアクセスできません。
あと、エンドポイントはInternal/Inputに限らずUDPが使えません。定義できるのはTCP(とHTTP/HTTPS)です。

Inputエンドポイントは外部公開するポートのほかに、インスタンスで実際にListienするポートを定義できます。(SDK 1.3以降のみ)

エンドポイントへの接続性について考えるとざっくり上図のような感じです。
Internalエンドポイントはホストサービスを跨ると接続できません。(もちろん外部からも接続できません)

 

応用

ホストサービスをまたがると、外部と同様に結構制限ありますね。
逆に考えてホストサービスをわざわざ分ける必要があるのはどんな時か?ですが、上述の制限を回避したい場合が主な要因になると思います。

例えば、

  • エンドポイント数が制限に達した。
  • デプロイするパッケージを分けたい(サービスパッケージはホストサービス単位ですよね。※厳密にはProductionとStagingがありますが)
  • ネットワークの構成を柔軟にしたい。

などなど…

Webのフロントエンド等、初期配置されても構わない系はいいのですが、例えばMySQL等のデータファイルに注意したりする必要があるもの、ライフサイクルが異なるものは同じタイミングでアップグレードやReImageされたりすると困りますね。

アップグレードについてはロール単位でも可能ですが、パッケージが同一であるということを考えると「障害発生時に全部一度に戻る」を考えると分けたいという要件もあると思います。

またホストサービスに一蓮托生なので冗長化しようとすると、どうしてもホストサービスを分けたり、そもそもデータセンターも分散したり、、といったことも考慮したくなります。

ということでホストサービスを分けてサービスパッケージを分割したり、ライフサイクルを変えたりすることも視野に入れるのですが、今度は各ホストサービス・ロール間の通信はInputエンドポイント経由にする必要があります。とすると今度はインターネットにオープンになっちゃうという弊害がでます。

もともと内部のみの通信をしたいのにしょうがなくInputエンドポイントを定義してるのに、今度は不用意に攻撃にさらされる可能性があると…

回避策は?というと正式サービスのみで考えると、もう各ロールインスタンス上のファイアウォールで制限かけるのがいいかもですね。

ちょっと乱暴ですが、ファイル共有を内部だけに制限する場合、スタートアップタスクで以下のようなコマンドを実行してファイアウォールにルールを追加したりします。

netsh firewall set service type=fileandprint mode=enable profile=Current address=10.0.0.0/8 scope=custom

DC内部ということで無理やりローカルのセグメント全部許可してますが、一応外部からは接続を拒否できます。
(ほんとはデフォルト拒否で許可するIPだけ絞る必要があります=事前に何かしらインスタンスのIPアドレスを共有しておく必要と、自動的な構成の仕組みを考慮する必要があります…)

まぁあくまで一例です。

基本的にデータセンター内は10.x.x.xなセグメントのIPアドレスが振られると思いますが、当然ながらサブネット間のルーティングはかなり制限されます。(DC間はもちろんOUT)
※Inputエンドポイント経由にすることでこれは回避できると思いますが…

なので、できるだけアフィニティグループを使って近くに配置されるようにするのがいいんじゃないかな?

 

将来的には…

現時点ではこのあたりが精いっぱい?

でも面倒だし。やりたくないし。

他に回避策は?ということで一番いいのはWindows Azure Connectを使用してホストサービス/ロールインスタンス間の専用ネットワークを作るのがベターかもです。

これで制限は回避できて安全に通信を行うことができますね。但し、ロードバランサはありませんので内部間通信で負荷分散したい場合は自前で考えましょう。
(WebならARRとか?)

また同一DCの場合、ホストサービス分けても安心できない場合とかあるかと思います。
その場合は昨日アナウンスされたTraffic Managerを使うことでデータセンターをまたがったホストサービス間で負荷分散やフェイルオーバー、ラウンドロビンを構成することができるようになると思われます。

※フェイルオーバーの場合、待機系も起動しっぱなしにする必要があるので、インスタンス数等お金と相談ですね~

まとめ

ということで、Windows Azureアプリケーションの構成を考えるにあたっては

  • エンドポイントの定義
  • ロールの役割とライフサイクル
  • アプリケーション負荷
  • 障害対策・冗長性
  • 生産性・保守性(サービスパッケージの分割等)

あたりを考慮して設計すればいいんじゃないかなーと勝手に思ってます。

おわり。

ふぅ、駄文な気がする。

広告

コメントを残す

以下に詳細を記入するか、アイコンをクリックしてログインしてください。

WordPress.com ロゴ

WordPress.com アカウントを使ってコメントしています。 ログアウト / 変更 )

Twitter 画像

Twitter アカウントを使ってコメントしています。 ログアウト / 変更 )

Facebook の写真

Facebook アカウントを使ってコメントしています。 ログアウト / 変更 )

Google+ フォト

Google+ アカウントを使ってコメントしています。 ログアウト / 変更 )

%s と連携中