Created on 2018-05-08
Modified on 2019-02-26
Published on 2018-05-10
この資料で解説しているDockerのバージョンは、Docker v18.03.1-ce (moby/moby@05c751b1be6785b4f8a42c412e858508b137c10e)です。
cgroup
とchroot
を使う。Merge component 'engine' from
から始まるmerge commitを探す。Upstream-commit:
から始まる行を探す。もっといい方法が知りたい。
コンテナ管理システムの実装の1つ。 Dockerのcore部分をコンポーネント化をするmoby projectが進められている。 ソフトウェアの名称はdockerだけど、ソースコードはmoby projectをベースにしたものが使われている。
deprecatedなchannelを除けば、3つのchannelが存在する。
広義の意味では、ホストから隔離されたプロセスの実行環境のこと。 コンテナの種類は下記の通り。
隔離されるリソースの例:
so0kさんが書いた図: https://github.com/docker-saigon/blog-hugo/blob/9a36cb4df96f7e036405a0dd384c40b0df6ac4aa/static/img/event_state.png
Docker Image Specification v1.2.0 に準拠したtarballのこと。
一般にDocker Imageと呼ばれるのは2種類ある。
1つは /var/lib/docker/image/*/
の下に
展開された状態のDocker Image のことである。
docker image ls
を実行されたときに表示されるのがこれに相当する。
この状態のDocker Imageの扱われ方は、使用するStorage Driver (Graph
Driverとも呼ぶ)によって異なる。 詳細はStorage
Driverの項目で解説する。
もう1つは、 データフォーマットとしてのDocker Image
である。
docker image export
したときに出力されるのが、これに相当する。
本項で解説するのは、データフォーマットしてのDocker Imageを解説する。
root filesystemへ加えられた変更のまとまり。 具体的には、ファイル・ディレクトリの追加・更新・削除や、属性の変更などが記録される。 メタデータは含まない。
./repositories
./manifest.json
./${IMAGE_ID}.json
./${LAYER_ID}/layer.tar
./${LAYER_ID}/json
./${LAYER_ID}/VERSION
repositories
: Docker Imageにつけられたtagmanifest.json
:
コンテナイメージの構成と、レイヤーの一覧を提供する。${IMAGE_ID}.json
: Image JSONと呼ばれている。 多分Docker
EngineがDocker
Imageを管理するときにしよする構造体の内容をダンプしたもの。${LAYER_ID}/layer.tar
: layer.tarを参照。${LAYER_ID}/json
: Image
Layerのメタデータ。下位互換のためだけにある。${LAYER_ID}/VERSION
$ tar tf ${LAYER_ID}/layer.tar
root/
root/new_file
root/new_empty_directory/
root/.wh.deleted_file
root/.wh.deleted_directory
tarは、ファイルの格納順序は任意である。 そのため、同じdirectory treeを記録しているのに、出力されたtarballのhash値が異なるという問題が発生しうる。
Dockerでは、格納順序をファイル名順にする(tar --sort=name
に相当)ことでこの問題を回避している
[0]
[1]
[2]
/var/lib/docker/volumes/metadata.db
volumeMetadata
構造体参考: Docker Engine API and SDKs
/var/lib/docker/image/
の下に展開された、レイヤーを管理する。graphdriver.Driver
インターフェースを実装している。Docker v18.03.1-ce の時点で使えそうなドライバの一覧。 ドキュメントに乗ってないドライバーがありますね。
$ ag 'graphdriver\.Register'
daemon/graphdriver/aufs/aufs.go
67: graphdriver.Register("aufs", Init)
daemon/graphdriver/btrfs/btrfs.go
41: graphdriver.Register("btrfs", Init)
daemon/graphdriver/devmapper/driver.go
25: graphdriver.Register("devicemapper", Init)
daemon/graphdriver/overlay/overlay.go
109: graphdriver.Register("overlay", Init)
daemon/graphdriver/overlay2/overlay.go
116: graphdriver.Register(driverName, Init)
daemon/graphdriver/vfs/driver.go
23: graphdriver.Register("vfs", Init)
daemon/graphdriver/windows/windows.go
57: graphdriver.Register("windowsfilter", InitFilter)
daemon/graphdriver/zfs/zfs.go
32: graphdriver.Register("zfs", Init)
daemon/graphdriver/lcow/lcow.go
85: graphdriver.Register("lcow", InitDriver)
Storage Driverではない。
DirCopy()
を提供するだけのパッケージ。
DirCopy()
は、タイムスタンプや属性を含めディレクトリ全体をコピーする関数。
cp -a
コマンドに相当する動作をするはず。
これを使用しているStorage
Driverは、overlay
とvfs
。
% ag github.com/docker/docker/daemon/graphdriver/copy
daemon/graphdriver/overlay/overlay.go
17: "github.com/docker/docker/daemon/graphdriver/copy"
daemon/graphdriver/vfs/copy_linux.go
3:import "github.com/docker/docker/daemon/graphdriver/copy"
daemon/graphdriver/copy/copy.go
3:package copy // import "github.com/docker/docker/daemon/graphdriver/copy"
daemon/graphdriver/copy/copy_test.go
3:package copy // import "github.com/docker/docker/daemon/graphdriver/copy"
いつの間にか非推薦になってた [1]。
overlay2
を使おう。
/var/lib/docker/image/overlay2/
/var/lib/docker/overlay2/
/var/lib/docker/overlay2/
以下のディレクトリ構造
./${LAYER_CACHE_ID}/diff/
./${LAYER_CACHE_ID}/work/ (optional)
./${LAYER_CACHE_ID}/link (optional)
./${LAYER_CACHE_ID}/lower
./${LAYER_CACHE_ID}/merged/ (optional)
./l/${LINK_ID} (symlink to "../${LAYER_CACHE_ID}/diff" directory)
upperdir
オプションに指定。workdir
オプションに指定する。lowerdir
オプションに指定する文字列を作成。操作
Overlayfsは、mount optionに少なくともlowerdir, upperdir, workdirを指定する必要がある。 https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/filesystems/overlayfs.txt
union file systemではない。 新しいレイヤを作るときに、親レイヤーの中身を全てコピーしてくるため、実用的なパフォーマンスは出せないと思う。 commit済みのファイルへ多数の変更を加える用途で、コンテナの起動終了が少ないなら、こういうドライバでもいいかもしれない。
ドキュメントにも書いてある通り、テスト目的で使用されている。
$ ag github.com/docker/docker/daemon/graphdriver/vfs --ignore-dir daemon/graphdriver/vfs
daemon/graphdriver/register/register_vfs.go
5: _ "github.com/docker/docker/daemon/graphdriver/vfs"
integration-cli/docker_cli_external_graphdriver_unix_test.go
16: "github.com/docker/docker/daemon/graphdriver/vfs"
layer/layer_test.go
15: "github.com/docker/docker/daemon/graphdriver/vfs"
Graph-driver for Linux Containers On Windows (LCOW) [1]
Windows分からん(´・ω・`)
github.com/docker/docker/daemon/logger
パッケージに実装されている。
Docker Engine Managed Plugin Systemは、Docker Engineが稼働中にpluginの追加・削除を自由に行うことができるシステムのこと。 dockerの本体に手を加えずに、機能を追加できる!
Pluginの開発には、go-plugins-helpersを使うと良さそう。
# Image/Layer/Graphdriver関連
image.Store
image.FSStoreBackend
layer.Store
layer.roLayer
layer.RWLayer
layer.MetadataStore
daemon.graphdriver.New
# networkやcontainer関連
container/container.go
daemon/container_operations.go
daemon/network/
daemon/network.go