🎄

コンテナ間通信をALBからECS Service Connectに切り替えようとしたら...

2023/12/11に公開

SRE Advent Calendar 2023の11日目の記事です。


Red Frascosinokumaです。

この記事では、Amazon ECS(Elastic Container Service)のService Connectを利用して、コンテナ間通信を従来のApplication Load Balancer(ALB)からECS Service Connectに切り替えようとした時に直面した課題について共有したいと思います。

いきなりまとめ

結局、ECS Service Connectの導入は見送っています。

  • Nginx の対応が予想以上に大変だった
  • 我々の環境においては、コスト削減効果がそこまで見込めなかった
    • コスト削減目的だけであれば、Fargate SPOT化やFeatureブランチ向けの環境の定期クリーニング処理を追加した方が削減効果が大きい

本題

なぜ、ECS Service Connectを導入しようとしたか?

2022年11月27日、ECS Service Connectが発表されました。
後述しますが、我々が運用するコンテナ環境では、コンテナ間の通信にALBを使用しています。
ECS Service Connectを使えば、ALBと同等の機能を担保したまま、ALBのコストを削減しつつ、インフラ構成をシンプルにできそうだったため、導入してみようと思い立ちました。

我々が運用するコンテナ環境について

  • ECS Fargate を使用
  • 3つのECS ServiceからなるWebサービスを運用中
    • Nginx(リバースプロキシ)
    • Next.js(フロントUI)
    • Apollo Server(GraphQLベースのAPI)
  • 各ECS Service間はALB経由で通信する
    • 構築当時、インフラコストは増えるが、Connection DrainingなどのALBの機能を使うことができるメリットを優先

導入時に発生した課題

結果を先にお伝えすると、導入は一旦取りやめてしまいました。
検証時に以下のような課題が見つかったためです。

Nginx環境での名前解決ができなくなる

ECS Service Connectは、サービス間の名前解決にhostsファイルを使用します。
Nginxを使用していて、リバースプロキシ(proxy_pass)を使用している場合、dnsmasqを導入するなどして、リバースプロキシ時にhostsを参照させるよう設定変更する必要があることが判明しました。

FROM nginx:1.23.3

# dnsmasq を systemd で起動するためにパッケージを追加 
RUN apt update && apt install -y dnsmasq systemctl

(中略)
systemctl start dnsmasq
/docker-entrypoint.sh nginx -g "daemon off;"

我々の環境において、リバースプロキシ層はなくてはならない存在であり、リバースプロキシの設定量も少なくありません。さらに、他システムへの通信も必要なため、hostsによる名前解決が必要な通信とDNSによる名前解決が必要な通信が混在しています。
通信方式をALBからECS Service Connect に切り替えるだけですめば良かったのですが、Nginxの仕様に引っ張られて、設定ファイルの修正がかなり膨れ上がってしまいました。

         # hosts参照させたい場合は、resolverを127.0.0.1に設定
    location = /hogehoge {
      resolver          127.0.0.1 valid=1s ipv6=off;
      resolver_timeout  5s;
      proxy_pass ${PROXY_PASS_TARGET}$request_uri;
    }
    
         # DNS参照させたい場合は、resolverは何も設定しない
    location = /hogehoge {
      proxy_pass ${PROXY_PASS_TARGET}$request_uri;
    }

最小スペックで動かしていたECSコンテナが起動しなくなる

開発環境ではコストを抑制する目的で、最小スペックのECSコンテナ(vCPU:256、メモリ:512MiB)で動作確認・テストを行なっています。
開発環境において、ALBからECS Service Connectに変更したところ、ECS Serviceが起動したり、しなかったりと動作が不安定になりました。

公式ドキュメントをよく読んでみると、サイドカーコンテナが安定して動作するために、少なくとも256vCPUと64MiBメモリを割り当てることが推奨されると記載されています。スペックを1段階上げると確かに問題なく動作しました。

我々は、GitのFeatureブランチがpushされるたびに開発環境を自動生成する仕組みを導入しています。日々5〜10環境ほど自動生成を繰り返しているので、これらのコンテナすべて1段階スペック増強すると、ALB廃止によるコスト削減効果がECSのスペック増強によるコスト増加によってほぼ帳消しになることが分かりました。

まとめ(再掲)

結局、ECS Service Connectの導入を一旦見送ることにしました。

  • Nginx の対応が予想以上に大変だった
  • 我々の環境においては、コスト削減効果がそこまで見込めなかった
    • コスト削減目的だけであれば、Fargate SPOT化やFeatureブランチ向けの環境の定期クリニーング処理を追加した方が削減効果が大きい

といった理由から、今すぐの導入は見送ることにしています。
しかしながら、2月にPublic IPv4の課金が始まるなど年が明けるとまた状況が変わります。
一定のコストメリットが見込めるようになったり、サービスのアップデートでよりメリットの大きい機能が追加されたりしたら、もう一度アーキテクチャの見直しにトライしたいと思います。

それでは、みなさま良いお年をお過ごしください。

Red Frasco

Discussion