セルフホストしているRedashのログが貯まり続けたせいでdisk fullで死んだ。
OSS版Redash をEC2でセルフホストしてそのまま運用していると踏むトラップだと思うので各位気をつけられたし。
ざっくり要点まとめ
- Redashは結構ログを吐く
- Docker Daemonはデフォルト設定では無限にログを貯め続ける
- ↑の仕様が重なって、ログのローテーション設定をしておかないとディスクが食いつぶされる
調査と一次対応
「Redashが使えなくなった」というアラートを受けて調査したところ、dockerがdiskを食いつぶしてハングしていた。
root@xxx:/var/lib/docker# cat . | sort -r 9.7G containers 9.6G overlay2 ...
下記の記事を参考に各コンテナのdisk使用量を調べるも微々たる大きさ。要因は別にありそう。
地道に du
コマンドを叩きながら深ぼっていくと、diskをたくさん食っているのはコンテナのログファイルということが判明。
root@xxx:/var/lib/docker# docker inspect c347f677f78a | less ... "LogPath": "/var/lib/docker/containers/c347f677f78a9aac644c1c818e119e6aced19b8506d683b9012a50e964382e54/c347f677f78a9aac644c1c818e119e6aced19b8506d683b9012a50e964382e54-json.log", ...
root@xxx:/var/lib/docker/containers/c347f677f78a9aac644c1c818e119e6aced19b8506d683b9012a50e964382e54# du -sh * 2.9G c347f677f78a9aac644c1c818e119e6aced19b8506d683b9012a50e964382e54-json.log 4.0K checkpoints 8.0K config.v2.json 4.0K hostconfig.json 4.0K hostname 4.0K hosts 4.0K mounts 4.0K resolv.conf 4.0K resolv.conf.hash
Redashをとめて find /var/lib/docker/containers -type f -name '*-json.log' | xargs truncate --size 0
でログファイルを切り詰めたあとRedashを起動させると無事起動して復旧したことを確認。
root@xxx:/opt/redash# docker-compose stop ... root@xxx:/opt/redash# find /var/lib/docker/containers -type f -name '*-json.log' | xargs sudo truncate --size 0 ... root@xxx:/opt/redash# docker-compose up -d ...
恒久対応を考える
一次対応として truncate
コマンドを叩いてひとまず復旧はしたものの、このままでは時間が経つとまた起きてしまうので恒久対応について考える。
最初はtrucateコマンドをcrontabで定期実行しようかと思ったけど、ログ消した直後にRedashでトラブルが起きてしまったら調査するとき困りそうだと思ってやめた。「redash ログローテーション」や「docker ログローテーション」などのキーワードでヒットしたブログ記事を読んで、docker engineのconfigを書いておけば自動でログローテーションするように設定出来ることが分かったのでこの方法で行ことに。
Docker Daemonにログローテーションの設定をする
Docker DaemonをLinuxで動かす場合、設定ファイルは /etc/docker/daemon.json
に置けば良いらしい。
https://docs.docker.jp/config/daemon/daemon.html
10MB分ぐらいログ残しとけば大抵のトラブルには対応できるだろうという雑な読みで、下記のように設定。
/etc/docker/daemon.json
{ "log-driver": "json-file", "log-opts": { "max-size": "5m", "max-file": "2" } }
設定を反映するにはdockerdの再起動とdocker composeスタック作り直しが必要だった。
ubuntu@xxx:/opt/redash$ sudo docker-compose down ... ubuntu@xxx:/opt/redash$ sudo systemctl restart docker ... ubuntu@xxx:/opt/redash$ sudo docker-compose up -d ...
ubuntu@xxx:/opt/redash$ sudo docker inspect redash_worker_1 > inspect.log $ cat inspect.log | jq '.[0].HostConfig.LogConfig' { "Type": "json-file", "Config": { "max-size": "5m", "max-file": "2" } }
これで良いはず!