【AWS】ECSコンテナのポートマッピングについて整理する | 若手エンジニアのブログ

若手エンジニアのブログ

文系出身の若手女子エンジニアによる技術ブログ。
日々の経験や学びをアウトプットするためにブログを書いています。
バックエンド(Java+SpringFramework)を経てインフラエンジニアになりました。
今は育休中につき、本で勉強したことを中心にアウトプットしています。

Amazon ECSのタスク定義において、ポートマッピング関連のパラメータをみていたら、

似たようなパラメータがたくさんあって混乱してきたので整理します。

※2023年4月時点の情報です。

 

もくじ

1.前提事項:ECSのネットワークモード種別

2.ポートマッピングとは

3.補足:AWS Service Connectについて

 

 

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部分について、ふわっとした内容でごめんなさい(´・ω・`)

もうちょっと勉強する機会があれば改訂します。