経緯
Amazon ECSをインフラに利用したNode.js+expressのWEBアプリケーションを開発している過程でECSタスクが頻繁に強制停止されては再起動する事象に遭遇。
原因を調べるとコンテナインスンスタンス(Dockerホスト機)のメモリ不足でログ書き込みに失敗していた。
しかし、ECSタスクに割り当てているメモリは512MB程度でコンテナインスタンスの搭載メモリ上限には達していいないのになぜ…?
コンテナインスタンス上で動作しているプロセス一覧を確認するとNode.jsのプロセスが40個近く動作しており、それらがコンテナインスタンスのメモリを食いつぶしていた。
疑問
docker ps
の結果からみて起動しっぱなしのコンテナは存在しない。
docker ps -a
を実行するとSTATUS=Createdなコンテナがたくさん残っていた。
これは何?
Dockerはコンテナが停止されればプロセスも停止されるはずなのだが…
仮説
1週間ほど前にTaskDefinitionのLogging設定に記述ミスがあり、ECS Serviceにより何度も「タスクを起動しようとする」→「失敗」→「タスクを起動しようとする」…を繰り返していた。
その時のプロセスが残り続けているに違いない!
そして、コンテナが停止してもプロセスが残ることがあるに違いない!
検証
おそらくnode.jsとか関係ない。nginxコンテナを使って単純に再現するかを試す。
$ docker run --log-driver=awslogs --log-opt awslogs-group=unknown nginx
docker: Error response from daemon: Failed to initialize logging driver: Cannot determine region for awslogs driver.
一見logging driverのエラーでコンテナの起動に失敗した風。
$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
8befc665980a nginx "nginx -g 'daemon off" 2 minutes ago Created hungry_heyrovsky
Created状態のコンテナの存在を確認。
$ ps auxf
root 14295 0.0 0.0 208832 5528 ? Sl 20:18 0:00 \_ docker-containerd-shim 8befc665980aae3e099a71863f9ca54b97b8
root 14312 0.0 0.0 31732 5080 ? Ss 20:18 0:00 \_ nginx: master process nginx -g daemon off;
syslog 14331 0.0 0.0 32124 2816 ? S 20:18 0:00 \_ nginx: worker process
docker-containerd-shim 8befc665980aae3e099a71863f9ca54b97b8
を親としたnginxプロセスの存在を確認。
再現した!
対処
プロセスをkill。最も単純なのはコンテナインスタンスの再起動。