ECSのネットワークモードを調べてみた
はじめに
今回はAWSのECSのネットワークモードについて調べてみました。
きっかけはECSをEC2タイプで起動した際に、ネットワークモードの選択肢が色々あって気になったので調べてみました。
それぞれの違いは、どのようにホスト内のコンテナに接続するのか?という部分です。
ホストというのはコンテナを動作させるコンピュータ(EC2)のことです。
起動タイプ
ECSの起動タイプは2つの選択肢があります。
サーバレス型の「Fargate」
ホスト型の「EC2」
Fargateのネットワークモードはawsvpcのみなので、今回はあまり関係ありません。
EC2を選択した場合に複数の選択肢があるため、今回はこちらのネットワークモードが中心です。
host
まずはhostモードです。
hostはコンテナを実行しているホストに紐づくモードです。
ホストのENIを使ってコンテナが通信を行います。
具体的には以下のような図になります。
こちら、パッと見は問題なように思うかもしれませんが、非推奨となっています。
hostモードの問題点は、1つのホストで「ホストのポート=コンテナのポート」になります。
例えば、以下のように3000番ポートで処理を行うアプリケーションを同時に起動することができません。
これにより、複数のコンテナで同一の処理を負荷分散するということができません。
これを可能にするのが次の「bridge」です。
bridge
bridgeはDockerのデフォルトであるbridgeネットワークと同じモードです。
bridgeはENIとコンテナの間に新たなレイヤ(bridge)を挟みます。
こうすることで、ホストとコンテナを別のポートで接続することができます。
先ほどのhostとの違いは、bridgeというレイヤーが間に入ったことと、ホストとコンテナのポートが別になっています。
何が嬉しいかというと、ホストのポートを変更することで、同じポートでコンテナを起動させられるという点です。
これにより、LoadBalancerを使った負荷分散が可能になります。
ALBやNLBを使ってポート毎に負荷分散ができます。
ホストのポートはbridgeの動的マッピングという機能により、未使用のポートを動的(ランダム)に割り当てることが可能です。
しかし、逆にポートをランダムに割り当てることで、ポートを制御することが難しくなります。
そのため、セキュリティ要件の厳しい場合では次に紹介するawsvpcモードが推奨されます。
補足ですが、bridgeを使ってホストのポートを静的に割り当てることも可能です。
awsvpc
awsvpcモードではホスト内のコンテナ毎にENIが生成されます。
hostやbridgeではホストのENIを使用していました、それをコンテナ毎のENIとすることで、より柔軟な設定が可能になります。
まずは図を見てみましょう。
先程までとの違いは、コンテナ毎にENIが増えていますね。
このENIはホストのENIとは別に生成され、VPC内で独自のプライベートIPが割り当てられます。
これにより、各コンテナ毎にセキュリ設定ができたり、同じホスト内のコンテナからの通信を制限することもできます。
起動モードがFargateの場合は、このawsvpcモードが自動的に選択されます。
こちらモードの唯一の欠点は、EC2の種類によって作成できるENIの数に上限があるという点です。
default
defaultモードを選択するとbridgeモードと同じ仕様になります。
これはECSがDockerを基盤として動作しているためだと思いますが、なぜあえて選択肢としてあるのかが疑問です。
none
最後に、noneモードは外からコンテナに接続できないモードです。
例えばローカルリソースのみでワークフローを行うようなアプリケーションで使用されると思います。
ホストのボリュームをマウントするなどしてデータのやり取りができます。
ここはあまり調べきれなかったので、またハンズオンをしてみたいと思います。
まとめ
ECSのEC2タイプは色々と管理が必要になるので、どちらかというとFargateを使うことが多いかと思います。
特にENIの制限を受けない範囲であればawsvpcを使うのが一般的なのかな?と感じました。
ECSはDockerを元にしているので、Dockerのネットワークモードも一緒に学習ができて一石二鳥でした。
参考資
Discussion