從零碎觀念回到一句話#

走完前面五節之後,可以嘗試用一句話回答「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 時的預設行為:EntrypointCmdEnvWorkingDirUserExposedPortsVolumesLabels
  • 內含 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 storelayer SHA256
Image configregistry blob / 本地 image storeimage id(config SHA256)
Manifestregistryimage digest(manifest SHA256)
Tagregistry / 本地可變的字串,指向某個 manifest
Container 寫入host 上的 UpperDir不屬於 image,container 刪除即消失

延伸閱讀#