tail my trail

作るのも使うのも、結局は、人なのだ

Docker for Mac v1.13 でディスクイメージの自動圧縮に対応されたのであげておくべし

f:id:uorat:20170131164247p:plain

tl;dr

「Docker for Mac 使ってる場合のimage群の保存場所と掃除方法」というタイトルでブログに書き殴っておこうと思ったら、実は Docker for Mac v1.13 から自動圧縮に対応していたというオチ。

Docker for Mac 使いは 今すぐ v 1.13 に上げよう。

背景

Docker および Amazon ECS 素振り中の身。 数年前に 軽く触った程度であまり詳しくないけど所用でコンテナを本番運用することになりそうなので、浦島太郎状態から抜け出すべくキャッチアップしつつ、ついでに開発機のMac OS X のDocker環境を Docker Toolbox から Docker for Mac に移行していた。

ゴミが散らかっていたのでコンテナやイメージを掃除していたら、なかなか開放されず困ったちゃんだったので色々調べていた。

Where are Docker images?

通常Linux をDocker ホストに使ってる場合は、 /var/lib/docker にイメージが保存される。 けど、Docker for Mac 入れたMac OS Xに /var/lib/docker が見当たらなかったので、気になってファイル漁ってみた。 そもそも Docker コマンドってどこにあるんだろう。

$ which docker
/usr/local/bin/docker
$ ll /usr/local/bin/docker
lrwxr-xr-x  1 uorat  Users  66  1 30 17:01 /usr/local/bin/docker -> /Users/uorat/Library/Group Containers/group.com.docker/bin/docker

$HOME/Library/Group Containers にあるらしい。 $HOME/Library/Containers というディレクトリもあったので、ここを掘り下げて見てみると

$ ll -h ~/Library/Containers/com.docker.docker/Data/com.docker.driver.amd64-linux/
total 1998512
drwxr-xr-x  13 uorat  Users   442B  1 30 17:01 .
drwxr-xr-x  22 uorat  Users   748B  1 30 17:01 ..
-rw-r--r--   1 uorat  Users   976M  1 31 14:04 Docker.qcow2
-rw-r--r--   1 uorat  Users    64K  1 30 17:01 console-ring
-rw-r--r--   1 uorat  Users    64K  1 30 16:45 console-ring.0
-rw-r--r--   1 uorat  Users     3B  1 30 17:01 hypervisor.pid
-rw-r--r--   1 uorat  Users     0B  1 30 16:45 lock
drwxr-xr-x   2 uorat  Users    68B  1 30 16:45 log
-rw-r--r--   1 uorat  Users    17B  1 30 17:01 mac.0
-rw-r--r--   1 uorat  Users    36B  1 30 16:45 nic1.uuid
-rw-r--r--   1 uorat  Users     3B  1 30 17:01 pid
-rw-r--r--   1 uorat  Users    94B  1 30 17:01 syslog
lrwxr-xr-x   1 uorat  Users    12B  1 30 17:01 tty -> /dev/ttys000

更新日やファイルサイズ見る限りなんかそれっぽいのがある。 qcow2 という拡張子見る限り、QEMUのイメージファイルらしい。内部的にQEMU使ってるのか。

フォーラム漁ってみる

Dockerのフォーラム見てみると、似たようなスレッドがあってまさにこのファイルがdefault指定されていると言及されていた。

Where are images stored on Mac OS X? - Docker for Mac - Docker Forums

It depends on the driver being used, but the default is: $HOME/Library/Containers/com.docker.docker/Data/com.docker.driver.amd64-linux/Docker.qcow2

Try it

ごりごり docker rmi で不要なイメージ消してみる。 元々1GBくらいに育ってたのですっきり。

$ docker images prune
$ docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
alpine              latest              70c557e50ed6        11 months ago       4.8 MB

では、実体のファイル見てみると、

$ ll -h Docker.qcow2
-rw-r--r--  1 uorat  Users   976M  1 31 14:45 Docker.qcow2

減らないうぇーい。

Docker for Mac の仕組み

Mac OS X の xhyve 使って Linux 仮想マシン立ち上げている

QEMUファイルがあることから推察できるとおり、Docker for Mac も所詮は仮想マシン上にContainer立ち上げる仕組みのよう。 昔使ってた Docker Toolbox はVirtualBoxバックグラウンドで使って実現していたわけだけども、Docker for Mac は 内部的には xhyve という Mac OS X の Hypervisor 使って Dockerホスト用のLinux を立ち上げているらしい。

引用: The Docker Platform

DOCKER FOR MAC An integrated, easy-to-deploy environment for building, assembling, and shipping applications from a Mac, Docker for Mac is a native Mac application architected from scratch, with a native user interface and auto-update capability, deeply integrated with OS X native virtualization, Hypervisor Framework, networking and file system, making it faster and more reliable than previous ways of getting Docker on a Mac.

引用: Docker for Mac and Windows Beta: the simplest way to use Docker on your laptop - Docker Blog

Faster and more reliable: no more VirtualBox! The Docker engine is running in an Alpine Linux distribution on top of an xhyve Virtual Machine on Mac OS X or on a Hyper-V VM on Windows, and that VM is managed by the Docker application. You don’t need docker-machine to run Docker for Mac and Windows.

なので、screen tty するとLinuxに入れる。

$ cd ~/Library/Containers/com.docker.docker/Data/com.docker.driver.amd64-linux/
$ screen tty

...

 * Running system containerd ... [ ok ]
 * Running system containers ... binfmt rng-tools [ ok ]
 * Configuring host settings from database ... [ ok ]
 * Setting up proxy port service ... [ ok ]
 * Starting Docker ... [ ok ]
 * Starting chronyd ... [ ok ]
 * Checking system state ...
✓ Drive found: sda
✓ Drive mounted: /dev/sda1 on /var type ext4 (rw,relatime,data=ordered)
✓ Network connected:           inet addr:192.168.65.2  Bcast:192.168.65.7  Mask:255.255.255.248
✓ Process transfused running
✓ Process dockerd running: dockerd --pidfile=/run/docker.pid -H unix:///var/run/docker.sock --swarm-default-advertise-addr=eth0 --userland-proxy-path /usr/bin/slirp-proxy --debug --experimental --storage-driver aufs
✓ Process containerd running: docker-containerd -l unix:///var/run/docker/libcontainerd/docker-containerd.sock --metrics-interval=0 --start-timeout 2m --state-dir /var/run/docker/libcontainerd/containerd --shim docker-containerd-shim --runtime docker-runc --debug
✓ Docker daemon working: 1.13.0
✓ Diagnostics server running: /usr/bin/diagnostics-server -vsock
✓ System containerd server running: /usr/bin/containerd
✓ System containerd working
 * Starting Hyper-V daemon: hv_kvp_daemon ... [ ok ]
 * Starting Hyper-V daemon: hv_vss_daemon ... [ ok ]
 * Adjusting oom killer settings ... [ ok ]

Welcome to Moby

                        ##         .
                  ## ## ##        ==

/ # hostname
moby

/ # cat /etc/os-release
NAME="Alpine Linux"
ID=alpine
VERSION_ID=3.5.0
PRETTY_NAME="Alpine Linux v3.5"
HOME_URL="http://alpinelinux.org"
BUG_REPORT_URL="http://bugs.alpinelinux.org"

/ # (Ctl-a + D)

Mac OS XQEMUディスクイメージをリサイズする方法 (従来)

ググってみたら、まさに同じようなことを言及している記事を発見。 ここでは qemu で仮想ディスクをリサイズする方法が紹介されている。KVM触ってた頃を思い出す。

Docker for macでDocker.qcow2というファイルが肥大化する件 | GENDOSU@NET

Github Issue でも同じ案内を見つけた。DockerホストとなるLinuxサーバにログインして /var/tmpfile を0埋めした後で、Mac OS X上の Docker.qcow2 ファイルを qemu-img コマンドで convert しろというもの。

Docker.qcow2 never shrinks - disk space usage leak in docker for mac · Issue #371 · docker/for-mac

試してみたらいつの間にか勝手に圧縮されていた

結論、ブログタイトル & この見出しのような挙動をした。 一応途中までやったこと書き記しておく。

従来の圧縮方法の下準備

まずは brewqemu 入れた。

$ brew install qemu

リサイズする前に、念のため Linux仮想マシン上に無駄なファイルがないか確認。 上の記事に良いこと書いてあるので、ここにも転機させて頂く。

変換をかける前に、考慮する部分があり。通常ディスク上でファイルを削除した場合にはインデックス上で削除したという情報を管理して、実体は消えていない状態ですが、通常の場合だとそこに上書きすることになるので、容量があるという見え方になりますが、仮想ディスクはそのインデックス上では削除されているけれど、実体がある場合も、ディスク容量として消費していることになります。この削除されているけれど実体がある部分を綺麗にしてから変換をすることで、効率よくファイルを小さくする事が出来ます。

で、Docker for Mac の Preferances を変更する。これを機に自動起動 (Start Docker when you log in) を無効にしておいた。使わないのに無駄にデーモン立ち上がってるの嫌いだから使うときだけ起動するようにする。

で、Docker for Mac 再起動。

圧縮しようとしたら…

ここでddコマンドによる0埋めや、qemu-imgコマンドでリサイズかける前に、今一度 ディスクイメージのファイルサイズを測ってみたところ

$ ll -h Docker.qcow2
-rw-r--r--  1 uorat  Users   113M  1 31 15:30 Docker.qcow2

あら、減っとる。。

Docker for Mac v1.13 で qcow2 ファイルの圧縮に対応していた

2017年1月31日時点のstable版 v1.13 で対応したらしい。 上記の Github Issues を読み進めていくと、 compaction に対応する旨が言及されており、無事 v1.13 に組み込まれリリースされていた。

経緯は以下あたりから読み進めてみてほしい。

Docker.qcow2 never shrinks - disk space usage leak in docker for mac · Issue #371 · docker/for-mac

ドキュメントを探してみると、確かに記載あった。ググラビリティが低かったらしく、最初にこれを見つけられなかったのが無念。

How do I reduce the size of Docker.qcow2?: Frequently asked questions (FAQ) - Docker

以下引用する。

In Docker 1.13 there is preliminary support for “TRIM” to non-destructively free space on the host. First free space within the Docker.qcow2 by removing unneeded containers and images with the following commands:

  • docker ps -a: list all containers
  • docker image ls: list all images
  • docker system prune: (new in 1.13): deletes all stopped containers, all volumes not used by at least one container and all images without at least one referring container.

Note the Docker.qcow2 will not shrink in size immediately. In 1.13 a background cron job runs fstrim every 15 minutes. If the space needs to be reclaimed sooner, run this command: docker run –rm -it –privileged –pid=host walkerlee/nsenter -t 1 -m -u -i -n fstrim /var

厳密には即時圧縮というわけではなく、15分毎に走るcron jobで実現しているらしい。 ただ、以前の手法と比べると大きな改善だし、これで十分だと思う。

結論

Docker for Mac v1.13 に上げると幸せになれます。