從零碎觀念回到一句話#
走完前面五節之後,可以嘗試用一句話回答「Docker Image 是什麼」:
Image 是一組 read-only 的檔案系統 layer,加上一份描述「怎麼疊起來、怎麼跑」的設定,並由一個 manifest 把這些東西串成一個可被識別與分發的單位。
把這句話拆開來,就是 image 的三個核心組件:layer 集合、config、Manifest。
三個組件#
Layer 集合#
- 每個 layer 是一份 tarball,內容是「相對於下一層的檔案系統差異」
- 每個 layer 用 SHA256 識別,內容變了 SHA256 就變
- LowerDir 的順序由 manifest 指定;在 OverlayFS 中對應到 LowerDir 的串接順序
Config(image config JSON)#
- 描述 image 啟動成 container 時的預設行為:
Entrypoint、Cmd、Env、WorkingDir、User、ExposedPorts、Volumes、Labels - 內含
rootfs.diff_ids:以 SHA256 列出組成 image 的 layer 摘要 - 內含
history:每一層的成因(對應到 Dockerfile 指令) - 整份 config JSON 本身也有 SHA256,這個摘要就是
docker inspect看到的 image id
Manifest#
- 描述「這個 image 由哪一份 config + 哪些 layer」組成
- 列出每個 blob(layer 或 config)的 media type、size、digest
- 是 registry 與 client 溝通的主要文件
- multi-arch image 通常另外有一份 manifest list(或 index),下面再對應到不同平台的 manifest
Content-Addressable Storage 的全景#
Image 系統各個層級都用 SHA256 識別內容:
- 每個 layer blob:
sha256:<hex> - image config:
sha256:<hex>,這也是 image id - manifest:
sha256:<hex>,這就是 image digest(docker images --digests看到的那個)
這個設計叫作 Content-Addressable Storage:「位址 = 內容的雜湊」。性質:
- 不可變:一旦摘要算出來,內容就不能變;變了就是不同的東西
- 去重:相同內容只會儲存一份
- 可驗證:下載完之後重算 SHA256 就知道有沒有被竄改
tag(如
nginx:1.27)只是指向某個 manifest digest 的別名,會被覆蓋。在嚴格的場景(CI/CD、Kubernetes deployment)建議用 digest 鎖定 image,例如nginx@sha256:...。
OCI Image Spec:把規範從 Docker 抽出來#
早期這套格式是 Docker 自家的。隨著 container 生態擴展,業界把它標準化成 OCI (Open Container Initiative) Image Spec,讓不同 runtime(containerd、CRI-O、podman 等)能互通。
OCI Image Spec 主要規範:
- Image Manifest:描述 config + layers 的 JSON
- Image Index:跨平台 manifest 的集合(例如同時支援 amd64 / arm64)
- Image Configuration:image 的設定 JSON
- Filesystem Layers:tar + 可選 gzip 壓縮,內含 whiteout 表達刪除
Docker 從 1.10 之後的 image 格式基本上就是 OCI 相容;docker build 出來的 image 可以被 podman / containerd 直接用。registry 端也有對應的 OCI Distribution Spec,定義 push/pull API。
把 image 想成「可重現的封裝單位」#
從工程角度收斂,image 提供三個對使用者真正重要的性質:
- 可重現:同一份 image digest 在哪裡跑出來都是一樣的檔案系統 + 設定
- 可分發:透過 registry 推拉,網路上只傳缺少的 layer
- 可組合:image 之間可以共用 base layer,工作流程上可以 multi-stage build、可以 commit、可以打 tag 與 digest 鎖定
回看前面幾節:
- 01:用 pull / inspect / history 看到 image 的外貌
- 02:理解 Dockerfile 一行一層、commit 怎麼產生新 layer
- 03:UpperDir / LowerDir / MergedDir / WorkDir 把 layer 在 disk 上具體化
- 04:OverlayFS 提供聯合掛載的 kernel 機制
- 05:寫時複製 + whiteout 處理「在 read-only 上做修改與刪除」
- 06(本節):把上述機制收斂回 image 的三個組件 + OCI 標準
一張收斂表#
| 概念 | 在哪裡 | 用什麼識別 |
|---|---|---|
| Layer 內容 | registry blob / 本地 image store | layer SHA256 |
| Image config | registry blob / 本地 image store | image id(config SHA256) |
| Manifest | registry | image digest(manifest SHA256) |
| Tag | registry / 本地 | 可變的字串,指向某個 manifest |
| Container 寫入 | host 上的 UpperDir | 不屬於 image,container 刪除即消失 |
延伸閱讀#
- OCI 規範:Image Format Specification ↗
- OCI 規範:Distribution Specification ↗
- Docker 官方文件:About images, containers, and storage drivers ↗