AWSで可用性の高いWEBサービステンプレートを構築する

f:id:watass:20141103203916j:plain

Elastic Beanstalkをちょこまかいじっていたわけですが、ちょっと挫折しちゃいました。
後々にサービスを拡張することを考えるならば、VPCを使えたほうがいいよねと思って、Elastic BeanstalkからVPCの設定をやってみたものの、なんかうまくいかんくなってああああああああああってなったので、勉強の意味も込めて、一から構築することにしました。
決してElastic Beanstalkで遊んでいた時間は無駄ではなかったと思いますよ?なんかいろいろなサービスに理解が深まったし。ただ、各サービスをしっかり理解できていれば、Elastic Beanstalkを使う必要も実はないんじゃないかと思ってしま



最終形イメージ

  • ロードバランサで物理的に別の地域に作成されたサーバへトラフィックを負荷分散。
  • 各サーバはクライアントPCのIPアドレスからのみSSH接続可能。
  • 各サーバはロードバランサを経由せずにアクセスできない。

ざっとこんな感じです。
本当はAutoScalingとかRDSの設置とか、IAMの使用とかCloudWatchでの監視とかいろいろやっておきたいわけですが、まずは簡単な構成から、ということでこれだけにしておきます。とはいえ、こんな構成でも高可用性&高セキュリティですし、なかなかオンプレミスで簡単には構築できないでしょう。さっとこんな構成が組めちゃうのがAWSのよさですね。

図にするとこんな感じ。

f:id:watass:20141124220513p:plain

ロードバランサにはELBを使用し、トラフィックの振り分け先は別のアベイラビリティゾーン(AZ)とします。いわゆるマルチAZですね。AZは物理的に別の地域における構成らしいので、災害時などにも対応できるという高可用性を実現します。
後ろの方に何もインスタンスがないネットワークがありますが、これは後々、RDSなどを使用できるように事前に作っておきました。
ELBの配置がちょっと気になるかもしれませんが、ELBは内部的に複数のAZにまたがるような構成になっているそうなので、意図的にどちらかのAZ内に配置するのはちょっと違うのかなーと思いました。

というわけで、上記構成を見てもわかるように、使用するサービスは

  • Elastic Compute Cloud (EC2)
  • Elastic Block Store (EBS)
  • Elastic Load Balancer (ELB)
  • Virtual Private Cloud (VPC)
  • Security Group (SG)

です。それぞれについて解説していきます。


VPCの作成

さて、順番どおりに行くならEC2からですが、大人の事情でまずVPCを作成します。
VPCとは、AWS上に構築することができるネットワークサービスです。実はVPCを設定しなくても、デフォルトVPCといって、基本的なVPCが勝手に作成されて、ネットワークを意識せずともEC2を作成することができるんですが、データベースはインターネット上に公開したくない!と思ったときに、全部EC2と同じネットワーク上だと必然的に公開されてしまうんですよね。SGでブロックすればいいのかもしれませんが、あんま本質的な解決になりません。
VPCを使うと、複数サービスを運用するときにも、それぞれを完全に切り離して運用できたり、外部からのアクセスを許可するパブリックサブネットとローカル内のみアクセスできるプライベートサブネットを作成することができます。

パブリックサブネットを分割する

早速、VPC内のネットワークをサブネット分割して、一方を外部アクセス許可し、一方をローカルからのアクセスしかできないようにします。ちょっとネットワークの理解がないと難しい感じになるわけですが、頑張ってください。
東京リージョンでは現在、提供されているAZは2つのみなので、それぞれのAZでパブリックとプライベートなサブネットを作成します。つまり、サブネットは合計4つになります。

今回作成されたVPC CIDRは172.31.0.0/16で、パブリックサブネットがそれぞれのAZに、172.31.0.0/20と172.31.16.0/20になっています。これはマネージメントコンソールのVPCメニューで確認できます。
この時点でIPアドレスは172.31.0.0〜172.31.31.255まで埋まっていますので、サブネットはこの後のIPアドレスのレンジで作成します。VPCダッシュボードでSubnetを選択、Create Subnetをクリックします。

f:id:watass:20141124223426p:plain

まずは一方のAZにおけるプライベートサブネットを作成します。使用できるのが172.31.32.0〜なので、今回はCIDR blockを172.31.32.0/20とします。これでYes,Createすることでサブネットが作成できます。

Route Tableを作成して、分割したサブネットに紐付ける

これだけではサブネットが作成できただけで、プライベートサブネットとしては機能しません。ポイントはRoute tableになりますので、VPCメニューのRoute Tablesを選択します。単純にCreate Route Tableを選択しましょう。

f:id:watass:20141124224022p:plain

これで作成されたRoute Tableを見てみましょう。きっとlocalへのアクセスのみになっていると思います。これを先ほど分割したサブネットに紐付けることで、ローカル内のみのアクセスを許可するプライベートサブネットが作成できます。サブネットの方で、Route TableのEditができますので、作成した新しいRoute Tableに変更しましょう。

f:id:watass:20141124224618p:plain

これでOKです。プライベートサブネットができました。
ちなみに、パブリックサブネットのRoute Tableは0.0.0.0/0でInternet Gatewayへのアクセスが許可されていると思います。これが外部へのアクセスを許可する要素になっています。確認しておくといいでしょう。

以上を別AZでも行います。これで最初の構想図のVPCサブネットが4つある、という状況ができたかと思いますので、次は各インスタンスを作成します。


EC2とEBSの作成、およびSGの設定

VPCの設定はできましたので、VPC上にEC2を作成していきます。
EC2ダッシュボードからEC2をLaunchします。それぞれのEC2を別AZに作成します。スペックやらOSやらはご自由に選んでもらって構いませんが、2つのEC2を起動する時点で無料枠を超える可能性があることはご了承。EBSの作成も同時にできます。30GBまでは無料なので、さっと選びましょう。

問題はSGです。既存のSGを選択してもいいですが、無いならば作っておきましょう。基本方針に倣うならば、インバウンドSSH用に22番とHTTP用に80番のみを許可します。ただし、SSHは自分のIPのみを許可するようにしましょう。

インスタンスが立ち上がったら、SSHで接続して、Apacheの起動やらドキュメントの設置やらをやっておきます。できればテスト用ならば、コンテンツは違うものがいいですね。
作業を終えたら、直接インスタンスにブラウザからアクセスできるか確認しておきましょう。

だいぶ雑に説明しましたが、だいたい前の記事に書いたから・・・いいよね?



ELBの作成

最後にELBを作成します。EC2ダッシュボードのLoad Balancerを選択して、Create Load Balancerを選択。ポートはとりあえず80番で、ヘルスチェックはindexにします。未確認ですが、インデックスファイルがindex.phpだと、ヘルスチェック先をindex.phpにしないとヘルスチェック失敗になるかもしれないので、ちょっと気にしておいてください。
配下インスタンスは先ほど作成したマルチAZ上のインスタンスを選択しましょう。

ここでSGが選択できますが、これはインバウンド80番ポートのみ開放しておきましょう。これでELBは完成です。DNS Nameにあるホスト名でアクセスでき、さらに複数回アクセスすると、コンテンツが切り替わることを確認してください。
うまくいかないときは、インスタンスのないAZにトラフィックが振り分けられていたり、一方のAZのヘルスチェックに失敗して、StateがOutOfServiceになっている可能性があります。

EC2のSGを編集して直接アクセスできなくする

この時点で、EC2のIPを叩くと直接インスタンスにアクセスできることがわかると思います。これでは最初の要件が達成できていないですね。なので、EC2のSGを編集して、ELBを経由しないといけないようにします。
HTTPのSourceを0.0.0.0/0ではなく、ELBのSGを選択することで、ELBからの80番トラフィックしか許可しないようにできます。設定後、ELBからはアクセスできるけど、インスタンスには直接アクセスできないことを確認しましょう。

以上で完了です。文章でもずいぶんさらっとかけた印象ですね。


まとめ

  • 基本的な負荷分散には、ELBとEC2でOK。
  • SGとVPCでセキュリティもOK。
  • マルチAZで構築することで、災害対策もOK。


ところで課金されちゃいました

f:id:watass:20141124231513p:plain

せこせこと無料枠でやっていたわけですが、ちょっと油断したうちにSNSからメール飛んできてファッ!?ってなりました。どうやらElastic BeanstalkでRDSを弄っていたとき、マルチAZでRDSを作成したことが原因だったみたいですね。EC2と同じで時間課金だと思っていたので、複数インスタンスでも問題なくね?と思ったのが運の尽きでした。

定期的にログインしないと、こうなっちゃうわけなので、気をつけましょうね。そんな俺は1ドルのCloudWatchアラームとは別に10ドルのアラームを作りました。というか、意外と高いよね。無料枠終わったら死ぬんじゃないだろうか。


参考にした記事

【AWS】VPC環境構築ノウハウ社内資料 2014年4月版 | Developers.IO
# VPCの基本設計方針で参考になりました。いつものクラスメソッドさんの記事です。
Amazon VPCを使ったミニマム構成のサーバ環境を構築する | Developers.IO
# 今回のようなミニマムな構成でのVPCの運用方法など参考になりましたね。
VPC初心者がハマりやすいポイントをまとめてみた « サーバーワークス エンジニアブログ
# VPCハマりやすかったのでとっても助かりました。
AWSにおける可用性の考え方 | Developers.IO
# AWSの設計論みたいな話で、読んでおくといいと思います。
Elastic Load Balancingで複数のゾーンにわたって振り分けるときに気をつけること | Developers.IO
# マルチAZでのELBについてググって一番参考になりました。
AWS - ELB 経由で EC2 にアクセスする - Qiita
# ELBでアクセスできなかったときに参考にさせてもらいました。