Fargateで以下のようなDockerfileからビルドしたイメージで起動すると、タスクのステータスがessential container in task exited
で終了してしまう。
Fargate自体は開発環境で利用していて、アーキテクチャとか設定の仕方は分かってる。今回理由があって、別のAWSアカウントに一からFargateを立てて、適当なDockerイメージで検証することにした。
で、Fargateの環境を立てたのはもうだいぶ前なので、最初からの立て方は色々忘れてて、復習を兼ねて良い機会だと思い出しながら進めてく。先にリポジトリ立ててタスク定義作って、ALBも先に作っておいた方が良くて、そのターゲットグループはIPで作るんだったよな..と思い出しながら進めてく。で、そんなに時間かからずに環境できたので、Dockerイメージは適当にnginxを利用することにして、ubuntuのイメージにインストールするのがいいかなあ、nginxの公式(OSはdebian)がいいかなあなんて進めてく。で、とりあえずこんなもんかなとサービス作成してタスクが起動されると、上記のエラーでタスクは終了する。そのときターゲットグループのターゲットのステータスはヘルスチェック失敗でdraining(破棄)になってく。CloudWatch見ると、普通に起動処理が終わったあとの20秒後くらいに、sigexitを食らって終了するような出力がでてる。sigexitということは外部(AWS?)から終了が実行されてる?? タスクが終了するとまたタスクが起動するが、それも同じエラーで終了する、のループが続く。ここから、普段どおり以下のような切り分け(設定確認)をしてく。
- ポート番号の整合性取れてるか
- タスク定義、ターゲットグループ(ヘルスチェック)、ALBのリスナー、nginxのポート番号
- セキュリティグループちゃんと空いてるか
- サービス/タスク用、ALB用
で、見直しても問題ない。ここから深みにはまっていく..
- タスクの配置サブネットはパブリックとプライベートで制約はあったか
- プライベートサブネットからNAT経由でインターネット接続可能になってるか
- VPCエンドポイントのセキュリティグループは正しいか。エンドポイントの配置サブネットやプライベートDNS設定は正しいか
- etc
で、その辺で何が問題か分からないので、Dockerfileの中身を変えてみると、以下が分かった
- nginxの公式イメージはOK
- ubuntuの公式イメージはNG
nginxの公式イメージ利用時はFROM nginx
の1行なんだけど、ubuntuの公式イメージ利用時は、apt-getでnginxを入れている。nginxのインストールがうまくできていないのか?? 起動できていないのか?? など手元でdocker runしても特に問題なくて、なんでFargateで動かせないのか意味が分からない。
ただ、ubuntuで手でnginxを入れたときがだめ、という切り分けがついたので、インターネット上で同じ使い方している人の、実績があるであろうコードをコピペで入れて動かしてみようと調べたら、あるサイトに理由が書いてあった
6行目のENTRYPOINTコマンドは、コンテナを起動した際に実行するコマンドの指定だ。
Dockerでnginxを扱う場合、daemon off;の指定がないとコンテナが終了してしまうので、起動時に必ず必要なコマンドだ。
なるほどと、ENTRYPOINT ["nginx", "-g", "daemon off;"]
をDockerfileに追加したらタスク正常起動。
単にDockerの知識不足。。
(でも手元では普通に動いてた?)
以下のような状況だと、環境周りの設定が悪いのかなと疑ってしまうけど、こういうケースもある、と勉強になったのでした
- 被疑箇所を絞りづらいログ出力、ヘルスチェック失敗から環境設定周りを疑う
- 構成要素が多いサービス(サブネット/NAT/ルートテーブル/VPCエンドポイントなどNW周り, ALB/ターゲットグループ, タスク定義, etc..)で、久々にさわるのもあり、基本的な部分で見落としや、仕様に沿った設定の確認不足があるのではないか