Amazon ECSonEC2 ENIトランキング機能でENIの上限数を拡張

# 1．はじめに
<!-- 発端や概要を記載 -->

こんにちは。gura3です。本ブログが初投稿です。
至らぬ点等あるかと思いますが、お手柔らかにお願いします。
（以降の文章は常体で書きます。）

ー経緯ー
　ECS専用EC2インスタンス内に3台のコンテナを起動する構成を検証していたら、
　2台までしか起動出来ず、エラーが発生した。
　EC2インスタンスにアタッチできるENIの数には制限があることがわかった。

**更に、調べるとENIの上限を解放できるAmazonECSのENIトランキング機能というものがあるらしい。
設定手順を試してみた。** 

# 2．概要

## 2.1. 概要図
<img width="600" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3558533/60c6a9c6-faa8-76ca-1e3d-429fd61fc5f3.png">

## 2.2. ENIトランキングに対応しているインスタンス

* 各インスタンスタイプのENI制限については、AWS公式の[Elastic Network Interface](https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/using-eni.html "Elastic Network Interface")を参照

* 以下のURLから、ENIトランキング機能に対応しているEC2インスタンスタイプを確認する

    AWS公式ドキュメント： [Elastic Network Interface のトランキング](https://docs.aws.amazon.com/ja_jp/AmazonECS/latest/developerguide/container-instance-eni.html#eni-trunking-considerations "Elastic Network Interface のトランキング")

    :::note warn
    注意点
    ENIトランキング機能に対応していないEC2インスタンスタイプは、ENIの数を拡張出来ない。
    				例）汎用インスタンスのt2ファミリー、t3ファミリーは拡張出来ない。
    				・t2.micro, t2.small, t2.medium, t2.large

今回は、「m5.large」を使用して拡張を行うことにした。
**前提として、「m5.large」は通常、2つまでしかコンテナを作成できない**
<img width="600" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3558533/c3b65b22-262d-b8a9-b6d6-c42a162d86dd.png">


# 3．検証環境の準備
## 3.1. ECSクラスター作成
* クラスター名：test-cluster1

## 3.2. タスク定義作成

|項目 | 設定内容 |
|:-----------|:------------|
|ファミリー名| test-httpd-task|
|コンテナ名| httpd |
|イメージ| ECRにpush済のイメージ|
|アプリケーション環境| Amazon EC2 インスタンス|
|タスクサイズ|CPU:.25v メモリ: .5GB|
|タスクロール| -|
|タスク実行ロール| EcsTaskExcutionRole|
|ネットワークモード|aws vpc|

:::note warn
EC2インスタンスのタイプを「t2.micro」もしくは「t3.micro」で作成予定のとき、
デフォルトのタスクサイズ（CPU：1v、メモリ:3GB）では、メモリ不足でタスクが動かないので注意する
:::

## 3.3．ALBを作成
* ALB用セキュリティグループ 

    |項目 | 設定内容 |
    |:-----------|:------------|
    |セキュリティグループ名| alb-sg|
    |タイプ| HTTP|
    |プロトコル| TCP|
    |ポート|80|
    |ソース|マイIPまたは0.0.0.0/0|

* ALB
    |項目 | 設定内容 |
    |:-----------|:------------|
    |ALB名| test-alb|
    |スキーム| インターネット向け|
    |プロトコルVPC、サブネット| 任意|
    |セキュリティグループ|alb-sg|

* リスナー設定

    |項目 | 設定内容 |
    |:-----------|:------------|
    |プロトコル| HTTP|
    |ポート| 80|
    |転送先| test-tg|

## 3.4．ECSサービスの作成
1. 環境およびデプロイ設定
 
    |項目 | 設定内容 |
    |:-----------|:------------|
    |コンピューティング設定| 起動タイプ|
    |起動タイプ| ec2|
    |アプリケーションタイプ| ami-01703abf1e5cede54|
    |ファミリー|test-httpd-task|
    |サービス名|httpd-service|
    |サービスタイプ|レプリカ|
    |必要なタスク|1|

1. ネットワーキング設定

    - 任意のVPC、サブネットを選択
    - 先ほど作成した、ALBを既存のロードバランサーとして選択

## 3.5．ECSonEC2インスタンス作成

1. インスタンス起動設定
    |項目 | 設定内容 |
    |:-----------|:------------|
    |インスタンス名| test-eni-trunking|
    | AMI名| amzn2-ami-ecs-hvm-2.0.20230301-x86_64-ebs|
    | AMI ID| ami-01703abf1e5cede54|
    | インスタンスタイプ| m5.large|
    |DNSリクエスト応答| 無効|
    |IAMロール| ecsInstanceRole|
    |ユーザデータ| 以下|

    ```:ユーザデータ
        #!/bin/bash
        echo ECS_CLUSTER=test-cluster1 >> /etc/ecs/ecs.config
    ```
    
    :::note warn
    　※Amazon ECS に最適化された AMIのバージョン 1.28.1 以降でないと
    　ENIトランキング機能に対応していないため注意が必要。

1. インスタンス登録確認

    * ECSコンソール>クラスター>インフラストラクチャを参照
    * EC2インスタンスが追加されたことを確認
　<img width="500" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3558533/2686ca1e-ff9f-9085-8d5c-71d506ec6ca1.png">


# 4．コンテナを3つ起動してみる
1. サービスの必要なタスクの数を変更
    * 「サービスの更新」ボタンをクリック
    *  必要なタスクの数：3に変更

    　ECS＞クラスター＞サービス＞test-httpd-service＞更新
    　<img width="500" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3558533/166e1369-de9e-1110-d77e-cdce8074d354.png">

1. タスク実行状況を確認
    * コンソール上から確認すると、2つのタスクのみ表示されていた
    　ECS＞クラスター＞サービス
    　<img width="500" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3558533/ab559d43-de0e-b62a-fad3-e5a042d26e0b.png">

    * サービスのイベント情報を確認
        ECS>クラスター>サービス＞デプロイとイベント
        <img width="500" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3558533/d305ede0-c15f-2fd2-c7a9-b5dcd68274a2.png">

:::note alert
　3つ目のタスクを実行出来ない旨のエラーが発生している
:::
```:メッセージ全文
service test-httpd-service was unable to place a task because no container instance met all of its requirements. 
The closest matching container-instance 4bfe560f78fe4d1baf8da01e7e236078 doesn't have the agent connected.
For more information, see the Troubleshooting section of the Amazon ECS Developer Guide.
```

**現状のままでは、3つ以上のタスクを起動出来ないことが分かった**


# 5．ENIトランキング機能の有効化を行う

1. ECS＞アカウント設定に移動
1. 「更新」　ボタンをクリック
　![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3558533/ac03a98c-f2a5-ea21-503d-581913928578.png)

1. AWSVPC Trunkingにチェックを入れて「変更を保存」ボタンをクリック
　![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3558533/67653b5d-de1a-12f5-7dc2-d03e546c373f.png)

1. ダイアログの「確認」ボタンをクリック
　![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3558533/f1cba209-4a18-7c76-17f8-cfd07d7b9653.png)

1. 変更を確認
　![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3558533/eca1ad6b-ab8c-c44b-ac45-48834c661c6a.png)


1. EC2再作成
    * ENIトランキング機能の適用は、awsvpcTrunking 設定をオンにした後から起動されたEC2インスタンスのみが対象
    * それ以前に起動されたインスタンスは、AWSVPC Trunking機能を使用できない。
    **有効後は必ずEC2インスタンスの再作成が必要**
    <br>

1. もう一度3つのタスクを起動する
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3558533/8caaf4de-ee48-3b9f-de1a-e2eb0f3333f8.png)


:::note alert
　未だに、3つ目のタスクを実行出来ない旨のエラーが発生している
　この後、EC2を作り直して何回やっても2つしかコンテナが起動しない
:::

# 6．エラーの原因調査

1. googleでエラー文を入力して検索した

    * 見つけた記事：[[ Qiita ] awsvpcTrunking設定を試す【ECS】]("https://qiita.com/s0mpt15/items/f536ffc9efb21f9a1619")
　↑途中までは同じ……その先が知りたい

    * 海外の方がissueとして質問しているのを発見：[githubのプラットフォーム]("https://github.com/aws/amazon-ecs-agent/issues/2760")
　↑返信を翻訳してみる

***
AWSマネジメントコンソールのECSのアカウント設定（awsvpcTrunkingの有効化）は、リージョンごとに適用される。
ユーザーやロールのようなIAMリソースはグローバルに設定されているものである。※リージョン特有のIAMリソースではない
awsvpcTrunkingの有効化は、マネジメントコンソール上からではなく、**CLIからroot権限を使用して有効にする必要がある**
上記を実施して、私の問題は解決した。
***

と、いう事で設定方法が間違っていたらしい。
まさかマネジメントコンソールを使用した設定方法が間違いだったとは！

**改めて公式ドキュメント等を確認**

下記リンクの、「コマンドラインを使用し、アカウント所有者としてユーザーまたはコンテナインスタンスの IAM ロールを引き上げられた ENI 制限に有効化するには」という箇所にCLIからの設定方法が記載されている
- [Elastic Network Interface のトランキング](https://docs.aws.amazon.com/ja_jp/AmazonECS/latest/developerguide/container-instance-eni.html#eni-trunking-considerations)



# 7．CLIからENIトランキングを有効化する
1. AWS CLIを起動
1. 以下のコマンド実行
    ```
    aws ecs put-account-setting-default --name awsvpcTrunking --value enabled
    ```
1. 結果（全てのロールに対してawsvpcTrunkingが有効になった）
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3558533/23bda230-7229-b4bd-9477-00a2356b4092.png)

# 8．コンテナを3つ起動してみる（リベンジ）
1. サービスの必要なタスクの数を変更
    * 「サービスの更新」ボタンをクリック
    * 必要なタスクの数：3に変更

        ECS＞クラスター＞サービス＞test-httpd-service＞更新
        <img width="500" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3558533/166e1369-de9e-1110-d77e-cdce8074d354.png">

1. タスク実行状況を確認
    **遂に、ENI上限を開放できた!!**
        ECS＞クラスター＞サービス
        <img width="500" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3558533/a226b563-3b8c-6359-6ba9-8268b0c03a2b.png">


<a id="#reference"></a>
# 参考文献
- [Elastic Network Interface](https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/using-eni.html)
- [Elastic Network Interface のトランキング](https://docs.aws.amazon.com/ja_jp/AmazonECS/latest/developerguide/container-instance-eni.html#eni-trunking-considerations)
- [[ Qiita ] awsvpcTrunking設定を試す【ECS】]("https://qiita.com/s0mpt15/items/f536ffc9efb21f9a1619")
- [海外の方が質問を上げていたgithubのプラットフォーム]("https://github.com/aws/amazon-ecs-agent/issues/2760")