Skopeo 在容器映像檔管理方面提供許多優於傳統 Docker CLI 的優勢。它不需要 Docker daemon 就能運作,可以直接與儲存函式庫互動,減少了額外的步驟和資源消耗。此外,Skopeo 的 inspect 命令允許檢查映像檔的細節而無需下載整個映像檔,對於快速確認映像檔資訊非常有用。同步功能則簡化了在不同儲存函式庫之間搬移映像檔的流程,尤其適用於維護本地映象或在斷網環境中佈署。這些特性使得 Skopeo 成為管理容器映像檔的利器,提升了效率並簡化了工作流程。

管理容器映像檔與 Skopeo

Skopeo 是一個強大的工具,用於管理容器映像檔,包括複製、檢查和同步映像檔等操作。以下將詳細介紹如何使用 Skopeo 來管理容器映像檔。

從遠端登入檔提取映像檔到本地 OCI 相容儲存

使用 Skopeo 的 copy 命令,可以將映像檔從遠端登入檔提取到本地 OCI 相容儲存。以下是一個例子:

$ skopeo copy \
--authfile ${HOME}/.docker/config.json \
docker://docker.io/library/nginx:latest \
oci:/tmp/nginx

該命令將從 Docker Hub 提取最新的 NGINX 映像檔,並將其儲存到 /tmp/nginx 目錄中。該目錄將符合 OCI 映像檔規範,具有以下結構:

$ tree /tmp/nginx
/tmp/nginx/
├─ blobs
│ └─sha256
│ ├──21e0df283cd68384e5e8dff7e6be1774c86ea3110c1b1e932[...]
│ ├──44be98c0fab60b6cef9887dbad59e69139cab789304964a19[...]
│ ├──77700c52c9695053293be96f9cbcf42c91c5e097daa382933[...]
│ ├──81d15e9a49818539edb3116c72fbad1df1241088116a7363a[...]
│ ├──881ff011f1c9c14982afc6e95ae70c25e38809843bb7d42ab[...]
│ ├──d86da3a6c06fb46bc76d6dc7b591e87a73cb456c990d814fd[...]
│ ├──e5ae68f740265288a4888db98d2999a638fdcb6d725f42767[...]
│ └──ed835de16acd8f5821cf3f3ef77a66922510ee6349730d89a[...]
├─ index.json
└─ oci-layout

blobs/sha256 目錄中的檔案包含映像檔的 manifest(JSON 格式)和映像檔層(壓縮的 tarball)。

值得注意的是,Podman 可以無縫地從符合 OCI 映像檔規範的本地目錄中執行容器。以下是一個例子:

$ podman run -d oci:/tmp/nginx

該命令將從 /tmp/nginx 目錄中執行 NGINX 容器。

檢查遠端映像檔

使用 Skopeo 的 inspect 命令,可以在不下載映像檔的情況下檢查遠端映像檔的組態、標籤和後設資料。以下是一個例子:

$ skopeo inspect docker://docker.io/library/nginx

該命令將輸出一個 JSON 格式的結果,包含以下欄位:

  • Name:映像檔儲存函式庫的名稱。
  • Digest:計算出的 SHA256 摘要。
  • RepoTags:儲存函式庫中可用的映像檔標籤列表。
  • Created:儲存函式庫或映像檔的建立日期。
  • DockerVersion:用於建立映像檔的 Docker 版本。
  • Labels:在建立映像檔時套用的額外標籤。
  • Architecture:映像檔所針對的系統架構。
  • Os:映像檔所針對的作業系統。
  • Layers:組成映像檔的層列表,以及它們的 SHA256 摘要。
  • Env:在建立映像檔時定義的額外環境變數。

同步登入檔和本地目錄

使用 Skopeo 的 sync 命令,可以在不同登入檔和本地儲存之間同步映像檔。以下是一個例子:

$ skopeo sync \
--src docker --dest dir \
registry.example.com/lab/busybox /tmp/images

該命令將從 registry.example.com/lab/busybox 儲存函式庫中提取所有標籤,並將其儲存到 /tmp/images 目錄中。

Skopeo 支援不同的傳輸型別,包括 dockerdiryaml。可以使用 --scoped 選項來保留原始映像檔路徑。

詳細解說

使用 Skopeo 的優點

Skopeo 提供了一個靈活且強大的方式來管理容器映像檔。它允許使用者在不同登入檔和本地儲存之間複製、檢查和同步映像檔。

Skopeo 的應用場景

Skopeo 可以用於多種場景,包括:

  • 在斷開連線的環境中同步儲存函式庫。
  • 在不同的登入檔之間遷移映像檔。
  • 在本地儲存中備份映像檔。
Skopeo 的未來發展

Skopeo 是一個活躍的開源專案,持續發展和改進中。未來可能會增加更多的功能和特性,以滿足不斷變化的容器化需求。

使用Skopeo管理容器映像

Skopeo是一個強大的工具,用於管理容器映像,包括同步映像到容器註冊中心、刪除映像等操作。以下將詳細介紹Skopeo的使用方法和相關技術細節。

同步映像到容器註冊中心

Skopeo提供了skopeo sync命令,用於將映像從一個註冊中心同步到另一個註冊中心或本地目錄。這個命令在斷網環境中尤其有用,可以用來建立本地註冊中心的映象。

基本用法

$ skopeo sync --src docker --dest dir docker.io/library/busybox:latest /tmp/images

上述命令將docker.io/library/busybox:latest映像同步到/tmp/images目錄。

同步多個映像

如果需要同步多個映像或整個倉函式庫,可以在源引數中指定倉函式庫名稱或使用YAML檔案定義源。

$ skopeo sync --src docker --dest docker --dest-tls-verify=false registry.access.redhat.com/ubi8 mirror-registry.example.com

上述命令將registry.access.redhat.com/ubi8倉函式庫中的所有映像同步到mirror-registry.example.com註冊中心。

使用YAML檔案定義源

對於更複雜的同步需求,可以使用YAML檔案來定義源。

docker.io:
  tls-verify: true
  images:
    alpine: []
    nginx:
      - "latest"
  images-by-tag-regex:
    httpd: ^2\.4\.[0-9]*-alpine$
quay.io:
  tls-verify: true
  images:
    fedora/fedora:
      - latest
registry.access.redhat.com:
  tls-verify: true
  images:
    ubi8:
      - "8.4"
      - "8.5"
$ skopeo sync --src yaml --dest dir --scoped example_sync.yaml /tmp/images

上述命令根據example_sync.yaml檔案中的定義,將相關映像同步到/tmp/images目錄。

刪除映像

Skopeo還提供了skopeo delete命令,用於刪除遠端註冊中心中的映像。

基本用法

$ skopeo delete docker://mirror-registry.example.com:5000/foo:bar

上述命令將刪除mirror-registry.example.com:5000註冊中心中的foo:bar映像。

技術細節

Docker Registry v2協定支援遠端刪除映像,Skopeo利用這一特性提供了簡單易用的刪除功能。底層上,這涉及到向註冊中心傳送HTTP DELETE請求。

$ curl -v --silent \
-H "Accept: application/vnd.docker.distribution.manifest.v2+json" \
-X DELETE http://127.0.0.1:5000/v2/<name>/manifests/sha256:<image_tag_digest>

內容解密:

  1. curl命令:用於傳送HTTP請求到註冊中心。
  2. -H引數:指定HTTP頭部,接受Docker Distribution Manifest V2格式的回應。
  3. -X DELETE:指定HTTP請求方法為DELETE,用於刪除指定的映像。
  4. http://127.0.0.1:5000/v2//manifests/sha256:<image_tag_digest>:註冊中心的API端點,用於刪除指定的映像Manifest。

執行本地容器登入檔

大多數企業和組織採用企業級登入檔,以依賴安全和彈性的解決方案來儲存容器映像。大部分企業登入檔還提供諸如根據角色的存取控制(RBAC)、映像漏洞掃描、映象、地理複製和高用性等進階功能,成為生產和關鍵任務環境中的預設選擇。

然而,有時執行一個簡單的本地登入檔是非常有用的,例如在開發環境或培訓實驗室中。本地登入檔在斷開連線的環境中也很有幫助,可以映象主要的公共或私有登入檔。

本文旨在說明如何執行一個簡單的本地登入檔以及如何應用基本組態設定。

執行容器化的登入檔

與其他應用程式一樣,本地登入檔可以由管理員安裝在主機上。或者,一種常見的首選方法是將註冊表本身執行在容器內。

最常用的容器化登入檔解決方案是根據官方的 Docker Registry 2.0 映像,它提供了基本登入檔所需的所有功能,並且非常易於使用。

組態本地登入檔

執行本地登入檔(無論是否容器化)時,我們必須定義一個目標目錄來存放所有映像層和後設資料。下面的範例展示了容器化登入檔的首次執行,其中建立了 /var/lib/registry 資料夾並進行繫結掛載以儲存映像資料:

# mkdir /var/lib/registry
# podman run -d \
  --name local_registry \
  -p 5000:5000 \
  -v /var/lib/registry:/var/lib/registry:z \
  --restart=always registry:2

登入檔將在主機地址上的 5000/tcp 連線埠上可存取,這也是該服務的預設連線埠。如果我們在本地工作站上執行登入檔,它將在 localhost:5000 上可存取,並使用分配的 IP 地址或其完全合格的網域名稱(FQDN)向外部連線公開,如果工作站/筆記型電腦由本地 DNS 服務解析。

例如,如果主機具有 IP 地址 10.10.2.30 和 FQDN registry.example.com,並且正確地由 DNS 查詢解析,則登入檔服務將在 10.10.2.30:5000registry.example.com:5000 上可存取。

重點注意事項

如果主機執行本地防火牆服務或位於企業防火牆後面,請不要忘記開啟正確的連線埠以向外部公開登入檔。

建置並推播測試映像

我們可以嘗試建置並推播一個測試映像到新的登入檔。下面的 Containerfile 建置了一個根據 UBI 的基本 httpd 伺服器:

FROM registry.access.redhat.com/ubi8:latest
RUN dnf install -y httpd && dnf clean all -y
COPY index.html /var/www/html
RUN dnf install -y git && dnf clean all -y
CMD ["/usr/sbin/httpd", "-DFOREGROUND"]

內容解密:

  1. FROM registry.access.redhat.com/ubi8:latest:使用 Red Hat Universal Base Image 8 作為基礎映像。
  2. RUN dnf install -y httpd && dnf clean all -y:安裝 httpd 伺服器並清除 dnf 快取。
  3. COPY index.html /var/www/html:將 index.html 複製到 httpd 的預設檔案根目錄。
  4. RUN dnf install -y git && dnf clean all -y:安裝 git 版本控制系統並清除 dnf 快取。
  5. CMD ["/usr/sbin/httpd", "-DFOREGROUND"]:設定 httpd 伺服器以前台模式執行。

我們可以使用 Buildah 建置新的映像:

$ buildah build -t minimal_httpd .

要將映像推播到本地登入檔,我們可以使用 Podman 或其配套工具 Buildah 或 Skopeo。Skopeo 在這種情況下非常方便,因為我們甚至不需要將映像名稱限定為登入檔名稱。

下面的命令展示瞭如何將新的映像推播到登入檔:

$ skopeo copy --dest-tls-verify=false \
  containers-storage:localhost/minimal_httpd \
  docker://localhost:5000/minimal_httpd

內容解密:

  1. skopeo copy:使用 Skopeo 將映像從一個位置複製到另一個位置。
  2. --dest-tls-verify=false:由於本地登入檔預設提供 HTTP 傳輸,因此需要停用 TLS 驗證。
  3. containers-storage:localhost/minimal_httpd:來源映像的位置,使用 containers-storage 傳輸。
  4. docker://localhost:5000/minimal_httpd:目標映像的位置,使用 docker 傳輸並指定本地登入檔的 URL。

儘管實作簡單,但預設的登入檔組態有一些限制,需要解決。為了說明其中一個限制,讓我們嘗試刪除剛剛上傳的映像:

$ skopeo delete \
  --tls-verify=false \
  docker://localhost:5000/minimal_httpd

結果出現 HTTP 405 錯誤訊息,表明登入檔不允許刪除映像。要改變這種行為,我們需要編輯登入檔的組態。

自訂登入檔組態

登入檔組態檔案 /etc/docker/registry/config.yml 可以被修改以改變其行為。該檔案的預設內容如下:

version: 0.1
log:
  fields:
    service: registry
storage:
  cache:
    blobdescriptor: inmemory
  filesystem:
    rootdirectory: /var/lib/registry
http:
  addr: :5000
  headers:
    X-Content-Type-Options: [nosniff]
health:
  storagedriver:
    enabled: true
    interval: 10s
    threshold: 3

我們很快意識到,這是一個非常基本的組態,沒有身份驗證,不允許刪除映像,也沒有 TLS 加密。我們的自訂版本將嘗試解決這些限制。

重點注意事項

有關登入檔組態的完整檔案有廣泛的選項,由於超出本文範圍,因此未在此提及。更多組態選項可以在以下連結找到:https://docs.docker.com/registry/configuration/。

下面的檔案包含修改後的登入檔 config.yml 版本:

version: 0.1
log:
  fields:
    service: registry
storage:
  cache:
    blobdescriptor: inmemory
  filesystem:
    rootdirectory: /var/lib/registry
  delete:
    enabled: true

內容解密:

  1. version: 0.1:指定組態檔案的版本。
  2. log.fields.service: registry:設定日誌記錄的服務名稱為 “registry”。
  3. storage.cache.blobdescriptor: inmemory:將 blob 描述符快取在記憶體中。
  4. storage.filesystem.rootdirectory: /var/lib/registry:設定儲存映像層和後設資料的根目錄。
  5. storage.delete.enabled: true:啟用刪除映像的功能。