AWS ECS タスク内でコンテナ名でのコンテナ間通信
nginxでのリバースプロキシ + railsというよくある組み合わせのアプリケーションをECSでデプロイしようとした際、うまく起動できず原因を調べ始めました。
順を追って書いていますが、結論はこちらです。
原因調査
まずrails側のログを見てみると、何もエラーがないのに突然落ちているというのがわかります。
$ docker logs ecs-****************-task-8-app-******************** => Booting Puma => Rails 7.0.4.2 application starting in staging => Run `bin/rails server --help` for more startup options Puma starting in single mode... * Puma version: 5.6.5 (ruby 3.1.3-p185) ("Birdie's Version") * Min threads: 5 * Max threads: 5 * Environment: staging * PID: 1 * Listening on http://0.0.0.0:3000 Use Ctrl-C to stop - Gracefully stopping, waiting for requests to finish Exiting
このケース、ヘルスチェックが通らずECS側の挙動によって落とされた時等に発生します。
ということで、まずはヘルスチェック周りを確認したのですが、特に問題はなさそう。
このときnginx側のログには host not found in upstream “app” が出力されていましたが、この時点ではrailsが落ちているからだと思っていました。
が、CloudWatchログを設定して両コンテナのログを合わせて確認してみると、こんな流れになっていました。
rails起動→nginx起動するもappが見つからず落ちる→落ちたステータスを見てECSがrailsも落とす
という順序のようです。
このとき発生している現象
ということでようやく本題に入りますが、nginxがapp(rails)を見つけられていません。
docker-composeでは特に何も指定しなくても別コンテナのノード名で通信することができるのですが、ECSではそうはいかないようです。
タスク内でコンテナ名でのコンテナ間通信をさせる方法
検索してみると、ネットワークをデフォルト(この時はデフォルトはブリッジ扱いになっていました)ではなくawsvpcに変更して云々みたいな記事は引っかかるのですが、普通に考えればブリッジネットワークのままでも方法はあるはずです。
ということで調べていくと公式のユーザーガイドの中にありました。
Amazon ECS クラスターの NGINX ワークロードのサンプル
の中の
Amazon ECS で NGINX とウェブサーバーアプリを実行するタスク定義を作成します。
のタスク定義を見ると、nginxコンテナの設定に
"links": [ "app" ]
という記述が。
まさにこれでした。
早速タスク定義にlinksを追加して起動すると、問題なく動きました。