ECSのNetwork Mode awsvpcとbridgeとHostの比較

# 内容

https://ecsworkshop.com/ecs_networking/ にのっているNAT以外を日本語にしてまとめた -> https://docs.aws.amazon.com/AmazonECS/latest/bestpracticesguide/networking-networkmode.html あとで、ここにどのネットワークモードを選択するかの公式ページがあったが、こちらがわかりやすい。

1. awsvpc
1. bridge
1. host
1. none

# [AWSVPC MODE](https://ecsworkshop.com/ecs_networking/awsvpc/)

- ENIを各タスクに割り振り、動的プライベートIPアドレスと内部DNS名を提供する <- コンテナネットワーク管理と操作を簡易化し、タスクがAWSのネットワーク機能を全て使うことができる
- タスクのENIの管理は全てECSでされるので、コンソールから誤って消してしまうことを防いでいる
- ECSは awsvpc ネットワークモードを推奨している

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/7059/77fcff73-126a-a02d-e3ef-3e2c4268139a.png)

利点:

- IPアドレスとENIのDNS名により連想可能
- ALBとNLBにIPターゲットとしてアタッチが可能
- VPCフローログとして監視可能
- CloudWatchログやContainer Insights と連携ができる
- Security Groupによってアクセスが管理できる
- 同一インスタンス上で、同じタスクディフィニッションのタスクをポート衝突の心配なく実行可能
- ブリッジネットワークモードで必要となるport翻訳やdocker0ブリッジの帯域幅のために競合する必要がないためパフォーマンスが高い

Considerations:

- EC2インスタンスタイプによってENIの数に上限がある → [Elastic Network Interface のトランキング](https://docs.aws.amazon.com/ja_jp/AmazonECS/latest/developerguide/container-instance-eni.html)の考慮
- ENIトランキングを使った場合、大量のワークロードを走らせる場合には、IPアドレスが枯渇しないかどうか確認が必要

詳細: https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task-networking-awsvpc.html

# [BRIDGE MODE](https://ecsworkshop.com/ecs_networking/bridge/)

- タスクのホストとなるEC2インスタンス内のDockerのbuilt-in仮想ネットワークを使う
- タスクは、bridge network IPレンジからIPアドレスを取得する
- コンテナは、docker0の仮想ブリッジインターフェイスを使って、インスタンス外のエンドポイントと通信する。そのインスタンスのENIを使って。
- bridge networkのポートマッピングは、複数のコンテナが同じホストで同じポートを使うことが出来ない
    - nginxのコンテナを2つ立てて８０番ポートをホストの80番ポートにマップしたければEC2インスタンスが２つ必要になる **Static port mapping**
    - ホストのポートをランダムに割り振ることで同じホストでも複数のコンテナを動かすことを可能とする **Dynamic port mapping** <- `containerDefinitions.portMappings.hostPort`を0とセットすることで指定できる

Dynamic port mappingのダイアグラム: 

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/7059/2834bce7-1d2d-c8f0-3932-26aae2a85f69.png)

Static port mappingのダイアグラム:

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/7059/c1a52427-b7e0-4560-2f49-aa851e46bb3a.png)

Considerations:

- Additional network hop and decreased performance by using `docker0` 仮想ブリッジインターフェイスを使うことで、さらにネットワークホップによるパフォーマンスの劣化がある
- コンテナは、Dockerから割り振られたIPアドレスでは連想可能ではない
- ホストポートマッピングは、追加の操作と考慮が必要となる
- 一つのEC2 ENIが複数のコンテナに共有される
- 細かい粒度でのSecurity Groupｓによるコンテナへのネットワークポリシーの適用ができない
- AWS ネットワーク監視との連携ができない

その他: https://docs.aws.amazon.com/ja_jp/AmazonECS/latest/developerguide/task-networking-bridge.html

# [HOST MODE](https://ecsworkshop.com/ecs_networking/host/)

- taskのネットワークスタックはEC2ホストから分離されない
- コンテナは自分のIPを取得しない

HOST MODEは、パフォーマンスを最適化するためには役立つ。コンテナが広いポートレンジを必要とする状況では、ネットワークアドレス変換を必要としないためと "userland-proxy"をそれぞれのポートに作成しないため

Considerations:
単純なアプローチだが大きなデメリットがある:

- 一つのホストに一つ以上の同様のタスクを実行できない
- ポートの再マップが不可能　→ Portの衝突の場合は、コンテナ内のアプリケーション設定を変更することでしか解消できない


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/7059/556b1dd2-b5cb-0ea8-e163-ce638b583b29.png)

# [NONE MODE](https://ecsworkshop.com/ecs_networking/none/)

ネットワークスタックを使用しない。コンテナ内では、ループバックデバイスのみが作成される。タスクが外部ネットワーク接続を持たない場合はこちらを使える。

# 感想

- AWSが奨励してる通り、特に理由がなければ、ENIの上限考慮しつつawsvpcを使えばいいなと思った → その場合[ENI trunking](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/container-instance-eni.html) と規模によってIPアドレスの数を考慮する

# 参考リンク

- https://ecsworkshop.com/ecs_networking/
- https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task-networking.html
- https://docs.aws.amazon.com/AmazonECS/latest/developerguide/container-instance-eni.html