Proxmox VE 9.1 開始支援 OCI(Open Container Initiative)映像建立容器,Docker Hub 上現成的應用程式映像,可以直接拉下來變成 PVE 的 LXC 容器,不用另外架 Docker。
第一次用時最常卡住的是:「Pull from OCI registry」要填的字串到底是什麼?從 Docker Hub 網頁上看到的網址,要怎麼換成 PVE 要的格式?這篇整理字串的寫法,以及官方文件裡的下載與建立方式。
先了解 OCI 映像在 PVE 的定位
依 Proxmox VE 官方文件:
- PVE 原本的容器是系統容器(System Container),像一台完整的小型 Linux
- 9.1 起加入應用程式容器(Application Container),以 OCI 映像建立,只跑特定應用程式,目前是技術預覽(technology preview)
- 從 OCI 映像建立的容器,會自動轉換成 PVE 的 LXC 架構,備份、快照、資源限制這些管理功能都一樣能用
官方也提醒,需要最高隔離性或線上移轉的情境,還是建議在 QEMU VM 裡面跑容器。
注意:應用程式容器目前是技術預覽,功能與行為之後可能會調整,正式環境導入前請先充分測試。
OCI 字串的格式
PVE 要的是標準的 OCI 映像參照(reference):
<registry>/<namespace>/<image>:<tag>
| 部分 | 說明 | 範例 |
|---|---|---|
| registry | 映像庫主機 | docker.io、ghcr.io、quay.io |
| namespace | 帳號或組織 | oxidized、library |
| image | 映像名稱 | oxidized、debian |
| tag | 版本標籤,必填 | latest、0.34.3、bookworm |
注意:PVE 的 API 定義裡,tag 是必填的,而且只接受 :tag 形式,不接受 @sha256:... 這種 digest 寫法;名稱部分必須是小寫。前面也不用加 oci:,直接從 registry 開始寫。
從 Docker Hub 網址判斷
一般使用者或組織發佈的映像
Docker Hub 的網址長這樣:
https://hub.docker.com/r/oxidized/oxidized
/r/ 後面的 帳號/名稱 就是 namespace 與 image,前面加上 docker.io,後面加上 tag:
docker.io/oxidized/oxidized:latest
要固定版本的話,到 Docker Hub 頁面的 Tags 分頁找版本號:
docker.io/oxidized/oxidized:0.34.3
Docker 官方映像
Debian、Nginx、PostgreSQL 這類官方映像,網址是 /_/ 開頭,沒有帳號:
https://hub.docker.com/_/debian
這種要補上 library 這個 namespace:
docker.io/library/debian:bookworm
這就是開頭那個例子 docker.io/library/debian 的由來,在 docker 指令裡打 debian 時,其實就是被自動展開成這個完整名稱。
其他映像庫
不在 Docker Hub 的映像,直接照該映像庫的完整名稱寫:
| 映像庫 | 範例 |
|---|---|
| GitHub Container Registry | ghcr.io/<owner>/<image>:<tag> |
| Quay | quay.io/<org>/<image>:<tag> |
| LinuxServer.io | lscr.io/linuxserver/<image>:<tag> |
判斷規則整理
| 你看到的 | 填給 PVE 的 |
|---|---|
hub.docker.com/r/aaa/bbb | docker.io/aaa/bbb:<tag> |
hub.docker.com/_/bbb | docker.io/library/bbb:<tag> |
docker pull aaa/bbb | docker.io/aaa/bbb:<tag> |
docker pull ghcr.io/aaa/bbb:1.0 | ghcr.io/aaa/bbb:1.0 |
查詢可用的 tag
不確定有哪些版本時,PVE 本身就有查詢 tag 的 API,網頁介面的拉取對話框也會用到它:
pvesh get /nodes/pve1/query-oci-repo-tags --reference docker.io/oxidized/oxidized
查詢用的參照不用加 tag,會列出這個映像庫裡的所有 tag。
下載映像
網頁介面
- 點選存放範本的儲存區(例如
local),進入「CT 範本」 - 按「Pull from OCI registry」
- 填入映像參照,例如
docker.io/oxidized/oxidized:latest,也可以先查詢 tag 再選 - 下載完成後,映像會出現在 CT 範本清單裡
指令列
官方的指令列範本工具 pveam 沒有拉取 OCI 映像的功能,網路上看到 pveam download local oci:... 這種寫法是不能用的。指令列要直接呼叫 API:
pvesh create /nodes/pve1/storage/local/oci-registry-pull \
--reference docker.io/oxidized/oxidized:0.34.3
可以用 --filename 指定存檔名稱(PVE 會再做正規化)。下載完確認檔名:
pvesm list local --content vztmpl
注意:這支 API 沒有提供帳號密碼的參數,只能拉取公開的映像。需要驗證的私有映像庫,可以先在其他主機用 skopeo 等工具把映像存成 OCI 封存檔(.tar),再透過網頁介面上傳到 CT 範本。
建立容器
映像在儲存區上之後,就和一般範本一樣,可以用網頁的「建立 CT」精靈,或用 pct create:
pct create 210 local:vztmpl/<下載的檔名>.tar \
--hostname oxidized \
--memory 1024 \
--rootfs local-lvm:8 \
--net0 name=eth0,bridge=vmbr0,ip=dhcp \
--unprivileged 1
應用程式容器多了兩個系統容器用不到的設定,建立後可以在容器的「選項」裡調整:
| 設定 | 說明 |
|---|---|
entrypoint | 容器啟動時執行的指令,預設是 /sbin/init;從 OCI 映像建立時會帶入映像本身的設定 |
env | 容器的環境變數,很多應用程式映像都靠環境變數設定參數 |
資料要放在掛載點
應用程式容器的設計是「映像可以隨時換新版」,所以設定檔與資料要放在另外的掛載點(mount point),不要只放在容器的根檔案系統裡,之後換新版映像重建容器時,資料才不會跟著不見。要放哪個路徑,請看該映像在 Docker Hub 頁面上的說明(Docker 的 volume 路徑)。
常見問題
| 狀況 | 原因 |
|---|---|
| 格式錯誤,無法送出 | 少了 tag、用了大寫,或前面多加了 oci: |
| 找不到映像 | Docker 官方映像少了 library/ |
| 拉取失敗、要求驗證 | 私有映像庫,或該映像庫限制匿名下載 |
| 容器啟動後馬上停止 | 應用程式缺少必要的環境變數,看容器的主控台輸出 |
結論
整理成一句話:Docker Hub 網址 /r/ 後面的部分,前面加 docker.io/、後面加 :tag;官方映像則是 docker.io/library/名稱:tag。下載要用網頁的「Pull from OCI registry」或 oci-registry-pull API,不是 pveam。
應用程式容器還在技術預覽階段,我目前會拿來跑一些輕量、無狀態或資料很好備份的服務,比起為了一個小服務特地開一台 VM 跑 Docker,省了不少資源。
參考資料
- Proxmox VE 文件:Proxmox Container Toolkit(OCI Images)
https://pve.proxmox.com/pve-docs/chapter-pct.html - Proxmox VE API Viewer:oci-registry-pull、query-oci-repo-tags
https://pve.proxmox.com/pve-docs/api-viewer/ - Proxmox VE Roadmap:Proxmox VE 9.1
https://pve.proxmox.com/wiki/Roadmap - Open Container Initiative:Distribution Specification
https://github.com/opencontainers/distribution-spec



