はじめに

アプリケーション開発部の田村です。自社で運営するサービス開発を担当しています。
現在私が担当するサービスでは、アプリケーション実行環境にAWS ECS Fargateを利用しています。
今回はAWS ECS Fargateとは何か、使ってみて嬉しいことや注意点を説明します。
また自分がAWS ECSを構築した時の手順についてもサンプルアプリケーションを用いて解説していきます。

想定読者

  • Docker及びDocker Composeを使った経験がある
  • AWS ECS Fargateを使ってWebサイトを公開してみたい

モチベーション

AWS ECS FargateをAWSコンソールを使って一から自分の手で構築する記事を公開したいと考えました。
TerraformやAWS CloudformationなどのIaCを使った構築ではなく、実際に手を動かして構築することがAWS ECSの理解を深め、自分のスキルに出来ると感じています。

AWS ECSとは

AWS ECSについて

AWS ECSとは誤解を恐れずにいうと、「AWS上でDockerコンテナを動かす基盤」といえます。 AWS上でコンテナを動かし、Webサービスとして運用することが出来ます。 Webサービスの負荷が高くなったらコンテナの数を自動で増やす、コンテナが突然落ちた場合はコンテナを自動で起動する、など他にもコンテナを使ったWebサービスの運用において必要な機能が備わっています。

AWS ECSの種類(起動タイプについて)

AWS ECSは起動タイプによって3つに分類出来ます。内1つは少し特殊なので説明を省略し、下記2つの説明をします。

  • EC2
  • Fargate

    ■EC2

    当初、AWS ECSといえばこの起動タイプでした。このタイプではEC2上で稼働するDockerとECSエージェントがAWS ECSと連動します。
    イメージとしてはAWS ECSがEC2内のDockerを使い、タスク定義(後述)に従いコンテナを起動・管理するものになります。
    このEC2はECSコンテナインスタンスと呼ばれ、自分の管理対象であり、もちろんsshでログインすることも出来ます。

    ■Fargate

    EC2タイプから自分で管理すべきEC2がなくなったタイプです。タスク定義(後述)に従いコンテナが起動します。
    コンテナが稼働しているホストはユーザからは見えません。
    コンテナが稼働するホストにsshでログインすることも出来ません。

    なぜEC2ではなくFargateなのか

    私のチームではFargateでWebサービスの運用を行っていますがそのメリットについてお話します。
    その上で許容しなければいけないデメリットについてもお話します。

    メリット

    最も大きなメリットはやはり、「サーバの管理から解放される」ことでしょう。例えば下記のようなことです。

  • EC2の構築
  • サーバ内のユーザ管理
  • sshのキーやパスワードなどの秘匿情報の管理
  • ホストOSの更新
  • ホストOSのウィルスソフトやセキュリティ対策こういった作業が無くなるため、アプリケーションの開発に集中することが出来ます。
    また複数タスクを扱う際のタスク配置に関しても気にする必要がなくなります。
    Auto scalingの設定もEC2(ECSコンテナインスタンス)のことを意識する必要がなく、サービス・タスクのことだけを考えればよいので楽です。

    デメリット

    このようなメリットがある反面、やはりデメリットも存在します。
    実際にFargateを選択にあたって、このデメリットを許容する必要があります。

  • ホストOSにログイン出来ないので不具合調査が困難
    • これを解決する便利な機能がリリースされているものの手軽とはいいがたい
  • AWS ECSの設定において変更不可のものがある

クラスタ・サービス・タスクの関係とイメージ

ここでAWS ECSに出てくる登場人物を整理して、イメージ図にしてみました。

  • クラスタ
    • サービス・コンテナが稼働するホスト群
    • Fargateでは意識することが少ない、サービスの入れ物に近いイメージ
  • サービス
    • タスク定義をもとにタスク(コンテナ)の起動、起動数の調整などを行う
    • 必要なタスク数を自動的に増減させる(Auto Scaling)
    • ロードバランサにタスク(コンテナ)をターゲットとして登録・解除
  • タスク定義
    • Docker Composeにおけるdocker-compose.ymlのイメージ
  • タスク
    • タスク定義を元に起動するコンテナ群。Docker Composeでいうとdocker-compose.ymlで起動するコンテナ群のイメージ

構築手順

実施に関して

  • 実施にかかる時間:2時間程度

必要なモノ

  • AWSアカウント

作成するアプリケーション構成

今回、WordpressをAWS ECS Fargateを使って構築しWebサイトを公開するというテーマで進めていきます。
Wordpressにした理由は下記のような実践的なWebアプリケーションを題材にすることで、ECSの機能を実感出来ると考えたからです。

  • DBを利用する
  • データの永続化が必要(≒ファイルアップロードあり)
  • 管理者用サイトがある

下記の構成図をゴールとしてAWSコンソールで作業をしていきます。

AWS VPCの作成

まずネットワークを構築していきます。

  1. NATゲートウェイの設定で必要になるElastic IPを取得します。
    AWSサービスから「EC2」を選択し、「Elastic IP」を開きます。
  2. 「Elastic IPアドレスの割り当て」を押下、次の画面で「割り当て」を押下します。
  3. 次にVPCを作成します。
    AWSサービスから「VPC」を選択し、VPCウィザードを利用して「パブリックとプライベートサブネットを持つVPC」を選び、「選択」を押下します。

  4. 「VPC名」は任意で、CIDRの設定はお好みの設定に変更してください。
    AZはどちらも「ap-northeast-1a」を選択しておきます。

    「Elastic IP割り当てID」は先程取得したElastic IPを選択します。
    「VPCの作成」を押下します。

    ※本手順ではNATゲートウェイを利用しているので費用に気をつけてください。

  5. AWS RDS及びAWS ALBを作成するには、2つの異なるアベイラビリティーゾーン(以降、AZ)のサブネットが必要になります。
    パブリックサブネットとプライベートサブネットをそれぞれ1つずつ手動で追加していきます。
    VPCの「サブネット」を選択し「サブネットを作成」を選択します。 設定は下記のとおりです。
    VPCウィザードを利用して作成したサブネットのAZとは異なるものを選択してください。
  6. 次にVPCの「ルートテーブル」を選択します。 VPC「ecs-test」のルートテーブルのうち、デフォルトルートにigw(インターネットゲートウェイ)が設定されてるルートテーブルを表示します。
    「サブネットの関連付け」タブを選択します。
  7. 「サブネットの関連付けを編集」を押下し表示される画面で、「パブリックサブネット2」を選択して「関連付けを保存」を押下します。

AWS RDSの作成

次にWordpressで必要となるMySQLデータベースをAWS RDSを使って構築します。

  1. 先にDBサブネットグループを作成します。
    AWSサービスから「RDS」を選択し、「サブネットグループ」を選択、「DBサブネットグループを作成」を押下します。
  2. AZの「ap-northeast-1a」と「ap-northeast-1c」を選択し、それぞれのプライベートサブネットを選択、「作成」を押下します。
  3. 「データベース」を選択し、「データベースの作成」を押下します。
  4. データベースの設定ですが下記画像を参考にしてください。
    ポイントになる箇所は青枠で示しています。 パスワードは任意のものを設定してください(あと使うので控えておいてください)。
    セキュリティグループは新規作成にします。
    「データベースの作成」を押下します。

AWS ALBの作成

ECSのサービスを作成する際にロードバランサが必要になるのでAWS ALBを作成します。

  1. AWSサービスの「EC2」を選択し、「ロードバランサー」を選択、「ロードバランサーの作成」を押下します。
  2. 「Application Load Balancer」の「作成」押下します。
  3. 下記のようにロードバランサーの設定を入力します。AZでそれぞれのパブリックサブネットを指定します。 「次の手順: セキュリティ設定の構成」を押下、次の画面でも「次の手順: セキュリティ設定の構成」を押下します。
    ※今回、手順簡略ためのhttpsリスナーがないので警告が表示されます。
  4. セキュリティグループは「新しいセキュリティグループを作成する」を選択し、セキュリティグループ名を入力します。
  5. ターゲットグループの設定では、「ターゲットの種類」で「IP」を選択します。
    また一時的ですが、ヘルスチェックの成功コードは200,302にしておきます。
    Wordpressはセットアップが終わるまで、TOPのURLにアクセスすると302を返すためです。セットアップが終われば200だけに戻して構いません。
  6. ターゲットの登録は設定不要です。そのまま次へいきます。
  7. 確認画面になるので「作成」を押下します。

AWS EFSの作成

WordPressでは、アップロードされたファイルやプラグイン、テーマなどはファイルとして保存されます。
そのファイルを永続化する仕組みが必要になります。AWS ECSではAWS EFSをボリュームとしてマウントする機能があるのでそれを利用します。

  1. AWSサービスの「AWS EFS」を選択し、「ファイルシステムの作成」を押下します。 出現したポップアップで下記のように設定します。
    VPCは今回対象のVPCを選択し、「カスタマイズ」を押下します。
  2. 次の画面は変更せずに「次へ」、次の「ネットワークアクセス」では下記のように設定します。
    サブネットはプルダウンからぞれぞれプライベートサネットを選択します。
  3. あとはデフォルト値で進めていき作成を完了します。

    AWS ECS Fargate – クラスタの作成

    AWS ECSを設定していきます。

  4. AWSサービスの「Elastic Container Service」を選択し、「クラスターの作成」を押下します。
  5. クラスターテンプレートは「ネットワーキングのみ」を選択。
  6. クラスター名を入力して「作成」を押下します。

AWS ECS Fargate – タスク定義の作成

ECSサービスを作成するには事前にタスク定義が必要になります。
まずタスク定義を作成していきます。「どんなコンテナを使うのか」を定義していきます。

  1. 「タスク定義」を選択、「新しいタスク定義の作成」を押下します。
  2. 「Fargate」を選択して「次へ」。
  3. 下記のようにタスク定義の名前、サイズを設定します。
  4. 同画面では、さらに「コンテナ」と「ボリューム」を設定します。
    まずボリュームを設定します。ボリュームセクションの「ボリュームの追加」を押下します。
  5. 下記のように設定します。作成したファイルシステムを選択しています。「追加」を押下します。
  6. 次に「コンテナ」を設定します。「コンテナの追加」を押下します。
  7. まずイメージの設定をします。イメージはwordpress:latestを入力します。
    ポートマッピングは「80」を設定します。Fargate(というかawsvpcモード)ではホストとコンテナのポートは同じ値にしか出来ません。
  8. コンテナで利用する環境変数を設定します。
    Wordpressの場合、DB接続の情報とセキュリティー関連の情報を設定できます。

    • DB接続
名前
WORDPRESS_DB_HOST RDSのエンドポイント(RDSの設定画面で確認)
WORDPRESS_DB_NAME wordpress
WORDPRESS_DB_USER wordpress
WORDPRESS_DB_PASSWORD RDS作成時に指定したパスワード
  • セキュリティー関連
    https://api.wordpress.org/secret-key/1.1/salt/ で生成。
名前
WORDPRESS_AUTH_KEY 上記APIの生成値
WORDPRESS_SECURE_AUTH_KEY 上記APIの生成値
WORDPRESS_LOGGED_IN_KEY 上記APIの生成値
WORDPRESS_NONCE_KEY 上記APIの生成値
WORDPRESS_AUTH_SALT 上記APIの生成値
WORDPRESS_SECURE_AUTH_SALT 上記APIの生成値
WORDPRESS_LOGGED_IN_SALT 上記APIの生成値
WORDPRESS_NONCE_SALT 上記APIの生成値
 キーはCookieの値の検証や暗号化で利用されます。  
 設定しなくても起動するのですが、その場合コンテナ起動時に毎回自動生成して設定されてしまいます。  
 この値が変わるとログイン済みのユーザはログアウト状態になります。  
 これを防ぐため環境変数で固定する仕組みがWordpressのDockerイメージに提供されているのでそれを利用しています。
  1. 次にAWS EFSのマウントポイントを設定します。
    Wordpressでは/var/www/html/wp-content配下にユーザデータが保存されるので今回はこのフォルダをAWS EFSに永続化します。
    ※この配下以外のファイルを修正してもコンテナを再起動すると元に戻ります。
    「ソースボリューム」で先程「ボリュームの追加」で追加した「wordpress」、コンテナパスに/var/www/html/wp-contentを設定します。
  2. ここまで終われば画面下部の「追加」を押下し、最初のタスク定義作成画面の画面下部の「作成」を押下します。

AWS ECS Fargate – サービスの作成

サービスを作成して、実際にコンテナを起動していきます。

  1. AWS ECSのクラスタ「wordpress」を選択し、サービスの「作成」を押下します。
  2. 下記のように設定して次へ。
    ここで「タスク数」を「0」(=起動しない)にしているのは、サービス作成後にAWS RDSとAWS EFSのセキュリティグループで調整が必要になるので一旦、起動しないようにしておきます。
  3. ネットワーク構成の設定は下記のようにします。
    • サブネットはプライベートサブネットを2つ選択
    • 「パブリックIPの自動割り当て」はDISABLEDにしてロードバランサー経由のアクセスに
    • ロードバランシングでは、作成したAWS ALBの情報を設定すネットワーク構成の設定は下記のようにします。
  4. 次の「AutoScalling」は変更なしで次へ、次の画面で「サービス作成」を押下します。

    セキュリティグループの調整

    このコンテナは起動してもAWS RDSとAWS EFSへのアクセスに失敗します。
    理由はAWS RDS wordpressデータベース及びAWS EFS wordpressファイルシステムのセキュリティグループに、wordpressサービスからの通信を許可する設定がないためです。
    そこでこの通信を許可する設定にします。まず最初にwordpressサービスのセキュリティグループを確認し控えます。

    AWS EFS

  5. AWSサービスのEC2から以下のようなセキュリティグループを作成します。
    送信元をwordpressサービスのセキュリティグループにします。
  6. AWS EFSのwordpressファイルシステムのネットワークタブの「管理」を押下しマウントターゲットの設定画面を開きます。
  7. セキュリティグループを先程作成したセキュリティグループ(wordpress-efs)に置き換えます。

    AWS RDS

  8. AWS RDS wordpressデータベース作成時に指定した「wordpress-rds」というセキュリティグループを開き、下記のように設定します。
    送信元をwordpressサービスのセキュリティグループにします

    wordpressサービスのタスク数を1にする

    サービスのタスク数を1に変更して実際にコンテナを起動します。 ※現状の設定ではタスク数を1より大きくするとセッションを利用する機能(ログインなど)で問題が発生します。

  9. wordpressサービスを選択して「更新」を押下します。
  10. 「タスクの数」を「1」にして最後まで進めて更新します。

    動作確認

    しばらくするとタスクが起動します。
    ブラウザからアクセスして確認するために今回利用しているAWS ALBのDNSを確認します。

上記の場合、http://wordpress-852737063.ap-northeast-1.elb.amazonaws.com/にアクセスすると画面が表示されます。 画面に従ってセットアップを完了させてください。

まとめ

AWS ECSを実際に使ってサイトを公開してみました。
慣れないうちは設定画面も少し複雑なので混乱するかもしれません。
サイトは公開出来ましたが、運用するには例えば以下のような仕組みや手順も必要になってきます。
・管理者サイト(‘/wp-admin/’)へのアクセス制限 ・データベースのデータを閲覧・更新 ・AWS EFSのファイルシステムへのアクセス ・データのバックアップ・リストア ・画像ファイルなどサイズの大きいファイルはCDNで配信 他にもデプロイ周りや複数タスク起動時の設定など色々ありますが、これらに関しては今後の記事で紹介していきます。


本コンテンツはクリエイティブコモンズ(Creative Commons) 4.0 の「表示—継承」に準拠しています。