Docker for Mac の container のログを空にする

Docker for Mac で container のログを空にする方法の紹介です。
執筆時の環境は Docker for Mac 18.06.1-ce-mac73 (26764) です。

前置き

docker inspect を実行すると、container のログファイルのパスを取得できます。

$ docker inspect CONTAINER_ID --format "{{.LogPath}}"
/var/lib/docker/containers/3d0305c254c33ff5e78d675f45e60fdcef65937ed8b53e21baf07f818d34ce9b/3d0305c254c33ff5e78d675f45e60fdcef65937ed8b53e21baf07f818d34ce9b-json.log

Linux 上で dockerd や containerd が docker container と同じホストで動いている場合は、以下のようなコマンドを実行することでログを空にできます。

$ sudo truncate $(docker inspect CONTAINER_ID --format "{{.LogPath}}") --size 0
$ sudo bash -c ":> $(docker inspect CONTAINER_ID --format "{{.LogPath}}")"

しかし、macOS の Docker for Mac で docker inspect を実行すると、ログファイルのパスは取得できますが、macOS 上には /var/lib/docker がないので、上記の方法ではログを空にできません。 これは、macOS 上の HyperKit という仮想化環境で LinuxKit という軽量 Linux を動かし、そのうえで containerd を動かしているためです(雑な図にしたものが以下です)。

+------------+
| containerd |
+------------+
|  LinuxKit  |
+------------+
|  HyperKit  |
+------------+
|   macOS    |
+------------+

Docker for Mac 環境で container のログを空にしたい場合、macOS ではなく LinuxKit 上のログファイルを空にする必要があります。

LinuxKit への接続

LinuxKit には screen でシリアル接続します。

$ screen ~/Library/Containers/com.docker.docker/Data/vms/0/tty

# Ctrl-d を入力すると、以下が出力されます(Ctrl-a + k -> y でコンソールから抜けられます)

Welcome to LinuxKit

                        ##         .
                  ## ## ##        ==
               ## ## ## ## ##    ===
           /"""""""""""""""""___/ ===
          {                       /  ===-
           ______ O           __/
                          __/
              ___________/

linuxkit-025000000001 login: root (automatic login)

Welcome to LinuxKit!

NOTE: This system is namespaced.
The namespace you are currently in may not be the root.
System services are namespaced; to access, use `ctr -n services.linuxkit ...`
login[7397]: root login on 'ttyS0'

ただ、LinuxKit 上では docker コマンドを実行できないので、macOS 上でログファイルのパスを取得します。取得後に LinuxKit 上で以下を実行すればログを空にできます。

$ :> /path/to/logfile

しかし、これを毎回実行するのは面倒ですので、shell の関数を定義しておくと良いです。

clear_docker_log() {
    local container_id="${1}"
    logfile=$(docker inspect $container_id --format "{{.LogPath}}")
    screen_name="docker_$(date +%s)"

    # LinuxKit にシリアル接続(detached screen として)
    screen -d -m -S ${screen_name} ~/Library/Containers/com.docker.docker/Data/vms/0/tty
    # ログを空にするコマンドを送信
    # 末尾の echo は Enter キー入力のエミュレート
    screen -S ${screen_name} -p 0 -X stuff $":> ${logfile}"$(echo -ne '\015')
    # シリアル接続を閉じる
    screen -S ${screen_name} -X quit
}

引数に渡した container ID のログを空にできます。 docker-compose を使っている場合は docker-compose ps -q CONTAINER_NAME の結果を渡すような関数を用意しておくと良さそうです。

参考

comment

Comments

arrow_back

Previous

ethOS入門 自宅で暗号通貨マイニング書評

Next

メンテナンス作業手順の書き方
arrow_forward