最近、dockerイメージ管理スイートharborの高可用性とハードgcに取り組んでいて、dockerイメージ管理について理解を深めています。 Docker registryは公式のイメージ管理サービスで、harborもそれに依存しているので、dockerイメージの管理と理解を少し整理しました。
docker build
Dockerイメージの構築から始めます。
ドッカーファイル
FROM alpine:3.7
ADD venv.tg /venv.tg
ビルド
$ docker build -f Dockerfile -t alpine-build-test:2020-07-28 . --no-cache
Sending build context to Docker daemon 18.29MB
Step 1/2 : FROM hub.guazi-cloud.com/library/alpine:3.7
---> 6d1ef012b567
Step 2/2 : ADD venv.tg /venv.tg
---> c02816e88c1b
Successfully built c02816e88c1b
Successfully tagged alpine-build-test:2020-07-28
ビルドを見る
# イメージの履歴を見る
$ docker history alpine-build-test:2020-07-28 --no-trunc
IMAGE CREATED CREATED BY SIZE COMMENT
sha256:c02816e88c1bdf4528dcfccec58edc2373d3c3b95c15f98ef208f2229ecae0a8 2 minutes ago /bin/sh -c #(nop) ADD file:0b7e80d8489683c5c7f8f07cdba46a2c085cbd571ac23f2bfddfa808415da214 in /venv.tg 44.9MB
sha256:6d1ef012b5674ad8a127ecfa9b5e6f5178d171b90ee462846974177fd9bdd39f 17 months ago /bin/sh -c #(nop) CMD ["/bin/sh"] 0B
<missing> 17 months ago /bin/sh -c #(nop) ADD file:aa17928040e31624cad9c7ed19ac277c5402c4b9ba39f834250affca40c4046e in / 4.21MB
# docker images inspect info
$ docker image inspect alpine-build-test:2020-07-28
[
{
"Id": "sha256:c02816e88c1bdf4528dcfccec58edc2373d3c3b95c15f98ef208f2229ecae0a8",
"RepoTags": [
"alpine-build-test:2020-07-28"
],
"RepoDigests": [],
"Parent": "sha256:6d1ef012b5674ad8a127ecfa9b5e6f5178d171b90ee462846974177fd9bdd39f",
"Comment": "",
"Created": "2020-08-05T13:37:09.821307Z",
"Container": "",
"ContainerConfig": {
"Hostname": "",
"Domainname": "",
"User": "",
"AttachStdin": false,
"AttachStdout": false,
"AttachStderr": false,
"Tty": false,
"OpenStdin": false,
"StdinOnce": false,
"Env": [
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
],
"Cmd": [
"/bin/sh",
"-c",
"#(nop) ADD file:0b7e80d8489683c5c7f8f07cdba46a2c085cbd571ac23f2bfddfa808415da214 in /venv.tg "
],
"ArgsEscaped": true,
"Image": "sha256:6d1ef012b5674ad8a127ecfa9b5e6f5178d171b90ee462846974177fd9bdd39f",
"Volumes": null,
"WorkingDir": "",
"Entrypoint": null,
"OnBuild": null,
"Labels": null
},
"DockerVersion": "",
"Author": "",
"Config": {
"Hostname": "",
"Domainname": "",
"User": "",
"AttachStdin": false,
"AttachStdout": false,
"AttachStderr": false,
"Tty": false,
"OpenStdin": false,
"StdinOnce": false,
"Env": [
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
],
"Cmd": [
"/bin/sh"
],
"ArgsEscaped": true,
"Image": "sha256:6d1ef012b5674ad8a127ecfa9b5e6f5178d171b90ee462846974177fd9bdd39f",
"Volumes": null,
"WorkingDir": "",
"Entrypoint": null,
"OnBuild": null,
"Labels": null
},
"Architecture": "amd64",
"Os": "linux",
"Size": 49077843,
"VirtualSize": 49077843,
"GraphDriver": {
"Data": {
"LowerDir": "/var/lib/docker/overlay2/f2700a34d68f3dba52fc7e07580d295cf87b8a45a6ea46d24895e79a5a00875a/diff",
"MergedDir": "/var/lib/docker/overlay2/6596ea2712ea2d96b0f4eb0159de9657a0fbbee996d0881bd38514b9f7e7260a/merged",
"UpperDir": "/var/lib/docker/overlay2/6596ea2712ea2d96b0f4eb0159de9657a0fbbee996d0881bd38514b9f7e7260a/diff",
"WorkDir": "/var/lib/docker/overlay2/6596ea2712ea2d96b0f4eb0159de9657a0fbbee996d0881bd38514b9f7e7260a/work"
},
"Name": "overlay2"
},
"RootFS": {
"Type": "layers",
"Layers": [
"sha256:3fc64803ca2de7279269048fe2b8b3c73d4536448c87c32375b2639ac168a48b",
"sha256:6f8d036b97086be616fee7f45b5e6d41f7fdd05ee0c358208b2669dbda5f05ec"
]
},
"Metadata": {
"LastTagTime": "2020-08-05T13:37:10.4280472Z"
}
}
]
Imageのレイヤー、設定、履歴を管理するdockerレジストリについてはどうですか?
Docker registry manage image
Dockerイメージは主に3つのセクションに分かれています。
- マニフェスト:メイン記述ファイルで、イメージ管理レイヤー、ファイルレイヤーの設定を記述します。
- config : 設定記述ファイル。イマージュの設定、スタートアップコマンド、履歴、および一連の設定情報が記述されています。
- レイヤー:実ファイルの圧縮レイヤー。
マニフェストファイルの内容:
{
"schemaVersion": 2,
"mediaType": "application/vnd.docker.distribution.manifest.v2+json",
"config": {
"mediaType": "application/vnd.docker.container.image.v1+json",
"size": 2862,
"digest": "sha256:dda1f455646c10d58dcc05d9f7a893b2e785967652a3417dc95f46004f1d0b24"
},
"layers": [
{
"mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",
"size": 28058333,
"digest": "sha256:26687f18c250ea259f4c3adc62b2d2421b204078146daf592a6cb6149fff12e7"
},
{
"mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",
"size": 24047030,
"digest": "sha256:3db37b8c8581bc315682a25f04ad0f272e50cd8a2a22c2eb212c5f09437f41cb"
}
]
}
設定ファイルの内容
{
"architecture": "amd64",
"config": {
"Hostname": "",
"Domainname": "",
"User": "",
"AttachStdin": false,
"AttachStdout": false,
"AttachStderr": false,
"Tty": false,
"OpenStdin": false,
"StdinOnce": false,
"Env": [
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
],
"Cmd": [
"/bin/sh"
],
"ArgsEscaped": true,
"Image": "sha256:534c86f7312dbbab3a8f724cc87fa82f0770ec171659112c975315a7a6166a94",
"Volumes": null,
"WorkingDir": "",
"Entrypoint": null,
"OnBuild": null,
"Labels": null
},
"container": "953e5de88d11a4e81e21b1c7c1957519b8ff21e6e638981f21ea5ef845e308c4",
"container_config": {
"Hostname": "953e5de88d11",
"Domainname": "",
"User": "",
"AttachStdin": false,
"AttachStdout": false,
"AttachStderr": false,
"Tty": false,
"OpenStdin": false,
"StdinOnce": false,
"Env": [
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
],
"Cmd": [
"/bin/sh",
"-c",
"#(nop) ",
"CMD ["/bin/sh"]"
],
"ArgsEscaped": true,
"Image": "sha256:534c86f7312dbbab3a8f724cc87fa82f0770ec171659112c975315a7a6166a94",
"Volumes": null,
"WorkingDir": "",
"Entrypoint": null,
"OnBuild": null,
"Labels": {}
},
"created": "2019-03-07T22:19:53.447205048Z",
"docker_version": "-ce",
"history": [
{
"created": "2019-03-07T22:19:53.313789681Z",
"created_by": "/bin/sh -c #(nop) ADD file:aa17928040e31624cad9c7ed19ac277c5402c4b9ba39f834250affca40c4046e in / "
},
{
"created": "2019-03-07T22:19:53.447205048Z",
"created_by": "/bin/sh -c #(nop) CMD ["/bin/sh"]",
"empty_layer": true
}
],
"os": "linux",
"rootfs": {
"type": "layers",
"diff_ids": [
"sha256:3fc64803ca2de7279269048fe2b8b3c73d4536448c87c32375b2639ac168a48b"
]
}
}
ファイル管理
まず、全体的なデータ保存構造を見てみましょう。
.
ドッカー
レジストリ
v2
ブロブ
│ └──sha256
│ ├── 3d
│ │ └── 3dd72560ec4ecc993af6324c93c93fa12fc2a817cd89193854805f0967f4617f
│ │ └── data
│ ├── 48
│ │ └── 48e8f8b4d1d5b3fc320aa546e65a8cbf91ff6bcfbcbb3604ade41ee8c9fc65f8
│ │ └── data
│ ├── 52
│ │ └── 52179b638f890fdd03b83484b534daccfd9c9d9ea61b3e518ef899971b05892e
│ │ └── data
│ ├── 5d
│ │ └── 5d20c808ce198565ff70b3ed23a991dd49afac45dece63474b27ce6ed036adc6
│ │ └── data
│ ├── 6d
│ │ └── 6d1ef012b5674ad8a127ecfa9b5e6f5178d171b90ee462846974177fd9bdd39f
│ │ └── data
│ ├── 92
│ │ └── 92251458088c638061cda8fd8b403b76d661a4dc6b7ee71b6affcf1872557b2b
│ │ └── data
│ └── a3
│ └── a3ed95caeb02ffe68cdd9fd84406680ae93d633cb16422d00e8a7c22955b46d4
│ └── data
リポジトリ
ライブラリ
│ └── alpine
│ ├── _layers
│ │ └── sha256
│ │ ├── 5d20c808ce198565ff70b3ed23a991dd49afac45dece63474b27ce6ed036adc6
│ │ │ リンク
│ │ └── 6d1ef012b5674ad8a127ecfa9b5e6f5178d171b90ee462846974177fd9bdd39f
│ │ └── link
│ └── _manifests
│ ├── revisions
│ │ └── sha256
│ │ └── 92251458088c638061cda8fd8b403b76d661a4dc6b7ee71b6affcf1872557b2b
│ │ └── link
│ └── tags
│ └── 3.7
│ ├── current
│ │ └── link
│ └── index
│ └── sha256
│ └── 92251458088c638061cda8fd8b403b76d661a4dc6b7ee71b6affcf1872557b2b
│ └── link
└── zhaolong
アプリ・テスト
│ ├── _layers
│ │ └── sha256
│ │ ├── 265345b84d5c4a25b900ca94d0b19a3f0c11271e56ca354c80eb45637d5e09d2
│ │ │ └── link
│ │ ├── 5d20c808ce198565ff70b3ed23a991dd49afac45dece63474b27ce6ed036adc6
│ │ │ └── link
│ │ ├── 8c70b080af60d13c3e04212132c17a7a52ca81166c7c48088dbfee16c9815f56
│ │ │ └── link
│ │ ├── a3ed95caeb02ffe68cdd9fd84406680ae93d633cb16422d00e8a7c22955b46d4
│ │ │ └── link
│ │ ├── a67c4c15aee645045dc03fe9595a04b04167687ab8d6db0f1f547e68ea04f304
│ │ │ └── link
│ │ └── afbd3a0eed148d332d9809dd274dd9213a1baccffe9fa8b9836b20ff2ae108b2
│ │ └── link
│ └── _manifests
│ ├── revisions
│ │ └── sha256
│ │ └── 440d59188c7bb022b89225df3f0ce2aa5f0bd1eec0c2a54f555e38ddc1ecc975
│ │ └── link
│ └── tags
│ └── 2020-07-27-1
│ ├── current
│ │ └── link
│ └── index
│ └── sha256
│ └── 440d59188c7bb022b89225df3f0ce2aa5f0bd1eec0c2a54f555e38ddc1ecc975
│ └── link
ビルド・テスト
└── _layers
└── sha256
├── 48e8f8b4d1d5b3fc320aa546e65a8cbf91ff6bcfbcbb3604ade41ee8c9fc65f8
│ └── link
├── 52179b638f890fdd03b83484b534daccfd9c9d9ea61b3e518ef899971b05892e
│ └── link
└── 5d20c808ce198565ff70b3ed23a991dd49afac45dece63474b27ce6ed036adc6
└── link
ファイルツリーの構造から明らかなように、メインディレクトリは以下の2つに分かれています。
- blobs: マニフェスト、コンフィグ、レイヤーアーカイブなど、レイヤーの実際のコンテンツを格納します。
- repositories: docker イメージのリポジトリパスとタグを形成するサブディレクトリ構造を維持します。
blobは単純にsha256の最初の2桁から作られたサブディレクトリで、そのディレクトリにファイルが置かれ、最終的なファイル名はdataになります。
リポジトリはデータを保存せず、リンクのみを保存し、例えばサブディレクトリ構造を維持することで、完全なリポジトリパス+タグを形成します:
イメージ名 : xxxxxxxxxx.com/library/alpine:3.7 レジストリパス: repositories/library/alpine/_manifests/tag/3.7
repositories/library/alpine/_manifests/tag/3.7/current/linkイメージのメインフェストファイルは、ハッシュ265のblobレイヤーにあります。
系列関係
まとめ
dockerレジストリの設計はまだ非常に微妙で、複雑な設計はなく、ファイルの内容を一元的に保存することで、同じレイヤーのイメージで、データの重複保存を避けるために、レイヤーがすでに存在するかどうかを直接調べることができます。レポパス+タグはファイルディレクトリで管理されるので、シンプルで分かりやすいです。





