2014-02-27

docker exportとdocker importでdockerイメージのサイズを小さくする

Dockerって何かやってくとどんどんディスク圧迫するよね・・・
Dockerは素晴らしいソリューションだし、失敗しても削除すればいいという側面から手軽に使えるのが特に今までの仮想化ソリューションになかったという点が素晴らしいと思う。
でも。でもね。ファイルシステムのレイヤーをどんどん積み上げていくから、ディスクをどんどん圧迫する。

AUFSの仕組みをざっと解説する
幸か不幸か、ずーっと前に仕事でUnionFSを使ったことがあって、一方でDockerで使ってるAUFSは「Another UnionFS」。UnionFSを改良することを目的としたプロダクト。ということで、仕組みは同じだろう。ということで、色々すっ飛ばして実際間違ってる可能性もありますが、UnionFSで使われるオーバーレイと言われる仕組みを説明してみたいと思います。

図内ではベースになるファイルのレイヤーに対して、3つオーバーレイ[1]しているイメージ。一番下のレイヤーは普通にマウントできるファイルシステムで、そこに対して重ねていくような感じでマウントしていくと、ユーザが参照する時には積み重なったところからファイルシステムが見える。これが大雑把なUnionFS(AUFSも同じはず。。)の仕組みです。

実際Dockerのイメージはどうなっているか
AUFSを使っているという触れ込みのDockerですが、作業をしてくとどうなるか。
拙作のDockerイメージを使って確認しようと思います。
Dockerが使える環境で
# docker pull  utimukat55/jessie_20140213
2/13時点のDebian GNU/Linux jessieのDockerイメージです。これは単純に作ったイメージなので、
# docker images
REPOSITORY                   TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
utimukat55/jessie_20140213   latest              f17806c7b448        12 days ago         464.5 MB
utimukat55/docker_jessie     latest              e07ab3ea414f        4 weeks ago         267.8 MB
464MB!でかい!
んでもって、積み上げられているはずの差分はどこにあるか。
# docker info
Containers: 0
Images: 5
Driver: aufs
 Root Dir: /var/lib/docker/aufs
 Dirs: 5
WARNING: No memory limit support
WARNING: No swap limit support
Root Dirの下のdiff、/var/lib/docker/aufs/diff/に格納されています。
/var/lib/docker/aufs/diff/
├── 583d969ed337b16b3db6f2e5f7a6583df32ed25d5b03dc0de25e636897b51f15
│   ├── bin
│   ├── boot
│   ├── dev
│   ├── etc
│   ├── home
│   ├── lib
│   ├── lib64
│   ├── media
│   ├── mnt
│   ├── opt
│   ├── proc
│   ├── root
│   ├── run
│   ├── sbin
│   ├── srv
│   ├── sys
│   ├── tmp
│   ├── usr
│   └── var
├── e07ab3ea414f60ee7a8405289e27fa9caa6a5322f2bd4866c28d319b67c9f7de
├── f17806c7b4480783b9c0ddfe08d6c3521f373a93c352657b3903db418adac42d
│   ├── bin
│   ├── dev
│   ├── etc
│   ├── lib
│   ├── sbin
│   ├── usr
│   └── var
├── f4396103dc987caeef469f759dd147cb1bd4761786aa9672108b189a2b19e02e
│   ├── dev
│   ├── tmp
│   └── var
└── f86c3830f454c1ed1e217b86f09c47df41e2ed1bed22038813b478d1514283cc
    ├── bin
    ├── etc
    ├── lib
    ├── run
    ├── sbin
    ├── tmp
    ├── usr
    └── var
でも、元のイメージとか途中のイメージとかは要らないことありますよね。という訳で

docker exportを使ってみる
dockerのリポジトリを他の場所に移動するためのコマンドとして、
  • docker export/import
  • docker save/load
が用意されているみたいです。exportを使ってみる[2]。引数はCONTAINERなので適当に1回コマンドを実行[3]してから
# docker export df293a377639 > shrink.tar
importで戻す。
# cat shrink.tar | docker import - jessie:shrinked
# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
jessie              shrinked            b309e7a044ee        46 seconds ago      189.4 MB
189MBまで縮んだよ!
ちなみに、save/loadは差分を差分として持ったまま持ち運ぶ時に使うみたいです。

今回のエントリは、一番上のレイヤーだけほしいなぁと思ってググっていた時に見つけた以下の書き込みがきっかけでした。


[1] 組み込みプロダクトで使う場合、不揮発性のファイルシステムの上にtmpfsみたいな揮発性のファイルシステムを重ねあわせて、電源切ると元に戻る感じにするのが多いですね。
[2] http://docs.docker.io/en/v0.5.3/commandline/command/export/
[3] docker run -t -i f17806c7b448 /bin/echo "hello" とか

0 件のコメント:

コメントを投稿