😧

AWS ECS の IPv6 対応がムズカシイ

2022/05/03に公開約3,700字

サマリ

  • この記事は AWS ECS で IPv6 に対応したアプリケーションを構築しようとした際に発生したトラブルをまとめた記事になります
  • トラブルの原因は IPアドレス(IPv6)タイプのターゲットグループ(以下TG)でした
  • ECS サービス作成時に IPv6 タイプの TG を使用する ELB を選択すると、定期的に ELB から切り離され、タスクが再構成される可能性があります
  • (2022年5月時点)ECS で IPv6 対応のアプリケーションを構築する場合、他の AWS サービスを活用して IPv6 対応できるような仕組みが必要です

背景

仕事で AWS ECS を使用して IPv6 アドレスに対応した API サーバを構築しようとしていました。
もともとオンプレで利用してきたアプリとなっており、オンプレ版では IPv6 通信だけで完結するような仕様となっていました。
AWS に移行してもなるべく仕様を変更したくなかったため、ELB と ECS タスク間の通信も IPv6 で行うようにしたいと考えてました。
TG が IPv6 アドレスを登録できることは知っていたため、IPv4 タイプの TG と同様に構築すればよいと思ってました。

ECS サービスを作成してみると、、

ECSサービスを作成し、しばらく待つのですが、TGの health status が healthy/unhealthy が表示されるどころかいつまで経っても登録されないので、コンソールで ECS タスクの IPv6 アドレスを手動で TG に登録したところ、無事 healthy になりました。
この時点で違和感があったのですが、この時は特に不信に思うこともなくアプリの評価を進めました。

しかし、しばらくするとなぜか unhealthy になっていました。
いや healthy になっていたし、ALB の DNS 名を curl でアクセスできたからアプリは問題ないはずと思い、ECS コンソールの起動時間を確認するとなぜか新しくタスクが再構成されており、その再構成されたタスクは TG に登録されてませんでした。

しばらく放置して後に CloudTrail を見てみると大量の RegisterTargets のイベントが発生していました・・・

イベントの詳細を見てみると全てのイベントで以下のエラーメッセージが発生してました。

"errorCode": "ValidationException",
"errorMessage": "The IP address '10.***.***.***' is not a valid IPv6 address",

あれ、IPv6 タイプの TG にしているのになぜ IPv4 アドレスでエラーメッセージ?

AWS サポートに問い合わせ

この後何度も新しい ECS サービスを作成したのですが、同じ症状でした。(※Fargate/EC2 タイプ どちらも同じ症状でした)

解決できないので、この2つの症状に関して AWS サポートに以下の内容を問い合わせしてみました。

  1. ECS サービス作成時にタスクの IPv6 アドレスが TG に自動で登録されないこと
  2. ECS タスクが約1時間で再構成を繰り返していること

AWSサポートの回答

一部抜粋

こちらは正常な挙動として期待されたものではございません。
ECS サービスから起動された ECS タスクが NLB のターゲットグループへ登録できず、その結果としてターゲットグループへの登録に失敗してから約 1 時間後にタスクが ECS サービスにより終了され、その後に新たなタスクが起動されるという動作を繰り返してしまっているものと存じます。
ECS サービス: dev-ecs-service (作成したECSサービス名) のイベントを拝見いたしますと、ターゲットグループへの登録は以下のようなエラーメッセージで失敗していることを確認いたしました。

(service dev-ecs-service) failed to register targets in (target-group arn:aws:elasticloadbalancing:ap-northeast-1: xxxxxxxx) with (error The IP address '10.xxx.xxx.xxx' is not a valid IPv6 address)

IPv6 タイプのターゲットグループであるにもかかわらず、ECS タスクをターゲットグループへ登録する際には IPv4 のアドレスが用いられており、ターゲットの登録に失敗しておりました。

えぇ、IPv6 タイプの TG なのに IPv4 を使うってどういうこと? と思いました。
原因がまだ判明してないとのことだったので、数日待つと以下の回答でした。

■ タスクが 1 時間ごとに停止されてしまう原因について

調査・検証の結果、ECS サービスから起動し ALB/NLB のターゲットグループへ登録される awsvpc ネットワークタイプの ECS タスクにおいて、現状の予期された挙動であることを確認いたしました。
現状の ECS サービスの仕様上の制限であるものとご理解賜れますようお願い申し上げます。

ALB/NLB のターゲットグループが紐付けられた ECS サービスにおいて awsvpc ネットワークタイプの ECS・Fargate タスクが起動されると、ECS サービスが当該タスクを IP アドレスタイプのターゲットとしてターゲットグループへ登録いたします。
この時、現状の ECS サービスではタスクの IPv4 アドレスを使用して RegisterTargets API が実行されることを当方の検証などから確認いたしました。

うーん、IPv6 タイプなのに IPv4 アドレスを登録しようとするのを仕様と言ってしまうのはちょっと・・

現時点(2022年5月時点)での解決方法

ECS で IPv6 通信を使用するには以下の対応が必要です。

  1. TG は IPv4 タイプを使用、NLB で IPv6 アドレスを固定する (NLB⇔ECSは IPv4 通信)
  2. Lambda 関数で awscli を実行することで ECS タスクの IPv6 アドレス を TG に自動登録する仕組みを作成する

内部の通信は IPv4 でもよいのであれば 1 の方法が簡単に構築できますし、IPv4 タイプなので TG への自動登録も行ってくれます。
NLB の TG に ALB を登録できるので、NLB → ALB → ECS といった構成も可能です。
以下の記事が参考になると思います。

https://dev.classmethod.jp/articles/alb-type-target-group-for-nlb/

IPv6 通信だけで完結させたい場合、手動で TG に IPv6 アドレスを登録する方法もありますが、手間なので 2 の方法をとることで タスクの IPv6 アドレスを自動登録することが可能となります。
この方法では ECS サービス作成時では ELB の設定は行わずに ECS サービス、タスクを起動させる必要があります。

2 の方法をもう少し具体的に言うと、ECS タスクが RUNNING するときはIPv6 アドレスを TG に登録する cli を実行、ECS タスクが STOPPED すろときはIPv6 アドレスを TG から登録解除する cli を実行するように Lambda 関数を設定することで実現できます。

2 の方法は別の記事で解説できればと思ってます。

まとめ

2022年5月時点では、ECS の IPv6 対応は最低限のレベルであり、追加で IPv6 通信ができるような工夫や仕組みが必要ということがわかりました。

IPv6 対応のシステムを構築する場面はそこまで多くないと思いますが、参考になれば幸いです。

Discussion

ログインするとコメントできます