AWS ECS(Elastic Container System)でコンテナを起動する方法

こんにちは。8月からデジタル・トランスフォーメーション推進開発部に配属されたT. Tです。

 

AWSサービスの理解を深めるために、使ったことのないサービスについて自由研究として調査・構築を行いました。そこでECSをテーマに挙げて調査したものを記事にしていきたいと思います。

 

ECS(Elastic Container System)とは?

コンテナ環境構築のオーケストレーションツールです。ホストPCの中にコンテナと呼ばれる仮想環境の構築を複数台にスケーラブルに行うことができます。

主にコンテナ環境のスケジューリング・スケーリング・ヘルスチェック・ロードバランシングを取りまとめる役割を持っています。

ECSの役割

コンテナ環境のメリット

コンテナ環境は個々のサービスを独立することができるためマイクロサービス化につながります。

マイクロサービス化を行うことによって以下の3つのメリットがあります。

 

  • 一つのシステムに異なる技術を採用できる
    • 個々の機能に合わせた言語を採用し、開発を行うことができる

 

  • 柔軟性や拡張性が高い
    • 新たな機能を追加したり、一部の機能だけの削除・改変をしたりしやすい

 

  • アジャイル開発に向いている
    • 機能ごとの改変・コードの際利用・一部機能のみが停止可能になる

今回行ったコンテナシステムの構成

前提条件として今回はECSの調査を目的として行ったためサーバレスのFargateタイプのコンテナではなく、EC2インスタンスタイプを用いたECSを利用しました。

  • VPC × 1
  • AZ × 2
  • パブリックサブネット × 2
  • プライベートサブネット × 2
  • 2つのプライベートサブネットにスケーリングするEC2コンテナ
  • 2つのプライベートサブネットに負荷分散するALB
  • 処理内容を保存するS3バケット
  • ゲートウェイエンドポイント × 2
  • 各機能へのインターフェースエンドポイント × 1ずつ

ECSを使った構成図

今回はマイクロサービス化を意識してコンテナを2つずつ作成。それぞれNginxとApacheのWebサーバ機能を持たせる想定として作成しました。S3バケットはすべてデフォルト値で作成したものの、今回の研究ではコンテナ内のアプリケーション作成は行わなかったため実際には使用しませんでした。

構築手順~環境編~

Dockerイメージの準備

Dockerイメージの作成

今回はローカルのWSLを用いたUbuntu上でdockerをインストールしコンテナを作成しました。基となるイメージ(Nginx, httpd)をDocker公式リポジトリからプルし、起動したコンテナに接続してコンテナ環境を編集しました。

その後コンテナをイメージ化します。

dockerイメージの作成
ECR(Elastic Container Registory)にプッシュ

Dockerイメージが作成できたらECR(Elastic Container Registry)のリポジトリを作成します。ECRはECSがコンテナを作成する際にDockerイメージを取得するための保存場所になります。

ECRリポジトリを作成するとプッシュコマンドを表示できるようになるため、コマンドに従ってUbuntu上からプッシュします。また、今回はdockerイメージを作成済みになる為、2番はスキップします。

ECRプッシュコマンド

予めAWS CLIをインストールし、aws configureコマンドでアクセスキーとシークレットキーを設定しておいてください

ネットワークの構築

事前準備

始めに事前準備として

  • VPC
  • AZ × 2
  • 各AZ一つずつパブリックサブネットとプライベートサブネット
  • インターネットゲートウェイ

以上の4つは作成してあるものとします。

ゲートウェイエンドポイントの作成

プライベートサブネットのコンテナ内アプリケーションからS3にデータを保存する際に使用するエンドポイントを作成します。

エンドポイント作成画面からAWSのサービス→S3を検索し「Gateway」タイプのものを選択します。

ゲートウェイエンドポイントの作成画面
インターフェースエンドポイントの作成

インターフェースエンドポイントはECSがコンテナを作成し管理するためのものとコンテナがECRからdockerイメージを取得するための以下の4つを作成します。

  1. com.amazonaws.ap-northeast-1.ecs-agent
    ECSがプライベートサブネットコンテナに接続する

  2. com.amazonaws.ap-northeast-1.ecs-telemetry
    プライベートサブネットのコンテナからCloudWatchにメトリクスを送信する

  3. com.amazonaws.ap-northeast-1.ecs

    ECS APIを使用する

  4. com.amazonaws.ap-northeast-1.ecr.api

    プライベートサブネットのコンテナがECRからイメージを取得する

これら4つのインターフェースエンドポイントをそれぞれ2つのプライベートサブネットに紐づけて作成します。

 

ゲートウェイエンドポイントは冗長化したのに対し、インターフェースエンドポイントは1つずつ作成し、2つのサブネットに紐づけました。その理由として、インターフェースエンドポイント作成してから時間の経過で利用料金が発生してしまうという点があります。今回は調査としての構築であり、多種のインターフェースエンドポイントを必要とするため1つずつの作成としました。

 

ALB(Application Load Balancer)の作成

最後のネットワーク構築として複数コンテナに負荷分散するALBを作成します。インスタンスをターゲットタイプに持つHTTPのターゲットグループにターゲットとするインスタンスを設定しないで作成します。

 

作成したターゲットをリスナーとしたALBを作成し、HTTP通信をすべて受け入れるインバウンドルールを設定したセキュリティグループに設定します。

構築手順~ECS編~

クラスターの作成

クラスターとはコンテナを実行する際の環境を定義したものです。

 

  1. 今回はEC2インスタンスタイプで作成するためインフラストラクチャをEC2インスタンスを選択
  2. Autoscalingグループは新規作成
  3. OS, インスタンスタイプを選択
  4. 必要なインスタンスの最大数と最小数を選択
  5. VPC, 2つのプライベートサブネットを選択

作成ボタンを押すと、CloudFormationによって定義したAutoScalingグループ、インスタンスが作成されます。

 

タスク定義の作成

タスク定義とは、作成するコンテナについての設定を定義したものです。

タスク定義の設定

  1. インフラストラクチャはクラスターと同じものを選択

  2. ネットワークモードは「bridge」を選択
    →静的にホストポートとコンテナポートの同期設定可能

  3. タスクサイズ(vCPU, メモリ)を選択
    クラスターで選択したインスタンスタイプのスペックを超えないようにする

  4. タスクロールを選択(コンテナが必要なIAMロール)
    ECRへの権限とS3への権限を付与する

  5. タスク実行ロールは新規自動作成(画像は自動作成されたものを選択済み)
    →タスク実行ロールはタスクを実行するためにECR側が必要なロール
作成するコンテナの設定

今回は1つ目のコンテナをNginx, 2つ目のコンテナをApacheと仮定しました。Nginx側がフロントエンドとしてWebページを表示しデータを取得、Apache側がバックエンドで取得したデータの処理をすると仮定してコンテナを作成しました。

コンテナ作成画面
  1. コンテナ名・保存したECRリポジトリのURLを選択

  2. ホストポート, コンテナポート, プロトコル, ポート名, アプリケーションプロトコルを設定する
    →Nginxで80ポートを使用したいためコンテナ側の80ポートとホスト側の80ポートを設定し各プロトコルを選択
  3. リソース割り当て制限でvCPU, メモリの制限を設定する
    ※1 タスクサイズのスペックを全コンテナの合計で超えないようにする
    ※2 GPUの無いインスタンスタイプの場合はGPU値を入力しない

2つ目のコンテナは

  • コンテナ名:Apache
  • コンテナイメージ:ApacheのECRリポジトリURL
  • 必須コンテナ:はい
  • ポートマッピング:設定無し
  • リソース割り当て制限:1つ目と同様

に設定することで2つのコンテナを常に稼働するタスクとしました。

オプション:ストレージの設定

ホストのストレージと各コンテナのストレージを共有するパスを作っておくことでコンテナ間の通信でデータを送る必要性を無くす方法を取りました。

コンテナ間のストレージ設定画面
  1. ボリュームタイプで「バインドマウント」を設定し、ホスト側が共有するパスを入力
    →ホストとコンテナが共有するストレージを設定可能

  2. コンテナマウントポイントを設定
    →コンテナ側の共有ストレージのパスを設定

サービスの作成

今回はWebサーバをコンテナ上で実装することを想定するためサービスを作成します。

サービスとは停止して再起動できる長時間のコンピューティング作業を処理するタスクのグループのことです。

サービスの作成画面



  1. 作成したクラスターを選択

  2. コンピューティングオプションを「キャパシティープロバイダー戦略」に設定し、デフォルトのクラスターを使用
    →AutoScaling Groupを使用したコンテナを起動する設定

  3. サービスを作成するため起動タイプを「サービス」に設定

  4. 作成したタスク定義を選択

  5. サービスタイプは「レプリカ」を選択

  6. 必要なタスク数を選択

  7. ALB(Application Load Balancer)の作成で作成したALBとターゲットグループ, リスナールールを選択

作成ボタン押下後はCloudFormationが作動し、構築完了には数分かかります。

 

完成後

以上でECSの設定が完了になります。クラスター詳細画面でサービス(タスク)が○○件実行中となれば完成となります。保留中で動かない場合は以下の2点を確認してみてください。

  • エンドポイント等のネットワークの設定
  • クラスターとタスク定義のコンピューティングリソースのサイズ

 

最後に

ECSを用いたマイクロサービス構成として今回実際に構築をしましたが、コンテナのオーケストレーションツールとして自動でコンテナ生成を行ってくれるとはいえ、ECSの設定にかなり工程や知識が必要であると感じました。マイクロサービス化だけを目的とする場合はインスタンスを複数使用し、連携させることで実装することも可能であり構成も単純で分かり易くなります。

そのため、開発する際にコンテナを使用したいといった特別な理由がある場合(人数が多く開発環境を統一する場合等)にECSを使用するのが一番適していると感じました。

 

ECSのEC2インスタンスタイプはFargateタイプに比べてコンピューティングコストが割安になるというメリットをよく目にします。しかし、プライベート環境で構築する場合の多数のインターフェースエンドポイントによる利用コストを考えると、VPCエンドポイントを必要としないFargateとほとんど大差ないことが分かりました。

よって、環境を自己管理したい場合や、単純な処理をタスクとして実行したい場合、Fargateでは実装できない環境である場合はEC2インスタンスタイプを使用し、そうでない場合はFargateタイプを使用するという選択方法を取ることをお勧めしたいです。