ECS入門 DockerからFargate公開まで解説

AWS

はじめに

クラウド上でアプリケーションを効率よく動かす仕組みとして「コンテナ」が一般的になり、AWSでも数多くのサービスが提供されています。その中でも Amazon ECS(Elastic Container Service) は、コンテナを簡単に実行・管理できるマネージドサービスとして多くの現場で使われています。

しかし、初めて学ぶ方にとっては「タスク定義」「サービス」「Fargate」「ALB」「CloudWatch」など聞き慣れない言葉が多く、全体像をつかみにくいのも事実です。

そこで本記事では、以下の流れで ECSを実際に触りながら学べる入門ハンズオン を紹介します。

  • ECSの全体像を理解(タスク定義とサービスの役割)
  • DockerイメージをECRにpushし、Fargateでデプロイ
  • パブリックIPやALBで公開し、実際にアクセス確認
  • CloudWatchを使ったログ・メトリクス監視とオートスケーリング

ただ動かすだけでなく、運用監視までを体験することで、ECSを本番環境で活用するイメージが持てるようになるのがゴールです。

ECSタスク定義を理解する

タスク定義とは

ECSでコンテナを動かす際の“設計図”にあたるのが タスク定義 です。
ここで指定した内容をもとに、ECSは実際のタスク(コンテナ群)を起動します。

設定できる主な項目

タスク定義で設定できる主な項目は次のとおりです。

区分項目説明 / ポイント
基本情報タスク定義ファミリータスク定義の名前(設計図のグループ名)。1つのファミリー名に対してバージョン番号が付与される(例: myapp:1myapp:2)。
インフラ要件起動タイプFargate:サーバーレス、運用不要、学習〜中規模向け。EC2:自分でEC2管理、柔軟性ありだが運用コスト増。
OS / アーキテクチャ一般的には Linux/x86_64。Gravitonなどを使う場合は arm64
ネットワークモードawsvpc(Fargate必須)。タスクごとに専用のENIを割り当て、パブリックIPやSGを直接設定可能。
タスクサイズCPU / メモリタスク全体に割り当てるリソース。例:1 vCPU / 3 GB。複数コンテナはこの枠を分け合う。
IAMロールタスクロール(任意)コンテナがAWS APIを直接利用する場合に必要。例:S3に保存する場合はS3権限を付与。
タスク実行ロール(必須)コンテナエージェントが利用するロール。ECRからイメージ取得、CloudWatchログ送信に使用。通常は ecsTaskExecutionRole
コンテナ定義名前コンテナ識別名。複数コンテナを使う場合に必須。
イメージURI実行するコンテナイメージを指定。例:ECR xxxx.dkr.ecr.ap-northeast-1.amazonaws.com/myapp:latest、DockerHub nginx:latest
ポートマッピング外部に公開するポートを指定。例:80/TCP。アプリのLISTENポートと一致させる必要あり。
環境変数アプリに渡す設定。例:ENV=production, DB_HOST=xxx。Secrets ManagerやS3環境ファイルも利用可能。
リソース制限(コンテナ単位)CPU、メモリのハード/ソフト制限を設定可能。枠を超えるとコンテナは終了。
読み取り専用ルートFS/ を読み取り専用にしてセキュリティ強化。
ログ設定awslogsCloudWatch Logs に標準出力を送信。主なキー:awslogs-group=/ecs/myappawslogs-region=ap-northeast-1awslogs-stream-prefix=ecs
高度なオプション再起動ポリシーコンテナが失敗したときに再起動するかどうか。
HealthCheckコンテナの正常性チェック(例:HTTP 200 応答)。
起動順序制御複数コンテナの依存関係を設定。
エフェメラルストレージ一時ストレージ容量。デフォルト20GB、最大200GBまで拡張可能。
ボリュームコンテナ間で共有するデータ領域を定義。
モニタリング統合OpenTelemetryAWS Distro for OpenTelemetry を使い、アプリのトレース・メトリクス収集が可能。
タグタグリソース整理用のメタデータ。例:env=dev, project=planit

つまりタスク定義とは、「どんなイメージを、どのリソースで、どんな設定で動かすか」をまとめた設計図 であり、ECSを使ううえで最も基本となる要素です。

サービスを理解する

サービスとは

ECSの サービス(Service) は、タスクを「安定して動かし続ける」ための仕組みです。
単発でタスクを実行するだけでは、停止するとそこで終わってしまいます。サービスを利用すると、以下のような運用が自動化されます。

  • 常時稼働:指定した数のタスクを常に維持。万一タスクが落ちても自動で再起動。
  • オートスケーリング:CPUやメモリ使用率に応じて、タスク数を自動で増減。
  • ロードバランサー連携:ALB(Application Load Balancer)と組み合わせ、複数のタスクにトラフィックを分散。

つまりサービスは、単なる「タスク実行」から一歩進んで、本番環境向けにアプリを継続稼働させる仕組み だと理解すると分かりやすいです。

設定できる主な項目

区分項目説明 / ポイント
サービスの詳細タスク定義ファミリー既存のタスク定義ファミリーを選択。新規作成は「タスク定義」から行う。
タスク定義リビジョン最新の100件から選択可能。空欄なら最新リビジョンを使用。
サービス名クラスター内で一意の名前。最大255文字。英数字、アンダースコア、ハイフンが利用可。
環境起動タイプに応じた環境を指定。例:Fargate。
クラスターデプロイ先のクラスターを指定。
コンピューティング設定コンピューティングオプションタスク配置方法を設定。基本は「起動タイプ」を指定。
キャパシティープロバイダー戦略複数のプロバイダー(例:FARGATE / FARGATE_SPOT)を分散利用可能。ウェイトやベース値を調整可能。
プラットフォームバージョンFargateのプラットフォームバージョン。通常は LATEST を推奨。
デプロイ設定スケジューリング戦略レプリカ:指定数のタスクを維持。デーモン:各インスタンスに1つずつタスクを配置。
必要なタスク数起動するタスクの数(例:1)。
AZ再調整アベイラビリティゾーン間でタスク数を自動で均等化。
ヘルスチェック猶予期間タスク起動直後にヘルスチェックを待機する秒数。
ネットワーキングService Connectサービス間通信を短縮名+標準ポートで自動検出可能にする機能。
サービス検出Route 53 のネームスペースを利用してサービスをDNS経由で検出可能に。
ロードバランシングELB (ALB/NLB) を利用し、正常なタスクにトラフィックを分散。
VPC Latticeマルチアカウントや複数VPCにまたがるアプリ通信を統合管理するサービス(追加コストあり)。
スケーリングサービスの自動スケーリングCloudWatch アラームをトリガーに、必要タスク数を自動調整。
ストレージボリュームタスク内のコンテナに追加ストレージを提供。
タグタグリソースを整理するためのメタデータ。例:env=dev, project=planit

ECSでアプリを公開する

まずは、ECSで動かすための サンプルアプリ を用意しましょう。
本格的なアプリでなくても大丈夫です。ここではシンプルなWebアプリを例にします。

サンプルアプリ開発

ファイル構成

以下のようなシンプルな構成にします。

ecs-sample/
├── app.js          # アプリ本体
├── package.json    # Node.js の依存関係定義
└── Dockerfile      # コンテナ化するための設定

Node.js で簡単なWebサーバーを作成

app.js

const http = require("http");
const port = 3000;

const server = http.createServer((req, res) => {
  res.writeHead(200, { "Content-Type": "text/plain" });
  res.end("Hello ECS!");
});

server.listen(port, () => {
  console.log(`Server running at http://localhost:${port}`);
});

package.json

依存関係を管理する設定ファイルを作成します。

{
  "name": "ecs-sample",
  "version": "1.0.0",
  "main": "app.js"
}

Dockerfile を作成

このアプリをコンテナ化するために Dockerfile を用意します。

FROM node:22-alpine

USER node

WORKDIR /usr/src/app
COPY --chown=node:node package*.json ./
ENV NODE_ENV=production
RUN npm ci --omit=dev || npm install --omit=dev || true

COPY --chown=node:node . .

EXPOSE 3000
CMD ["node", "app.js"]

ローカルでの動作確認

  1. Dockerイメージをビルド
  2. コンテナを起動
  3. ブラウザまたは curl で確認
    Hello ECS! と表示されれば成功です。
docker build -t ecs-sample .
docker run -d -p 3000:3000 ecs-sample
curl http://localhost:3000

ECRにPushする

ECRとは

ECR(Elastic Container Registry) は、AWSが提供するコンテナイメージの専用リポジトリサービスです。
GitHubでソースコードを管理するように、ECRではDockerイメージを安全に保存・管理できます。

Push手順

  • ECRリポジトリを作成
    • AWSマネジメントコンソール → 「ECR」 → 「リポジトリ作成」
    • 設定内容はの意味は下記です。
項目内容設定内容
リポジトリ名イメージを保存するリポジトリの名前myapp
イメージタグのミュータビリティタグを上書きできるかどうか
Mutable: 上書き可能。開発や検証向き。
Immutable: 上書き不可。リリース用に推奨。
今回はMutable
変更可能なタグ除外(フィルター)特定のタグだけImmutableにする設定今回は未設定
Screenshot
  • AWS CLIでログイン
aws ecr get-login-password --region ap-northeast-1 | docker login --username AWS --password-stdin <account_id>.dkr.ecr.ap-northeast-1.amazonaws.com
  • イメージをビルド
 docker build -t myapp .
 docker build --provenance=false -t myapp . # macの場合はこちら
  • ECR用にタグ付け
docker tag myapp:latest <account_id>.dkr.ecr.ap-northeast-1.amazonaws.com/myapp:latest
  • Push実行
docker push <account_id>.dkr.ecr.ap-northeast-1.amazonaws.com/myapp:latest

これらのコマンドはECR内のプッシュコマンドを表示を押下すると確認できます。
そこからコピペで実行するのが早いです。

VPC作成

ECSを配置するための仮想ネットワーク「VPC(Virtual Private Cloud)」を作成します。
VPCはクラウド上に構築する自分専用のネットワーク空間で、IPアドレスの範囲や通信ルールを自由に設計できます。

作成手順(マネジメントコンソール)

  1. AWSマネジメントコンソールにログイン
  2. 「VPC」サービスに移動
  3. 左メニューの「VPC」→「VPCを作成」をクリック
  4. 以下を入力して作成
    • 名前タグ:sample-vpc
  5. IPv4 CIDR ブロック:10.0.0.0/16
    • その他の設定はデフォルトのままでOK
  6. 「VPCを作成」ボタンをクリックして完了

設定値の意味

項目設定例説明
名前タグsample-vpcVPCの識別用の名前。わかりやすい名前をつけましょう。
IPv4 CIDR ブロック10.0.0.0/16VPC内で利用するプライベートIPアドレスの範囲を指定します。/16だと最大65,536個のIPが使えます。
IPv6 CIDR ブロック無効または割り当てなし今回は使用しません(必要に応じて後から追加可能です)。
テナンシーデフォルト「専有」ではなく「共有」ハードウェア上にインスタンスを配置する設定です(コスト面で一般的)。

これでどうなるか

このVPCは、今後作成するサブネットやインターネットゲートウェイ、ルートテーブルなどの土台になります。
この時点ではまだ通信はできませんが、次のステップでそれを可能にしていきます。

パブリックサブネット作成

VPC内にサブネット(Subnet) を作成します。
サブネットとは、VPC内でIPアドレスの範囲を区切るネットワークの一部であり、ECSを実際に配置する場所です。

今回は、インターネットに接続できる パブリックサブネット を作成します。

作成手順(マネジメントコンソール)

  1. 「VPC」サービスにアクセス
  2. 左メニューから「サブネット」→「サブネットを作成」をクリック
  3. 以下を入力:
    • 名前タグ:sample-vpc-1a
    • VPC:sample-vpc
    • アベイラビリティゾーン:任意(例:ap-northeast-1a
    • IPv4 CIDRブロック:10.0.1.0/24
  4. 下部オプションの「パブリック IPv4 アドレスの自動割り当て」に✔を入れる
  5. 「サブネットを作成」をクリック

設定値の意味

項目設定例説明
名前タグsample-vpc-1aわかりやすい名称を付けましょう。
VPCsamole-vpc作成済みのVPCを指定します。
アベイラビリティゾーン(AZ)ap-northeast-1a など任意のAZを選びます。同じリージョン内であればどれでも可。
IPv4 CIDR ブロック10.0.1.0/24このサブネットに割り当てるIPアドレス範囲。VPCのCIDRブロック内で重複しない範囲を指定します。
パブリック IPv4 アドレスの自動割り当て有効(✔ チェック)インスタンス起動時に自動的にパブリックIPを割り当てる設定。パブリックサブネットに必須です。

これでどうなるか

インターネットに出られる準備が整ったサブネットが完成します。

  • このサブネットに配置されるECSには、自動でパブリックIPアドレスが割り当てられます。
  • ただし、まだ ルートテーブルでインターネットへの経路(IGW)を設定していないため、通信はできません。

インターネットゲートウェイの作成とアタッチ

何をするか

作成したVPCからインターネットにアクセスできるようにするために、インターネットゲートウェイ(IGW: Internet Gateway) を作成し、VPCに接続(アタッチ)します。
これにより、ECSが外部と通信できるようになります(例:Webアクセスやパッケージのインストールなど)。

IGWの作成手順

  1. AWSマネジメントコンソールで「VPC」サービスにアクセス
  2. 左メニューから「インターネットゲートウェイ」を選択
  3. 「インターネットゲートウェイを作成」をクリック
  4. 名前タグにsample-igwと入力
  5. 「インターネットゲートウェイを作成」をクリック

アタッチ手順

  1. 作成したIGWを選択
  2. 「アクション」→「VPCにアタッチ」をクリック
  3. 接続先VPCとしてsample-vpc を選択
  4. 「アタッチ」をクリック

これでどうなるか

  • VPCにインターネットの出入口が接続されました。
  • ただしこの時点ではまだルートテーブルの設定がされていないため、実際の通信はできません。
  • 次のステップ(ルートテーブル作成)で、インターネット経路を明示的に指定します。

ルートテーブル設定

何をするか

ルートテーブル(Route Table) は、VPC内の通信ルート(経路)を定義するものです。
ここでは、パブリックサブネットからインターネットにアクセスできるようにするためのルートを設定します。

具体的には下記を行います。

  • 0.0.0.0/0(すべての外部アドレス)宛のトラフィックを インターネットゲートウェイ(IGW) に転送するルートを追加
  • そのルートテーブルをパブリックサブネットに関連付ける

作成手順(ルートテーブル)

  1. 「VPC」サービスにアクセス
  2. 左メニューから「ルートテーブル」→「ルートテーブルを作成」をクリック
  3. 以下を入力:
    • 名前タグ:sample-rt
    • VPC:sample-vpc
  4. 「ルートテーブルを作成」をクリックして完了

ルートの追加手順

  1. 作成したルートテーブルを選択
  2. 「ルート」タブ → 「ルートを編集」をクリック
  3. 「ルートの追加」を押し、以下を入力:
    • 送信先:0.0.0.0/0
    • ターゲット:作成済みの インターネットゲートウェイ(igw-xxxxxxx)
  4. 「変更を保存」をクリック

サブネットとの関連付け手順

  1. 同じルートテーブル画面の「サブネットの関連付け」タブを開く
  2. 「サブネットの関連付けを編集」をクリック
  3. sample-vpc-1aを選択して「保存」

役割と設定内容

項目設定例・内容説明
名前タグsample-rtわかりやすい名前を設定
VPCsample-vpc作成済みのVPCを指定
ルートの送信先0.0.0.0/0すべてのIPv4トラフィックを意味します
ターゲットigw-xxxxxxx(作成済みのIGW)インターネットゲートウェイを指定します
サブネットの関連付けsample-vpc-1a作成済みのサブネットと紐付けることで、このルートテーブルが適用されます

これでどうなるか

対象のサブネット(=パブリックサブネット)からインターネットへ通信できる経路が確立されます。

  • 0.0.0.0/0 のルートは、「すべての外部宛の通信」を意味し、
  • それを インターネットゲートウェイ(IGW)に向けることで、ECSから外部ネットワーク(インターネット)への送信が可能になります。

ただし、この時点ではまだECSへの外部からのアクセスはできません。

  • なぜなら、セキュリティグループ(ファイアウォール)の設定がまだ行われていないためです。
  • セキュリティグループで必要なポート(SSH:22、HTTP:80など)を開放しない限り、外部からの通信は遮断されたままとなります。

セキュリティグループ設定

何をするか

セキュリティグループ(Security Group) は、ECSの 仮想ファイアウォール です。
ここでは、外部からWebブラウザでECSにアクセスしたりするために必要な通信ポートを開放します。

作成手順

  1. 「EC2」サービスにアクセス
  2. 左メニューから「セキュリティグループ」→「セキュリティグループを作成」
  3. 以下を入力:
  4. 名前sample-sg
    • 説明:サンプル用セキュリティグループ
    • VPCsample-vpc(作成済みのVPCを選択)
  5. 「インバウンドルールを追加」をクリックし、以下を追加
タイププロトコルポートソース
HTTPTCP800.0.0.0/0
HTTPSTCP4430.0.0.0/0
カスタム TCPTCP30000.0.0.0/0

これでどうなるか

このセキュリティグループをECSに適用することで、次のような通信が許可されます

  • httpを利用し3000番ポートにアクセス

クラスターを作成する

まずは、ECSでアプリを動かすための「クラスター」を作成します。クラスターは、コンテナを実行する基盤となるリソースのまとまりです。

  • ECSコンソール → 左メニューから「クラスター」 → 「クラスターの作成」
  • 設定
    • クラスター名:わかりやすい名前を入力(例:my-ecs-cluster
      インフラストラクチャー:ここではシンプルに Fargate を選択
      (EC2モードを使う場合は、後でEC2インスタンスの準備が必要になります)
  • 作成 → 数十秒でクラスターができあがります。

タスク定義を作成する

タスク定義は「コンテナの設計図」です。

  • ECSコンソールに移動
    左メニューから「タスク定義」 → 「新しいタスク定義を作成」
  • タスク定義ファミリー名
    • 名前:myapp-task(自由でOK)
  • 起動タイプ
    • Fargate を選択(インフラ管理不要で初心者に最適)
  • タスクサイズ
    • CPU:1 vCPU
    • メモリ:2 GB 〜 3 GB
  • コンテナ定義を追加
    • 名前:myapp-container
    • イメージURI:<account_id>.dkr.ecr.ap-northeast-1.amazonaws.com/myapp:latest
    • ポートマッピング:80、3000
  • ログ出力
    • グループ名:/ecs/myapp-task
    • リージョン:ap-northeast-1

サービスを作成する

サービスは「タスクを安定して動かす仕組み」です。

  • ECSコンソール → クラスター
    • 事前に作った my-ecs-cluster を選択
    • 「サービス」タブ → 「作成」
  • 基本設定
    • タスク定義:先ほど作成したmyapp-task
    • タスク定義のリビジョン:1
    • 起動タイプ:Fargate
    • サービス名:myapp-service
    • タスク数:1(最初は1でOK)
  • ネットワーク設定
    • VPC:先ほど作成したVPC
    • サブネット:先ほど作成した、パブリックサブネットを選択
    • セキュリティグループ:先ほど作成したセキュリティグループを選択
    • パブリックIP割り当て:有効化(ONにするのを忘れない!)

実行〜動作確認

タスクの実行状態を確認する

  • ECS コンソールにアクセスし、対象のクラスター → サービス → タスクを開きます。
  • ステータスが実行中 になっていることを確認します。

アプリにアクセスできるか確認する

  • タスク詳細画面に表示される Public IPv4 address をコピーします。
  • ブラウザまたはターミナルから以下のようにアクセスします。
http://{パブリックIP}:3000

まとめ

ECSでは、タスク定義がコンテナ実行の設計図となり、サービスが安定稼働を担います。
ECRにイメージをPushしてFargateで実行すれば、パブリックIPから動作確認が可能です。
さらにCloudWatchでログやメトリクスを監視し、オートスケーリングを設定することで、本番運用に耐える環境を整えられます。

コメント

タイトルとURLをコピーしました