ECSでタスクが起動しない時の調査方法

背景

オンプレミス環境からAWS ECSへ移行しようというプロジェクトを行っております。環境はnginx + Railsです。

Docker Desktop for Macでdocker networkを作成しnginxとrailsでコンテナ間通信ができるところまでは確認できたので、そのコンテナイメージをECRにpushし、タスク定義まで行いました。

ECSクラスターの作成を行い、作成したタスク定義を実行したところ起動できなかったのでその時の調査方法を記載します。

ECSインスタンスにログイン

起動しない原因を調査するにあたってまずはログを確認したいのですが、ログの確認方法がわかっていません…なので、本来もっと良い方法があると思うのですがよくわかっていないので、一旦ECSインスタンスにSSHログインできるようにしました。

2020/12/9追記

ログの確認方法

ECSクラスターを選択、下のタブのタスクをクリックします。

タスクの一覧が表示されます。表示されない場合は、コンテナがすでに止まってしまっている可能性が高いです。その場合は、必要なタスクのステータスStoppedにすると表示されると思います。タスクのIDのリンクをクリックします。するとタスクの詳細ページに遷移します。

画面上部にタブがあり、Logsタブをクリックします。ログを表示するコンテナを選択しますというメッセージの横にセレクトボックスがあるので、ログを表示するコンテナを選択します。CloudWatchに出力する(logDriverがawslog)設定になっているコンテナが選択できます。

選択すると下にログが表示されます。エラーなどコンテナが起動できなかった理由がわかると思います。

ECSインスタンスにログインするための設定

ECSインスタンスにログインするためには以下の設定が必要です。

  • クラスターテンプレートの選択EC2 Linux + ネットワーキングを選択する
  • クラスターの設定 -> インスタンスの設定キーペアを指定する
  • クラスターの設定 -> ネットワーキングパブリックサブネットを指定する
  • クラスターの設定 -> ネットワーキングAuto assign public IPEnabledにする
    • サブネットの設定でパブリック IPv4 アドレスの自動はいになっていればUse subnet settingでも大丈夫です
  • クラスターの設定 -> セキュリティグループでSSHを通しているセキュリティグループを選択する
    • デフォルトのセキュリティグループではNG

以上の設定でクラスターを作成します。

ECSインスタンスの起動確認

先ほど作成したクラスターを選択して、ECS インスタンスタブをクリックすると、作成したクラスターのECSインスタンスが表示されます。ECS インスタンスのリンクをクリックすると、EC2の確認ができます。

ECSインスタンスにSSHする

確認したEC2のパブリックDNS、もしくはパブリックIPにクラスター作成時に指定したキーペアを使ってログインします。

コンテナのログを確認

早速コンテナの状況を確認します。docker ps -aをすると、なにかの原因でステータスがExitedになっていました。

コンテナのログの確認にはdocker logsコマンドを利用します。

1
2
3
4
5
6
7
8
9
$ docker logs コンテナID
/docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration
/docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/
/docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
10-listen-on-ipv6-by-default.sh: error: /etc/nginx/conf.d/default.conf is not a file or does not exist
/docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh
/docker-entrypoint.sh: Configuration complete; ready for start up
2020/07/22 07:55:16 [emerg] 1#1: host not found in upstream "rails:3000" in /etc/nginx/conf.d/rails.conf:2
nginx: [emerg] host not found in upstream "rails:3000" in /etc/nginx/conf.d/rails.conf:2

nginxの設定がDocker Desktopで動作確認した時のそのままになってしまっているのが原因のようです。(docker networkを作成して動作確認したときに、Rails用コンテナをrailsという名前で起動していたため)

今回、タスク定義のネットワークモードをawsvpcにしているので、コンテナ間通信はlocalhost指定で行えます。こちらを参考にしました。

ですので、nginxのupstreamの指定をlocalhost:3000として、コンテナをbuild、pushしたら無事タスクが起動しました。

まとめ

なにか起こった時の調査にログは欠かせません。まずはログを確認するようにしたいです。
今回のログの確認方法は本来の方法ではないと思います。Fargate使っていたらできないと思いますし…
本来はCloudWatchなど利用して行うのだと思いますが、まだその辺りを理解できていないのでこれから調べていきたいと思います。

※ Container Insightsを使ってみましたが使用しているリソース確認、マップ表示くらいの機能でした。プロダクション環境では重宝するかもしれません。