こんにちは、hanhan1978です。この記事はイノベーター・ジャパンAdvent Calendar 2017の6日目の記事です。
コンテナ仮想化が話題ですが、そもそもコンテナって何なのか気になりませんか?
自分は、抽象化された技術をそのまま見過ごして使い続けるのがすごく苦手で、夜も眠れなくなってしまいます...。
というわけで、今回はDockerのコンテナを中身を見てみることで、コンテナについての理解を深めましょう。
Dockerのすごく簡単なおさらい。
Dockerでは、Dockerfile
というコンテナの設計図を使ってコンテナイメージを作成します。
Dockerfile
の一行目には、 From
という命令を使って、元になるコンテナイメージを指定します。
例えば、library/alpine - Docker Hub などは、Docker界隈では非常に有名な軽量Linuxです。
Dockerfile に FROM alipine:latest
と記述するとAlpine Linuxをベースイメージとしたコンテナを作成できます。
でも...?
Alpine Linuxは何を元にして出来ているんだろう?遡っていくと一番の元になっているイメージは何なんだろう?
Create a base image | Docker Documentation
Dockerの仕様書に記載がありますが、scratch
がDockerの最小単位のベースイメージです。
具体的には、何も含まれていない空のコンテナイメージです。
ここからは、実際に scratch
が空なのか?一体コンテナの中身はどうなっているのか?見ていきましょう。
最小限のDockerfile
仕様書には、FROM
を省略できそうな記載があるのですが、検証していると細々とエラーが出るので FROM scratch
を明示します。
最小限のコマンドとして、MAINTAINER
(このDockerfileを管理している人) と、touch blank
で予め作成しておいた空ファイルの追加を記述します。
FROM scratch MAINTAINER hanhan1978 ADD blank /blank
ビルドします。
$ docker build -t test . Sending build context to Docker daemon 37.89kB Step 1/3 : FROM scratch ---> Step 2/3 : MAINTAINER hanhan1978 ---> Using cache ---> ecd2a0489df2 Step 3/3 : ADD blank /blank ---> 6e68d787dc83 Successfully built 6e68d787dc83 Successfully tagged test:latest
イメージのサイズを確認します。
$ docker images test REPOSITORY TAG IMAGE ID CREATED SIZE test latest 37c8c1eadb08 2 seconds ago 0B
空のベースイメージに、空のファイルを追加したコンテナイメージのサイズは、なんと0B
です。
では、コンテナの中身を見てみましょう。 docker save [タグ名]
でコンテナイメージを出力することができます。
$ docker save test > test_image.tar
作成された tarを展開すると、こんなディレクトリ構造になっています。
. ├── 6e68d787dc831bc532a20bd8bdb9fb505a77dc431a14774bba086f24ae13b0eb.json ├── c9aff52f8c22a263c44363c6abb8665b2224a26cf778c5c15da4a4cd746b5eeb │ ├── VERSION │ ├── json │ └── layer.tar ├── manifest.json └── repositories
殆どがDocker用のmeta情報なのですが、layer.tar
というファイルがあります。ここにblank
ファイルが入っています。
実際に展開してみましょう。
$ tar xvf layer.tar x blank
blank
ファイルが出てきました。
つまり、まとめると….
Dockerのコンテナイメージの中身は
- Dockerのmeta情報
- 自分が追加したコマンド分のイメージレイヤー(tar)
イメージレイヤーは、Dockerfile
にコマンドを追加すると、上記の layer.tar
が含まれたディレクトリが追加されていきます。
├── VERSION ├── json └── layer.tar
コンテナのサイズは何で決まるのか?
中身が分かると、コンテナのサイズがどのように決まるのかが分かりますね。 つまり、容量の大きいファイルをコンテナに入れればコンテナのサイズは大きくなるし、逆であれば小さくなります。
当たり前のことですが、具体的に中身をみることですごくイメージが掴めやすいですね。 試しに大きいファイルを作ってコンテナに追加してみましょう。
100MBのダミーファイル作成
dd if=/dev/zero of=largefile bs=1M count=100
単純にコンテナイメージに追加します。
FROM scratch MAINTAINER hanhan1978 ADD largefile /
ビルドします。
$ docker build -t test . Sending build context to Docker daemon 104.9MB Step 1/3 : FROM scratch ---> Step 2/3 : MAINTAINER hanhan1978 ---> Using cache ---> ecd2a0489df2 Step 3/3 : ADD tempfile / ---> 999824e3e166 Successfully built 999824e3e166 Successfully tagged test:latest
イメージサイズを確認します。
$ docker images test REPOSITORY TAG IMAGE ID CREATED SIZE test latest 999824e3e166 4 seconds ago 105MB
100MBのファイルを追加したら、コンテナのイメージもほぼ100MBになりました。
まとめ
今日は、コンテナの基本ということで、Dockerイメージの中身を具体的に見てみました。
コンテナのイメージサイズが大きいと、pushやpullする際のデータ転送量が大きくなります。コンテナの中身についての基本的な構造を頭に入れた上で、できるだけ小さいイメージを作れると、ネットワークインフラに優しいコンテナイメージになるかと思います。
基本を抑えたら、色んなベースイメージをpullして中身を確認してみて下さい、すごく勉強になりますよ!百聞は一見にしかずです。
明日のアドベントカレンダー担当は、当社マーケティングファームのykkozwさんです。お楽しみに!