Amazon ECSのタスク定義において、ポートマッピング関連のパラメータをみていたら、
似たようなパラメータがたくさんあって混乱してきたので整理します。
※2023年4月時点の情報です。
もくじ
1.前提事項:ECSのネットワークモード種別
ポートマッピングの話をする前に、前提知識として、
ECSのネットワークモードの種別を整理しておく。
ECSでコンテナを動かす際、コンテナがどのように外部と通信するかを設定する必要がある。
この、外部との通信方式のことをネットワークモードと呼ぶ。
ECSにおいて、ネットワークモードの選択肢は5種類ある。
ただし、起動タイプ(ホスト基盤となるインフラ)がFargateかEC2かによって、使用できるネットワークモードは異なる。また、起動タイプがEC2の場合、OSがLinuxかWindowsかによっても、使用できるネットワークモードが異なる。
各ネットワークモードの簡単な説明と、当該モードを使用可能な起動タイプ・OSは以下の通りである。
モード | 説明 | Fargate | EC2(Linux) | EC2(Windows) |
---|---|---|---|---|
awsvpc | タスクにElastic Network Interface(ENI)を割り当て、外部と直接通信する。(Docker組込みネットワークを経由しない) | 〇 | 〇 | 〇 |
bridge | ホストOS(Linux)上のDocker組込み仮想ネットワークを経由し、外部と通信する。 | × | 〇 ※デフォルト |
× |
default | ホストOS(Windows)上のDocker組込み仮想ネットワークを経由し、外部と通信する。 | × | × | 〇 ※デフォルト |
host | ホストOSのENIにコンテナポートを直接マッピングし、外部と直接通信する(Docker組込みネットワークを経由しない)。そのためホストOSの特定のポート番号を割り当てる必要がある。 | × | 〇 | × |
none | 外部接続できない。 | × | 〇 | × |
特にFargateを利用する際は、ネットワークモードが自動でawsvpcになることに注意したい。
2.ポートマッピングとは
さて、ここからいよいよ本題。
ポートマッピングとは、ホストのポートとコンテナのポートとを紐づけて、コンテナが外部通信できるようにするための機能である。
紐づけの設定は、ECS作成時に、ポートマッピングを制御するパラメータ(PortMappingオブジェクト)によって行う。
PostMappingオブジェクトは以下の変数によって構成される。
変数 | 説明 |
---|---|
containerPort | ホストのポートに紐づける、コンテナのポート番号。 ポートマッピング利用時に指定必須。 |
hostPort | コンテナのポート紐づけのために予約しておく、ホスト側のポート番号。 |
containerPortRange | 動的にマッピングされたホストポート範囲に紐づけられる、 コンテナのポート番号の範囲。 |
hostPortRange | マッピングに使用されるホストのポート番号の範囲。 ECSやDockerによって値が自動で割り当てられるため、指定はできない。 |
appProtocol | Service Connect利用時に使用。 詳細は3.Service Connectとはにて説明。 |
name | Service Connect利用時に使用。 詳細は3.Service Connectとはにて説明。 |
protocol | ポートマッピングに使用されるプロトコル。 デフォルトはtcp。条件を満たせばudp指定も可。 |
これら変数を持つPortMappingオブジェクトについて、
変数値(特にcontainerPort、hostPort)をどのように設定できるかは、
1で説明したネットワークモードをどの種別にするかによって微妙に変わってくる。
◎ネットワークモードがawsvpcの場合
ネットワークモードがawsvpcで、ポートマッピングしたい場合、
起動タイプがFargateかEC2かによって、以下のようにPortMappingオブジェクトの変数を設定できる。
■Fargateの場合
基本的に、コンテナ側・ホスト側とも、使用するポートを静的に指定する。
変数 | 説明 |
---|---|
コンテナ側の使用ポート | containerPort で使用ポートを指定 |
ホスト側の使用ポート |
hostPort=containerPort になるように指定 |
■EC2の場合
コンテナ側・ホスト側とも、使用するポートを静的に指定できる他、
ホスト側のポートを動的に指定することもできる。
変数 | 説明 |
---|---|
コンテナ側の使用ポート | containerPort で使用ポートを指定。 |
ホスト側の使用ポート |
hostPort で静的に明示指定。 または指定なし/0に設定すると、 containerPortと同値が自動的に設定される。 |
◎ネットワークモードがbridgeの場合
ネットワークモードがbridgeでポートマッピングしたい場合、
コンテナ側・ホスト側とも、使用するポートを静的に指定できる他、
ホスト側のポートを動的に指定することもできる。
変数 | 説明 |
---|---|
コンテナ側の使用ポート | containerPort で使用ポートを指定。 |
ホスト側の使用ポート |
hostPort で静的に指定。 または指定なし/0に設定すると、 開いているホストポートが動的に割り当てられる。 |
◎ネットワークモードがdefaultの場合
ネットワークモードがdefaultの時については、
公式ドキュメントに詳しい説明が無く、、スキップさせてくださいm(__)m
ご存じの方いらっしゃったらコメントで教えてください。
ただし、containerPortRangeは定義不可であり、
コンテナ側はcontainerPort で使用ポートを指定することになる。
おそらくEC2側は、hostPort で静的に指定するのみと思われる(動的に決定できるかは不明)。
◎ネットワークモードがhostの場合
ネットワークモードがhostの場合、コンテナは、ホストであるEC2インスタンスのENIにポートをマッピングし、ホストのネットワークを使用して外部と接続する。
このとき、
コンテナ側のポート番号(containerPortパラメータで指定)と、
ホスト側のポート番号(hostPortパラメータで指定)は同じ番号を静的に指定することになる。動的指定はできない。
hostネットワークでポートマッピングする際の重要な制約として、
1つのEC2インスタンスにおいて、同じタスク定義のタスクは1つしか実行できない。
ホストのポート番号は、同時に重複利用はできないためである。(例えば、ホストポート番号100に来た通信をコンテナAに振り分ける設定でタスク定義し、その定義でタスクを2つ作っていた場合、どちらのタスクのコンテナAに向けた通信なのか判断できなくなる。そのため、同じタスク定義でのタスクは、1つのEC2インスタンスにつき1つまでとなる)
以上より、hostネットワークでのポートマッピングは、拡張性や柔軟性においてやや難がありそうだ。
◎ネットワークモードがnoneの場合
ネットワークモードがnoneの場合、コンテナはそもそも外部接続できない。
従って、ポートマッピングの設定もできない。
3.補足:Service Connectでポートマッピング
◎Service Connectとは
ポートマッピングの話に入る前に、Service Connectを簡単に説明する。
ざっくりいうと、Service Connectとは、
Amazon ECSサービス間の接続・通信を簡単にしてくれる機能である。
Service Connectは比較的新しいAWSサービスである。
そもそもService Connectがなかった時代、ECSサービス間の通信手段の主な選択肢は、以下の3つだった。
・ECSサービス間にロードバランサを作成し、通信を仲介させる
→ELB利用の金銭コストが高く、設定の手間も発生。
・Amazon Cloud MapにECSサービスを登録、さらにRoute53にDNSレコードを登録する
→登録内容は自動更新されないので手動で更新が必要。
・AWS App Meshを利用してサービス間通信をインフラ制御
→ECSとは異なる場所で通信制御となるため、管理が大変。
これらどの手段をとっても、それぞれ課題があったことが分かる。
そこで、これら課題を解決し、シームレスにECSサービス間の通信を実現するため、
新たに出てきたサービスがService Connectというわけだ。
Service Connectを使うと、ECSの設定時に、分かりやすい任意のサービス名を登録することになる。
裏ではECSとCloud Mapがシームレスに連携しており、
登録したサービス名を利用して、ECSサービス間で簡単に通信できるようになっている。
◎Service Connect利用時のポートマッピングについて
Service Connectを利用する場合にはいくつか設定が必要だが、
ポートマッピングに関する設定も必要となる。
具体的には、PortMappingオブジェクトの以下の変数を指定する。
変数 | 説明 |
---|---|
appProtocol | ポートマッピングで使用するアプリケーションプロトコル。 設定可能な値は、"HTTP"、"HTTP2"、"GRPC"。 設定は任意だが、設定した場合、 ・プロトコル固有の接続処理がサービス接続プロキシに追加される ・ECSコンソールとCloudWatchで、プロトコル固有のモニタリングが追加される。 設定しない場合はTCPが使用される。 |
name | 設定必須。 ポートマッピングに使用される名前。 |
今回は以上!
※周辺知識が膨大なのもあり、特にService Connect部分について、ふわっとした内容でごめんなさい(´・ω・`)
もうちょっと勉強する機会があれば改訂します。