Open10

[AWS] 公式のECS on EC2によるデプロイ手順トレースメモ

noknok

はじめに

GPUを利用するアプリケーションをECSでデプロイしたく[1]、先ずはミニマムな構成で「ECS on EC2」によるデプロイ手順を確認したい。

トレース元となる公式ドキュメント

https://docs.aws.amazon.com/ja_jp/AmazonECS/latest/developerguide/getting-started-ecs-ec2-v2.html

参考サイト

https://techblog.ap-com.co.jp/entry/2024/07/23/113344#サービスの作成ができない

脚注
  1. Fargateは現時点でGPUをサポートしていないので使えない ↩︎

noknok

予備知識

用語 説明
クラスター タスクを実行するためのコンテナの集合体を管理する単位
タスクを実行するインフラのグループとして機能する
サービス 指定した数のタスクを常に実行し続けるために管理する機能
ロードバランサーを介してトラフィックの分散や自動スケーリング、タスクの再起動などを行い、スケーラブルかつ冗長なアプリケーションを提供することができる
タスク 実行するコンテナの単位で、タスク定義によって構成される
タスク定義には、コンテナイメージや必要なリソース、ネットワーク設定などが含まれる
キャパシティプロパイダー ECSのタスクを実行するインフラを決定するもの
どのインスタンスでタスクを動かすかやインスタンスの自動スケーリングを効率的に管理する
noknok

クラスターを作成する

  • マネジメントコンソールから、[Amazon Elastic Container Service]表示
  • メニューから [クラスター]選択 > [クラスターの作成]選択
  • クラスターの作成メニューより、以下を入力して作成する

    • クラスター設定
      • クラスター名: aws-ecs-on-ec2-test-cluster(任意の名前)
      • デフォルトの名前空間: 上記と同じ(自動入力された値とした)

    • インフラストクチャ
      • キャパシティプロパイダー: [Amazon EC2 インスタンス] のみ選択とした
      • Auto Scaling グループ (ASG): [新しいASGの作成] とした
      • プロビジョニングモデル: [オンデマンド] を選択とした
      • コンテナインスタンス: [Windows Server 2019 Core] を選択とした[1]
      • EC2インスタンスタイプ:[t2.xlarge] を選択とした[2]
      • EC2 インスタンスロール: [ecsInstanceRole] を選択とした[3]
      • 必要な容量: [最小1、最大2] で設定した[4]
      • SSHキーペア: [なし] とした(デフォルトで入った値のままとした)
      • ルートEBSボリュームサイズ: [50] で設定した(デフォルトで入った値のままとした)

    • ネットワーク設定
      • VPC: 事前に作成していたネットワーク環境を選択した
      • サブネット: 事前に作成していたネットワーク環境を選択した(パブリックサブネットとした)
      • セキュリティグループ名: 事前に作成していたネットワーク環境を選択した(IGWからの全てのアクセスを許可した)
      • パブリックIPの自動割り当て: [オンにする] を選択とした

    • モニタリング、暗号化、タグ
      • デフォルト設定のままとし、何も変更なしとした

クラスター作成画面イメージ

クラスター作成画面イメージ

脚注
  1. タスク定義の手順で「WINDOWS_SERVER_2019_CORE」の指定があったため ↩︎

  2. タスク定義の手順で「"memory": "4096", "cpu": "2048"」の指定があったため、余裕を持ったインスタンスタイプを選択した ↩︎

  3. コンテナインスタンスロールを作成するの手順で作成したロール ↩︎

  4. 最小1以上にしないとタスク作成されない ↩︎

noknok

タスク定義を登録する

  • マネジメントコンソールから、[Amazon Elastic Container Service]表示
  • メニューから [タスク定義]選択 > [新しいタスク定義の作成] > [JSONを使用した新しいタスク定義の作成] 選択
  • 新しいタスク定義の作成画面より、以下を入力して作成する

タスク定義作成画面イメージ

タスク定義作成画面イメージ

脚注
  1. Amazon ECS タスク実行IAM ロールを参考に作成したIAMロールのARNを設定した ↩︎

noknok

サービスを作成する

  • マネジメントコンソールから、[Amazon Elastic Container Service]表示
  • メニューから [クラスター]選択 > これまでに作成したクラスターを選択 > [サービス] タブから、[作成] 選択
  • 作成画面より、以下を入力して作成する

    • 環境
      • コンピューティングオプション: [起動タイプ] を選択
      • 起動タイプ: [EC2] を選択

    • デプロイ設定
      • アプリケーションタイプ: [サービス] を選択
      • タスク定義/タスク定義: チェックオフ(デフォルトのままとした)
      • タスク定義/ファミリー: これまでに作成した、タスク定義を選択
      • タスク定義/リビジョン: 自動入力されるリビジョンのままとした
      • サービス名: aws-ecs-on-ec2-test-service(任意の名前)
      • サービスタイプ: [レプリカ] を選択とした(デフォルトのままとした)
      • 必要なタスク: 1 (デフォルトのままとした)
      • アベイラビリティゾーンの再調整: チェックオン(デフォルトのままとした)
      • デプロイ不具合の検出: 「Amazon ECS デプロイサーキットブレーカーを使用する」「失敗時のロールバック」の項目のチェックオフ(参考サイトを参照して対応した)

サービス作成画面イメージ

サービス作成画面イメージ

noknok

サービスを表示する

  • マネジメントコンソールから、[Amazon Elastic Container Service]表示
  • メニューから [クラスター]選択 > これまでに作成したクラスターを選択
  • [サービス]タブ選択 > 作成したサービスを選択 > [タスク]タブ選択 > 作成されたタスクを選択
  • タスクの [設定] セクションにある、[パプリックIP]をコピーする
  • ブラウザのURL欄に、「http://パブリックIP:443」の形式で貼り付けてサービス表示を行う[1]
"portMappings": [
    {
        "hostPort": 443, <=ホスト側のポート
        "containerPort": 80, <=コンテナ側のポート
        "protocol": "tcp"
    }

サービス表示結果イメージ

サービス表示結果イメージ

脚注
  1. タスク定義時に、以下設定で作成していたので「:443」を付与する ↩︎

noknok

クリーンアップ(料金発生しないようにリソース削除する)

  • マネジメントコンソールから、[Amazon Elastic Container Service]表示
  • メニューから [クラスター]選択 > これまでに作成したクラスターを選択
  • [サービス]タブ選択 > 作成したサービスを選択し、[サービスを削除] を選択("強制削除"で実施した

サービス削除イメージ

サービス削除イメージ1
サービス削除イメージ2

クラスター削除イメージ

クラスター削除イメージ1
クラスター削除イメージ2

noknok

タスク定義:タスクサイズ(CPU、メモリ)確認メモ

タスクサイズとして以下項目の設定が必要だが、具体的にどんな値を設定すれば良いのか?
=>結論: 実際に試行錯誤したところ、インスタンスタイプのCPUとメモリよりも少なめに設定する必要ありそう(全く同じ容量を指定するとデプロイ時にエラーとなった)

  • CPU(vCPU)
  • メモリ(GB)

設定例

インスタンスタイプが「g4dn.xlarge」の場合、「4 vCPU、 16GB」となる
この時、タスク定義では「3.5 vCPU、 15GB」などと余裕持たせる

参考

https://docs.aws.amazon.com/ja_jp/AmazonECS/latest/developerguide/create-task-definition.html
https://docs.aws.amazon.com/ja_jp/AmazonECS/latest/developerguide/task_definition_parameters.html

noknok

タスク定義:インスタンスロール、タスクロールと、タスク実行ロールの確認メモ

それぞれの違いは何か?結局、どのロールに権限を集中させれば良いのか?
=>結論: タスクロールにアプリケーションとして必要な権限を集中させれば良い認識

項目 インスタンスロール タスクロール タスク実行ロール
付与対象 ECSクラスターのEC2インスタンス ECSタスク ECSコンテナとFargateエージェント
役割 EC2インスタンスからAWSリソースにアクセスする権限を提供 ECSタスク内で実行されるアプリケーションがAWSリソースにアクセスする権限を提供 ECSタスクまたはFargateタスクを実行するために必要なアクセス権限を提供
必要なポリシーの例 S3、DynamoDB、CloudWatchへのアクセス権限 S3、SQS、SNS、DynamoDBなどへのアクセス権限 AmazonECSTaskExecutionRolePolicy
主な使用ケース EC2上で動作するECSコンテナがAWSリソースにアクセスする場合 ECSタスク内のアプリケーションが特定のAWSサービスにアクセスする場合 ECSエージェントがECRからのイメージ取得やCloudWatchにログ出力を行う場合

設定すべきポリシーの例

  • インスタンスロール: AmazonEC2RoleforSSMAmazonS3ReadOnlyAccessなど
  • タスクロール: AmazonS3FullAccessAmazonDynamoDBFullAccessAmazonSQSFullAccessなど
  • タスク実行ロール: AmazonECSTaskExecutionRolePolicy

参考サイト

https://docs.aws.amazon.com/ja_jp/AmazonECS/latest/developerguide/instance_IAM_role.html
https://docs.aws.amazon.com/ja_jp/AmazonECS/latest/developerguide/task-iam-roles.html
https://docs.aws.amazon.com/ja_jp/AmazonECS/latest/developerguide/task_execution_IAM_role.html
https://blog.serverworks.co.jp/ecs/difference-between-taskrole-and-taskexecutionrole