ラベル Docker の投稿を表示しています。 すべての投稿を表示
ラベル Docker の投稿を表示しています。 すべての投稿を表示

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" とか

2014-01-26

Dockerを使ってみる(2)-操作ひと通り

前回のエントリでDebian GNU Linux/jessieのDockerコンテナが出来上がってるので、それをいじりまわす感じで。
# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
utimukat55/debian   jessie              583d969ed337        4 minutes ago       153.3 MB
dockerのインストールが終わっていると、ホスト側にdocker0というNICが追加されますが、どうもここをルーティングする形でゲストから外に通信をするようです。
ルーティング設定と反映のコマンドを実行します。
/etc/sysctlの以下の行をアンコメント。
net.ipv4.ip_forward=1
以下のコマンドを実行して即時有効化
# sysctl -p
net.ipv4.ip_forward = 1

とりあえず起動する
docker images実行結果のIMAGE IDをイメージに指定、シェルを起動するよう引数に指定してコマンドを実行。
# docker run -t -i 583d969ed337 /bin/bash
root@ed7307934a79:/#
 今の状態だとifconfigもないなど色々扱いづらい(個人的に)なので、必要なパッケージを入れます。
# apt-get install net-tools openssh-server vim
vimを入れたので、/etc/apt/sources.listを必要であれば書き換えてミラーを変更します(USになっているので)

commitする!
起動しているbashを抜けると保存されずに終了してしまうので、別のターミナルを開いて、以下のコマンドを実行します。
# docker ps -a
CONTAINER ID        IMAGE                      COMMAND             CREATED             STATUS              PORTS               NAMES
ed7307934a79        utimukat55/debian:jessie   /bin/bash           23 minutes ago      Up 23 minutes                           lonely_euclid
 CONTAINER IDを引数に指定してcommitします。-mでコミットログも付けれるみたいですが未確認。
# docker commit ed7307934a79 utimukat55/debian:jessie
f86c3830f454c1ed1e217b86f09c47df41e2ed1bed22038813b478d1514283cc
commitが終わったら実行してた方を閉じます。exitでいいみたいです(Ctrl-dでも抜けれますがステータスが130になって正常終了じゃないみたいです。詳細不明)

色々と未整理なこと
コンテナを起動して終了すると、状態を記録した?ファイルが増えていきます。確認は以下のコマンドで可能です。
# docker ps -a
CONTAINER ID        IMAGE                      COMMAND             CREATED             STATUS              PORTS               NAMES
b12d2c3979c6        utimukat55/debian:jessie   /bin/bash           19 seconds ago      Exit 130                                boring_albattani  
84883288b0e9        utimukat55/debian:jessie   /bin/bash           About an hour ago   Exit 0                                  insane_shockley  
449810a25bd0        utimukat55/debian:jessie   /bin/bash           About an hour ago   Exit 0                                  grave_darwin        
この中から必要のないものがある場合、docker rmコマンドで削除可能です。引数はCONTAINER IDを指定します。
# docker rm b12d2c3979c6
いろんなコンテナを使っている場合、コンテナの一覧は以下のコマンドで確認できます。(既に出てきていますが)
# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
utimukat55/debian   jessie              583d969ed337        23 minutes ago      153.3 MB
base                latest              b750fe79269d        10 months ago       175.3 MB
base                ubuntu-12.10        b750fe79269d        10 months ago       175.3 MB
base                ubuntu-quantal      b750fe79269d        10 months ago       175.3 MB
base                ubuntu-quantl       b750fe79269d        10 months ago       175.3 MB
必要のないコンテナを削除する場合、docker rmiコマンドを使います。引数はIMAGE IDを指定します。
# docker rmi b750fe79269d
まだまだわかってない事のほうが遥かに多いですがとりあえずここまで。

ここまでやったイメージ
セントラルリポジトリ?にアップロードしました。
使う場合は以下のコマンドでどうぞ。
# docker pull  utimukat55/docker_jessie

Dockerを使ってみる(1)-導入

Dockerとは
いわゆる仮想化ソリューションですが、OSごと仮想化するような感じではなく、カーネル等は共通のものを使いながらユーザーランドを分離するSolarisコンテナみたいなもののようです。今回はいつもどおりDebian GNU/Linux(amd64)で導入します。今のところamd64でしか動作しないようです(Raspberry PIに移植してる人はいるみたいなので将来的にはアーキテクチャ非依存になるかもしれません)。

パッケージの導入
公式サイト[1]を参考にしつつ例によってsudo使わないのでこんな感じ。パッケージ自体はUbuntu用のものがそのまま使えています。
# wget -qO- https://get.docker.io/gpg | apt-key add -  
OK
# echo deb http://get.docker.io/ubuntu docker main > /etc/apt/sources.list.d/docker.list
# apt-get update
# apt-get install lxc-docker
よくわからなかったのでとりあえずデフォルトのまま。パッケージのインストールはこれで完了。

自前でイメージを作成
Dockerのイメージとして公式のもの[2]もありますが、今回はtesting(今はjessie)のイメージを作りたかったので、自分で作ることにします。Debianの場合はシェルが用意されています。docker searchコマンドで所望のイメージが見つかる場合はこの手順は必要ありません。

https://github.com/dotcloud/docker-debian/blob/master/contrib/mkimage-debian.sh

Rawを右クリックしてリンク先保存。ターミナルでダウンロードしてきた場所に移動して
$ chmod +x mkimage-debian.sh
$ su
# ./mkimage-debian.sh utimukat55/debian jessie
問題なく終われば、
# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
utimukat55/debian   jessie              583d969ed337        4 minutes ago       153.3 MB
みたいな感じでイメージができているはず。このエントリはここまで。

[1] http://docs.docker.io/en/latest/installation/ubuntulinux/
[2] https://index.docker.io/popular Officialと書かれているものは多分安全