Dockerコンテナのログ大きさを制限する

何も考えずにDockerを使っていると、そのコンテナのログファイルが膨れ上がる。これを放置すると、最終的にはサーバの空き容量がなくなってしまう事態に陥る。これは、すべての種類のコンテナに言えることでもなく、特にログサイズが大きくなるコンテナがあるようだ。

これらのログを定期的に削除するのでも良いのだが、面倒。自動でログサイズを制限したい。当然ながら、ログなどは何かしら異常があった時にコンテナを動かしながらしか見ないので、ログサイズを制限して「最新のログ」だけを残すようにしても、ほとんど問題になることはないだろう。

ログが膨れ上がった状態

ncduで調べてみると、特にこのコンテナのログが膨れ上がっている。

つまり、「/var/lib/docker/containers/コンテナID/コンテナID-json.log」というファイルが膨れ上がっている。

この場合のコンテナIDは、「22e97…」なのだが、番号ではわからない。具体的にどのコンテナなのか?

「docker ps」コマンドで調べてみると、コンテナ一覧とそのIDがわかる。

80fa09807c7d   nextcloud:24.0.5                "/entrypoint.sh apac…"   5 months ago   Up 4 months             80/tcp                                                                                                                                                                                                                                                                                                                         nextcloud
22e97ec3446e   mariadb:latest                  "docker-entrypoint.s…"   5 months ago   Up 4 months             3306/tcp                                                                                                                                                                                                                                                                                                                       mariadb

ということで、犯人はmariadbコンテナということがわかった。

ログを制限する方法〜うまくいかない

docker-compose.ymlを使うという前提だが、ログサイズの制限には二つの方法がある。

  1. 各コンテナのdocker-compose.ymlにて制限をかける方法
  2. docker全体に制限をかける方法

Dockerのlogdriverを全て試してログの保存方法を考えるに解説がある。ここではdocker全体に制限をかけてみる。つまり、既存のコンテナに制限がかかるだけでなく、今後導入するいかなるコンテナにも自動的に制限がかけられることになる。

これは、/etc/docker/daemon.jsonに以下を記述するだけのようだ。もちろん、この場合には最大3Mバイト、ローテートで3つのファイルができる。

{
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "10m",
    "max-file": "3"
  }
}

このdaemon.jsonには他にもいろいろなオプションを指定できるようなのだが、最初は「存在していない」。自分で勝手に作成して良いようだ。

次にdocker自体を再起動する。

systemctl restart docker

しかし、全く効果がなかった。

docker-compose.ymlで制限をかける

個別のdocker-compose.ymlで制限をかけることにする。loggingキーワード以下に設定を記述する。

version: '3'

services:
  mariadb:
    logging:
      options:
        max-size: "10k"
        max-file: "1"
      driver: json-file
    image: mariadb:latest
    command: --transaction-isolation=READ-COMMITTED --binlog-format=ROW --innodb-file-per-table=1 --skip-innodb-read-only-compressed
    container_name: mariadb
    environment:
      - MARIADB_ROOT_PASSWORD=********
    volumes:
      - ./data:/var/lib/mysql
    restart: always

これを行った後、mariadbを再起動すると、ただちにログサイズが少量になった。成功。

そもそも何でこんなにログが出ているのか?

ログをみてみると、大量に出ている理由がわかった。

docker-compose logs -f

すると

mariadb    | 2024-12-17 23:29:15 66 [ERROR] Incorrect definition of table mysql.column_stats: expected column 'hist_type' at position 9 to have type enum('SINGLE_PREC_HB','DOUBLE_PREC_HB','JSON_HB'), found type enum('SINGLE_PREC_HB','DOUBLE_PREC_HB').
mariadb    | 2024-12-17 23:29:15 66 [ERROR] Incorrect definition of table mysql.column_stats: expected column 'histogram' at position 10 to have type longblob, found type varbinary(255).
mariadb    | 2024-12-17 23:29:15 66 [ERROR] Incorrect definition of table mysql.column_stats: expected column 'hist_type' at position 9 to have type enum('SINGLE_PREC_HB','DOUBLE_PREC_HB','JSON_HB'), found type enum('SINGLE_PREC_HB','DOUBLE_PREC_HB').
mariadb    | 2024-12-17 23:29:15 66 [ERROR] Incorrect definition of table mysql.column_stats: expected column 'histogram' at position 10 to have type longblob, found type varbinary(255).
mariadb    | 2024-12-17 23:29:15 66 [ERROR] Incorrect definition of table mysql.column_stats: expected column 'hist_type' at position 9 to have type enum('SINGLE_PREC_HB','DOUBLE_PREC_HB','JSON_HB'), found type enum('SINGLE_PREC_HB','DOUBLE_PREC_HB').
mariadb    | 2024-12-17 23:29:15 66 [ERROR] Incorrect definition of table mysql.column_stats: expected column 'histogram' at position 10 to have type longblob, found type varbinary(255).
mariadb    | 2024-12-17 23:29:15 66 [ERROR] Incorrect definition of table mysql.column_stats: expected column 'hist_type' at position 9 to have type enum('SINGLE_PREC_HB','DOUBLE_PREC_HB','JSON_HB'), found type enum('SINGLE_PREC_HB','DOUBLE_PREC_HB').
mariadb    | 2024-12-17 23:29:15 66 [ERROR] Incorrect definition of table mysql.column_stats: expected column 'histogram' at position 10 to have type longblob, found type varbinary(255).
mariadb    | 2024-12-17 23:29:15 66 [ERROR] Incorrect definition of table mysql.column_stats: expected column 'hist_type' at position 9 to have type enum('SINGLE_PREC_HB','DOUBLE_PREC_HB','JSON_HB'), found type enum('SINGLE_PREC_HB','DOUBLE_PREC_HB').
mariadb    | 2024-12-17 23:29:15 66 [ERROR] Incorrect definition of table mysql.colu

よくあるエラーらしく、(https://www.aqua-informatics.jp/?p=1151)[https://www.aqua-informatics.jp/?p=1151]に対処方法があった。

docker exec -it mariadb /bin/bash
mariadb -u root -proot

mysqlを使用
USE mysql;

hist_type 列の型を修正
ALTER TABLE column_stats MODIFY hist_type ENUM('SINGLE_PREC_HB', 'DOUBLE_PREC_HB', 'JSON_HB');

histogram 列の型を修正
ALTER TABLE column_stats MODIFY histogram LONGBLOB;

mariadbを再起動し、ログを見てみると、もうこのエラーは生じていない。

未分類

Posted by ysugimura