目錄

關於容器倉庫的那些事

隨著使用容器(Container)技術也有一段時間了,多數人在初次接觸 Container 時,應該都會嘗試執行 docker pull docker.io/library/centos 這類指令。那麼 docker.io/library/centos 背後到底有什麼玄機?今天想分享一下關於容器倉庫(Container Repository/Registry)的觀念與結構。本文將以 podmanskopeo 為主要操作工具進行說明。

/2025/03/20250321-container-repos/container-repos.png

Q&A

Q1: 一般來說,正常的下載路徑長怎樣?

通用標準格式如下:

1
<HOSTNAME>/<NAMESPACE>/<IMAGE>:<TAG>
  • Hostname:例如 https://docker.iohttps://registry.redhat.io 或私有的 http://quay.misc.internal,需符合 RFC 3986 - URI 標準 且使用 httphttps
  • Namespace:也稱 project、organization,用來分類資源。在 Docker Hub 中,若省略,預設會使用 library
  • Image:要使用的映像檔名稱。
  • Tag:版本標籤,若省略,預設為 latest

也可以使用 <HOSTNAME>/<IMAGE>:<TAG> 的簡寫格式,但建議避免,維持一致性較佳。

Q2: 遠端與地端的 Namespace 與 Image name 必須一致嗎?

不必一致,以下是常見情境:

1. 同倉庫不同 Namespace 可共用 Image 名稱

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
# 測試範例
# Local 1: quay.misc.internal/library/centos:latest
# Local 2: quay.misc.internal/golden/centos:latest

# 複製
skopeo copy docker://quay.misc.internal/library/centos:latest docker://quay.misc.internal/golden/centos:latest

# 比對
skopeo inspect docker://quay.misc.internal/library/centos:latest
skopeo inspect docker://quay.misc.internal/golden/centos:latest

這兩個 Image 內容完全相同,只是 Namespace 不一樣。這種方式可用於不同用途的隔離或測試。

2. 不同倉庫中,可以有相同的 Namespace 與 Image 名稱

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
# 測試範例
# Remote: docker.io/library/centos:latest
# Local: quay.misc.internal/library/centos:latest

# 複製
skopeo copy docker://docker.io/library/centos:latest docker://quay.misc.internal/library/centos:latest

# 比對
skopeo inspect docker://docker.io/library/centos:latest
skopeo inspect docker://quay.misc.internal/library/centos:latest

這用於地端同步遠端映像,也常見於 Dev/Stage/Prod 環境的鏡像隔離。

Q3: 映像檔標籤命名慣例有哪些?

根據 Tagging images - OpenShift Container Platform 4.2 的建議,建議遵循 語意化版本 Semantic Versioning 2.0.0 或使用時間戳記 ISO 8601 - Data and time format 來管理標籤

描述範例
語意化版本myimage:v2.0.1
語意化版本 + 架構myimage:v2.0-x86_64
語意化版本 + 基礎鏡像myimage:v1.2-centos7
ISO 8601(完整時間)myimage:202002011200
ISO 8601(日期)myimage:20200201
穩定版myimage:stable
最新(不穩定)myimage:latest
環境標籤myimage:prod / myimage:test

Q4: 關於 latest 有什麼誤解?

引用 What’s Wrong With The Docker :latest Tag? 的說明, latest 有幾個常見誤解:

  1. :latest 只是個普通的標籤,不具特殊意義
  2. :latest 不會自動更新,它的指向是靜態的,必須手動更新
  3. :latest 很容易被覆蓋,可能造成部署錯誤 (Latest is Easily Overwritten By Default)
  4. :latest 沒有描述性,不適合在生產環境使用 (Latest is Not Descriptive and Hard to Work With)

實際案例:在 2019 年中,centos:latest 原本指向 CentOS 7,但某天被上游改為指向 CentOS 8,造成許多使用 latest 的使用者部署錯誤。

建議:在 Dockerfile/Containerfile 中務必明確指定版本號,避免產生環境差異與維運困難。

Q5: 有建議的命名方式嗎?

穩定版使用 stable 標籤。

正式版本使用語意化版本號(例如 v1.3.2)。

開發過程或頻繁釋出情境,建議使用 ISO 8601 格式(例如 20240321),可確保唯一性並保有可讀性。

範例: _/alpine 使用時間為 tag,即是一種良好實踐。

Q6: 所以 latest 應該要完全禁止使用嗎?

不需要完全禁止,但需慎用。當你未指定標籤時,大多數工具預設會拉取 :latest

1
2
# 測試看看 current :latest 指向哪一個版本?
skopeo inspect docker://docker.io/library/centos | jq ".RepoTags"

實務上,不建議依賴 latest 來進行部署。CI/CD 流程若使用 latest,容易造成版本不一致,建議搭配明確版本號與 immutable 設定,才能確保穩定性。

結語

latest 是最容易被誤解的標籤之一,若使用不當,容易造成部署錯誤、版本不一致等問題。建議開發者在撰寫 Dockerfile 或設定 CI/CD pipeline 時,避免使用 latest 作為唯一依賴的標籤。

此外,建立一致的命名規則、理解 Container Registry 的路徑結構與標籤策略,也是確保映像檔穩定與可維護性的關鍵。

延伸閱讀: Docker中latest标签引发的困惑 ,提供更多中文討論案例,可供參考

References