2016/12/15

AWSでWebサービスを構築08 サーバ冗長化とロードバランサの構築

前回までにAPサーバ、DBインスタンスを作成した。
ただ、このままでは一般的なレンタルサーバなどと特に構成が変わらない。
AWSなどのクラウドプラットフォームだと、よりサービスに適した構成をとることが出来る。
今回はインスタンスの構成について、もう少し改善したい。

具体的には、サーバの冗長化と負荷分散機構について説明する。



インスタンス構成の前知識


一般的なWebサービスでは、どのようなサーバ構成を取っているのだろうか?
もちろんサービスによるが、あくまで一般的・汎用的な構成を考える。

まず、サーバを構成する上で重要な点として
  • 耐障害性の確保
  • 負荷分散
が主に挙げられる。

耐障害性に関しては冗長化(多重化)を行うことで、一つのルートで障害が起きても他のルートでサービスが継続できる、という構成にすることができる。
負荷分散もサーバを複数用意して、それらに処理を分散することで達成できる。

これらの点を考えると、次のような構成になることが多い。



上図はインターネットからHTTP通信が来た場合の図となる。
まずはロードバランサー(LB)というインスタンスに通信が来る。
ロードバランサーは、
  1. アクセス元から通信を受けた場合、そのまま他のサーバに丸投げする。丸投げ先からレスポンスがきたら、それをアクセス元に返す
  2. 1の送付先を、負荷分散を踏まえて選択する
  3. 1の送付先をヘルスチェックして、機能していないものを送付先から外す
という機能を持つ。
1の機能はリバースプロキシと呼ばれる。
狭義には2の機能をロードバランシング機能とか呼ぶわけだが、だいたいロードバランサと言ったら1、2、3をあわせ持つ。

本来だったらLBとしてNginxなどをインストールしたEC2インスタンスを用意するが、めんどくさいよね。
AWSではロードバランサ機能を提供しているため、これを使用する。
(正式にはAWS ELBと呼ばれる機能)

上の図を見ていたら「アレ・・・?これLBに隕石落ちたらサービス止まっちゃうジャン・・・?」と気づくかもしれない。
おっしゃる通り。ただ、AWSのELBはすでに冗長化されている機能なので、気にする必要がない。すごい。


EC2インスタンスの冗長化


EC2インスタンスの冗長化は、異なるサブネットにそれぞれインスタンスを立ち上げることで実現する。
サブネット1が動作不能になってもサブネット2のシステムで対応できるのでサービスが停止しない、という仕組みだ。

先日EC2を作成した際に作ったAMIがあると思うが、このAMIから異なる公開サブネットに一つづつインスタンスを立ち上げよう。
EC2の管理画面から、画面左部の「インスタンス」を選択して、画面上部の「インスタンスの作成」ボタンを選択する。



AMIの選択画面の画面左部から「マイAMI」を選択すると、先日保存したAMIが出てくるので、これを選択する。
(このAMIのからサーバを複製することになるので、AMI作成時からAPサーバを更新していたら、新しくAMIを作成しよう)

その他はVPCを適切に選択することと、サブネットの選択に気をつける。
1つ目のインスタンスはサブネット1、2つ目のインスタンスはサブネット2、などといった具合に選択する。

ここでは2つのインスタンスで冗長化しているだけだが、負荷分散の効果を考えるなら、1サブネットに1つではなく複数のインスタンスを立ち上げてもいい。
このようにして立ち上げた複数のインスタンスを、後ほどロードバランサに接続してクラスタとする。


ロードバランサの構築


EC2の管理画面の左部メニューから「ロードバランシング→ロードバランサー」を選択すると、ロードバランサの管理画面が表示される。
画面上部の「ロードバランサーの作成」ボタンを選択すると、ウィザードが開始される。



まずはロードバランサのタイプを選択する。
HTTP/HTTPS以外のプロトコルが必要な場合はClassicを選択するといいが、基本的にはApplicationを選択することが多いだろう。
今回も「Application Load Balancer」を選択する。

ロードバランサーの設定


次はロードバランサーの設定情報を入力する。
「名前」は適当に。サービス名+LB001とかでいいんじゃないだろうか。
「スキーム」は外部アクセスの負荷分散用なので「インターネット向け」を選択する。

「リスナー」に関してはHTTPがすでに登録されているが、HTTPSが必要な場合は追加する。
今回はHTTPのみとする。

「アベイラビリティーゾーン」は、受けたリクエストをどのAZに流すかを設定する項目となる。
現在アプリケーションサーバは2つの公開サブネットに起動したので、この2つの公開サブネットを追加する。
※VPCはちゃんと選択すること。

画面右下部の「次の手順」ボタンを選択する。

セキュリティ設定の構成


ここでは先ほどの画面でHTTPSをリスナーに加えた場合に設定する画面となる。
証明書の運用方法の選択などを行うが、今回はHTTPSは想定していないのでスキップする。
(HTTPSは後ほどまとめて記事にするかも。)

画面右下部の「次の手順」ボタンを選択する。

セキュリティグループの設定


ここではロードバランサーのセキュリティグループを作成・選択する。
基本的にはAPサーバと同じグループでOK。
ただSSHはいらないので、APサーバのセキュリティグループの列の右部から「コピーして新規作成」を選択して、SSHのみ削除するといい。
グループ名は適当に設定する。サービス+LBとかでいいかと。

設定したら、画面右下部の「次の手順」ボタンを選択する。

ルーティングの設定


ここでは、リクエストを投げる対象の「ターゲットグループ」と、投げる対象のサーバが機能しているかを確認する「ヘルスチェック」に関する設定を行う。

ヘルスチェックは、LBからHTTP/HTTPSでアクセスしてサーバがレスポンスを返すか、という形で実現されるが、そのアクセス先を設定できるのでより複雑なヘルスチェックを実現できる。
例えばあるphpファイルをヘルスチェックの対象に指定して、そのphp内でサーバの詳細な状態を確認し、問題があったらエラーステータスコードを返す・・・という方法でより詳細になヘルスチェックを実装することも可能。
(ただのHTTPアクセスのヘルスチェックではDBが生きているかを確認できないが、php内で「DBに接続して失敗したらエラーとする」という実装を行うことでDBの状態も確認できる)

基本は初期設定で問題ないが、ターゲットグループに関しては新規に作成するため、ターゲットグループ名を登録する必要がある。
サービス+LBTarget001とかでいいんじゃないだろうか。

画面右下部の「次の手順」ボタンを選択する。

ターゲットの登録


この画面では、実際に負荷分散でリクエストを送る先のサーバを指定する。
選択できるAPがすでにリストアップされているため、対象となるサーバを選択する。
ここでは、上で起動した2つのインスタンスにチェックを入れ「登録済みに追加」ボタンを選択する。

画面右下部の「次の手順」ボタンを選択すると確認画面となるので、問題なければ「作成」ボタンを選択する。


アクセスの確認


EC2の管理画面から、画面左部の「ロードバランシング→ロードバランサー」を選択すると、先ほど作成したLBがリストに表示される。
そのロードバランサを選択すると、下部に詳細な情報が表示される。



ここでDNS名という項目があるかと思う。
AWSのLBにはデフォルトでドメインが割り当てられうので、これでをブラウザに入力して確認する。

上記インスタンスのAMIではApacheを動かしただけだったため、「Amazon Linux AMI Test Page」が表示されると成功。
どちらかのインスタンスのApacheがレスポンスを返しているはず。



今回対象インスタンス数は2つだったが、もちろんもっと多くてもいい。
実際のサービスをやる際には、多くのインスタンスを対象にするべきだろう。

小〜中規模のサービスまでだったらこうして手動でターゲットを指定してもいいが、大規模になると勝手にやってほしくなるだろう。
サーバ数を増やして負荷分散することを「スケーリング」と呼んだりするが、これを自動でやってくれる「オートスケーリング」を設定してもいい。
これは、必要に応じてインスタンスを勝手に立ち上げてくれたりする便利なもの。これも後ほど記事を書くかもしれない。

とりあえずはレンタルサーバなどより一歩先んじた部分が出てきた。
ここまでの知識である程度のサービスなら対応は可能かと思うので、次回からは運用に関していくつかのトピックでまとめる予定。

0 件のコメント:

コメントを投稿