モヒカンメモ

髪色が定期的に変わることに定評のある(比較的)若者Webエンジニアの備忘録

Redashのログが無限に貯まり続けたせいでdisk fullで死んだ

セルフホストしている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使用量を調べるも微々たる大きさ。要因は別にありそう。

suzuken.hatenablog.jp

地道に 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を書いておけば自動でログローテーションするように設定出来ることが分かったのでこの方法で行ことに。

it-web-life.com

qiita.com

Docker Daemonにログローテーションの設定をする

Docker DaemonをLinuxで動かす場合、設定ファイルは /etc/docker/daemon.json に置けば良いらしい。

https://docs.docker.jp/config/daemon/daemon.html

docs.docker.com

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"
  }
}

これで良いはず!