構築でつまづかないためのECS+ALB構成ベストプラクティス(2016年版)
本記事ではECS-optimized AMIを使った構築を前提とし、つまずきやすいポイントにフォーカスしてECS+ALB構成でのベストプラクティスをご紹介します。
ソフト道場の「SIerが目利きする。今日から使えるAWSレシピ」 第5回
- 2016年12月27日公開
はじめに
ソフト道場AWSチームの須藤です。
先日の記事「 SpotFleet+ECS+ALB構成を試したら気持ち良かったからAWS Lambdaで痒いところをさらに気持ち良く 」ですが、この中で紹介しているAWS LambdaでALBのターゲットグループをメンテナンスするやり方は 現時点でのECS+ALB構成でのベストプラクティスではありません 。むしろ、 ベストプラクティスでないやり方で進めざるを得なくなってどう切り抜けたか という記事であると考えていただくと良いでしょう。
現時点でのECS+ALB構成でのベストプラクティスは?というと、まずは AWS Black Belt Online Seminar 2016 Amazon EC2 Container Service を読みましょう、これが最高のテキストです。しかしながら、インフラエンジニア(Ops)の目線でつまづきやすいポイントをまとめた情報源がまだ少なく、アーキテクチャを決めて実際に構築作業を始めてから「できるはずなのにうまくいかないぞ...」とハマってしまうこともあります。
ですので、本記事では ECS-optimized AMI を使った構築を前提とし、つまずきやすいポイントにフォーカスしてECS+ALB構成でのベストプラクティスをご紹介します。なお、 今後AWSの新機能や新サービスのリリースによってベストプラクティスが変わることもある ので、その点ご容赦ください。
ALBを使うサブネットにはある程度大きなIP帯を割り当てよう
ALBを使う場合、 ALBひとつにつき8つのIPが必要 とされます。これはELBでも同様ですが、ECS+ALBの場合、ひとつのECSクラスタ上に複数のServiceを起動し、結果として複数のALBを利用することがあります。3つのServiceに対してそれぞれALBを作るのであれば、空きIPが24必要になります。
この他に、サブネット作成時にAWS側で予約される5つのIPアドレスや、ECSクラスタを動かすためのIPアドレスも必要です。最低でも /26
、できれば /24
以上を目安に、拡張の可能性も見すえてある程度大きなサブネットを割り当てるよう計画しましょう。
サブネットとその中身全部構築し直しだ!ということのないように。
もちろん、セキュリティグループのインバウンド設定やインターネットゲートウェイのアタッチ、ルートテーブルへのインターネットゲートウェイの追加など、VPCの基本もお忘れなく。
ALBの数を抑え、Route53の設定も一度だけで良いように、ということであれば、ALBのパスベースルーティングも検討しましょう。 /admin
=> Admin Service, /api
=> API Service, /
=> Web Serviceのようにターゲットグループを切り替えることで、1つのALBで複数のServiceを扱うことも可能です。
ECSでServiceを作る前にALBと空のターゲットグループを作っておこう
ECSには、動的ポートマッピングやALBと組み合わせてのService Discovery、SpotFleetでのクラスタ起動やawslogsログドライバなど、便利な機能が盛りだくさんです。これらを有効に使うには、構築の順序に気を付ける必要があります。
- 空のECSクラスタを作成する
- SpotFleetを作成する
- このとき user-dataでECS_CLUSTERにECSクラスタ名の指定を忘れないこと
- 必ずインスタンスロールを指定し
AmazonEC2ContainerServiceforEC2Role
ポリシーをアタッチすること
- ALBと空のターゲットグループを作成する
- awslogsログドライバを利用する場合はCloudWatch Logsのロググループを作成する
- タスク定義を作成する
- 動的ポートマッピングを利用する場合はホストポートを指定しないこと
awslogs-group
に作成したロググループを指定すること
- Service作成時に、作成済みのALBとターゲットグループを指定する
ポイントは、 SpotFleetを作る前にECSクラスタを作成しておくこと と、 Service作成時にターゲットグループを指定すること です。それぞれ、ECSクラスタに所属するインスタンス情報のメンテナンスと、ALBとコンテナポートをつなぐターゲットグループのメンテナンスをECSに任せることができます。後者は、動的ポートマッピングを利用していても、Serviceが起動したインスタンスの割り当てられたホストポートをターゲットグループに登録してくれます。下図の赤い部分に相当します。
ALBやターゲットグループ、Serviceなどを作成する前にアプリケーションコンテナ単体の動作確認をしたいときは、Run Taskを使うと良いでしょう。現状、Service作成時しかターゲットグループを指定することができないので、先にServiceを作ってしまうとService Discoveryの恩恵を受けられません。
SpotFleetやServiceの作り直しだ!ということのないように。
awslogs でアプリケーションログを出力する場合には標準出力へのログ出力を設計しておこう
2016年5月からタスク定義でのログ出力設定にawslogsが指定できるようになっています。
ECSのタスク定義でawslogsを指定することで、アプリケーションのログをCloudWatch Logsで管理することができるようになります。アプリケーションのコンテナ内にログ集約のための作り込みをしたり、fluentdコンテナを立てたりしなくても良い、というのは非常に嬉しいポイントです。また、SpotFleetと組み合わせたときなど、インスタンスの永続性が保証されない場合にも、設定ひとつでログが常にCloudWatch Logsに集約される状態を保てる、というのは心強いです。
CloudWatch Logsからはロググループ単位でElasticsearch ServiceやLambdaへのサブスクリプションフィルタを作成できますから、ログの可視化もしやすくなります。
アプリケーション側がlog4jやlogbackなどのログ出力フレームワークをずっと使ってきているチームですと、いったんファイルに出力して日付単位などでログローテートし、そのあとログファイルをどこかに転送して集約、という発想になりがちです。しかし、awslogsログドライバを使う場合には標準出力が直接CloudWatch Logsに送られる形になるので、ログ出力の設計は標準出力で、というのを憶えておきましょう。
いざログを分析しようとしたら、そのログ標準出力に出してなかったから無い!ということのないように。
どのTaskのログか判断できるよう、 awslogs-stream-prefix
の設定もお忘れなく。
おわりに
ECS+ALB、いろんなことを意識する必要はありますが、本当に便利で癖になる楽しさです。SpotFleetと組み合わせれば安価に運用できますし、Route53でドメインを購入してACMで証明書を発行すればすぐにHTTPS化もできます。触っているうちにどんどん好きになりますよ、あなたもおひとつどうでしょう?
なお、本記事には、アマゾンウェブサービスジャパン株式会社様のソリューションアーキテクトよりアドバイスいただいた内容を含んでおります。
「AWSではお客様が新しいサービスをご利用いただけるように、ソリューションアーキテクトをはじめ、トレーニングやプロフェッショナルサービスなどAWSとの直接のやり取りを提供しています。アーキテクチャの相談などお待ちしています。」
とのことです。日本のAWSのユーザグループJAWS-UG各支部の勉強会
- JAWS-UG コンテナ支部
- JAWS-UG AI支部
- JAWS-UG HPC支部
- JAWS-UG 情シス支部
- JAWS-UG 初心者支部
- JAWS-UG ビッグデータ支部
- JAWS-UG IoT専門支部
- JAWS-UG CLI専門支部
- JAWS-UG アーキテクチャ専門支部
- aws-serverless
など、ソリューションアーキテクトの方々と話しやすい場もありますので、お悩みの方は足を運んでみてはいかがでしょうか?