💨

コンテナアプリケーションをECSで起動する

2023/11/21に公開

概要

docker-compose等で作成したイメージをAWS上にデプロイし、インターネット公開したときのメモ。

対象のコンテナアプリは、個人的に勉強していた書籍「詳解 セキュリティコンテスト」にあるセキュリティに関するものを利用している。

前提

  • Windows
  • AWS CLIをインストール済み(aws configure等でアクセスキー設定済み)
  • Docker Desktopをインストール済み

ローカルでコンテナアプリを起動してみる

ローカルでdocker-compose.ymlからイメージ作成・コンテナ起動してみる。
アプリの起動確認はおまけであり、目的はイメージの作成にある。

  1. docker-composeコマンドでアプリケーション起動
    docker-compose.ymlが配置されている場所へ行き、以下コマンドをPowershellなどで実行する
docker-compose up -d

完了したら、Docker DesktopのContainersタブで以下のようにコンテナが起動していることが確認できるはず

Imagesタブでは以下のようにイメージも作成されていることが確認できるはず

  1. (念のため)アプリの起動確認
    今回の場合はローカルホストの5000番, 5001番, 5002番ポートで起動するアプリケーションなので、5000番ポートであればブラウザでhttp://127.0.0.1:5000にアクセスしてアプリケーションが起動しているか確認できる。

Amazon ECRにリポジトリを作成する

起動したいコンテナアプリケーション(のイメージ)をプッシュするための入れ物:リポジトリをAmazon ECRに作成する。

  1. ECRでリポジトリを作成する
    AWSコンソールから「ECR」と検索し、機能>リポジトリを選択

「リポジトリを作成」を押下し、リポジトリ名を入力して「リポジトリを作成」する

コンテナアプリケーション(のイメージ)をECRにプッシュする

  1. プッシュコマンドを表示する
    ECRで作成したリポジトリの「プッシュコマンドの表示」から以降に実施するコマンドを確認できる

  2. AWSの認証情報をdockerコマンドに渡す
    ECRにイメージをプッシュするためには認証情報(トークン)をAWSから取得し、dockerコマンドに渡す必要がある。「プッシュコマンドの表示」で表示した値をコピペして実施すればいい。
    ※以下コマンドはMacOS/Linux用とはなっているが、AWS CLIとDocker DesktopであればWindowsでも関係ない模様

aws ecr get-login-password --region [利用しているリージョン] | docker login --username AWS --password-stdin [自身のリポジトリのURI]
  1. イメージのタグ付けを行う
    以下のコマンドでタグを付ける。
    ここも「プッシュコマンドの表示」で表示した値をコピーして一部値を書き換えるだけでいい。
docker tag [プッシュしたいイメージ名]:[プッシュしたいイメージのタグ] [自身のリポジトリのURI]:[設定するタグ]

今回の場合、例として下記のようなコマンドでタグを付けた

docker tag xxe-app-web1:latest [自身のリポジトリのURI]/xxe-app:web1
  1. イメージをリポジトリのプッシュする
    以下のコマンドでイメージをリポジトリにプッシュする。
    ここも「プッシュコマンドの表示」で表示した値をコピーして一部値を書き換えるだけでいい。
docker push [自身のリポジトリのURI]:[3で設定したタグ]

今回の場合は、下記のようなコマンドでリポジトリにプッシュした
※XXXはリポジトリ毎に異なる値

docker push [自身のリポジトリのURI]/xxe-app:web1
  1. ECRでイメージがプッシュされていることを確認する

ECSでタスク定義する

タスク定義とは

(以下chatGPT)
Amazon Elastic Container Service (ECS) のタスク定義(Task Definition)は、Dockerコンテナで実行するタスクを定義する設定のテンプレートです。タスク定義は、ECSでコンテナを実行するための設定情報を提供し、ECSがコンテナの実行とスケーリングを効率的に管理できるようにします。

タスク定義には以下の要素が含まれます:

  • コンテナイメージ: タスク定義には、実行するコンテナイメージの情報が含まれます。これにはDockerイメージの名前やタグ、CPUおよびメモリの制約、コンテナ間のリンクなどが含まれます。
  • ネットワーク設定: タスク定義には、コンテナ間のネットワーク接続やポートのマッピングなど、ネットワーク設定が含まれます。
  • スケール設定: タスク定義には、ECSがタスクをどのようにスケーリングおよび配置するかに関する設定が含まれます。例えば、必要なタスクの数やどのインスタンスにタスクを配置するかを指定できます。
  • ボリューム: タスク定義には、コンテナから使用可能なボリュームの設定も含まれます。これはデータの永続性やコンテナ間でのデータの共有に使用できます。
  • タスクロール: タスク定義には、コンテナが使用するAWS Identity and Access Management (IAM) ロールを指定することができます。これにより、コンテナが他のAWSサービスと連携できるようになります。
    +コンテナ間の依存関係: タスク定義には、コンテナ間の依存関係を定義できます。これにより、コンテナが特定の順序で起動されたり停止されたりすることができます。
  1. ECS>タスク定義で「新しいタスク定義の作成」する

  2. 設定を入力する
    今回のように試しで起動してみる場合、「タスク定義ファミリー」に適当な名前と「コンテナ」部分だけ設定して他は特にいじらなくていい。
    「コンテナ」には先ほどECRにプッシュしたイメージを設定する。この時、コンテナポートは5000番にする(ここの数値は何番ポートで立ち上がるアプリかによる)

クラスターを作成する

  1. ECSから「クラスターの作成」

  2. クラスター名設定して「作成」
    名前は適当に。

クラスター内のサービスorタスクとしてデプロイする

日本語がややこしいが・・・
タスク定義で定義したタスクをECSクラスタ内のサービスorタスクで起動する」
というイメージ

今回はタスクとして起動する(確認時点ではサービスでもほぼ同じ設定項目であった)

サービスとタスクについて

(以下chatGPT)
〇ECSサービス (ECS Service)

役割: ECSサービスは、アプリケーションのコンテナをデプロイし、実行するためのリソース管理を担当します。アプリケーションの実行状態を維持し、コンテナのスケーリングや再デプロイを管理します。

特徴:サービスは複数のタスクインスタンスを管理し、クラスタ内の複数のEC2インスタンスまたはFargateタスクに分散して配置できます。
サービスはコンテナのスケーリングをサポートし、タスクの数を自動的に増減させることができます。
サービスはバックエンドのロードバランサーに接続することで、トラフィックを均等に分散できます。
使用ケース: ウェブアプリケーション、マイクロサービス、長時間実行されるジョブなど、アプリケーション全体のコンテナ管理が必要な場合に使用されます。

〇ECSタスク (ECS Task)

役割: ECSタスクは、コンテナの実行単位で、タスク定義に基づいて1つまたは複数のコンテナを実行します。個々のコンテナインスタンスはタスクとして実行され、それぞれは独立して動作します。

特徴:タスクは単一のコンテナまたは複数のコンテナからなることができますが、それらは同じホスト上で実行されます。
タスクはECSクラスタ内の特定のEC2インスタンスまたはFargateタスクに配置されます。
タスクは通常、特定のバッチジョブ、ジョブキュー、または一時的なプロセスの実行に使用されます。
使用ケース: バッチ処理、データ処理ジョブ、一時的なタスクなど、個別のコンテナ実行を必要とする場合に使用されます。

簡単に言えば、ECSサービスはアプリケーション全体のコンテナ管理を担当し、スケーリングやロードバランシングを行います。一方、ECSタスクは個々のコンテナの実行を管理し、個別のタスクとして実行されることが一般的です。両者は共にECSクラスタ内で動作しますが、異なる役割を果たします。

  1. ECSのクラスター>タスクで「新しいタスクの実行」する
    ※画像は立ち上げた後のもの

  2. 設定の入力
    今回はパブリックIPアドレスを割り当ててインターネットからアクセスできるように起動してしまう(プライベートサブネットで起動する場合はロードバランサー割り当てるとかする模様)。

  1. ブラウザからアクセスしてみる
    デプロイが完了したらタスクの詳細からパブリックIPを確認し、アクセスしてみる

Discussion