docker鏡像和container鏡像為什么不能直接共通
Docker 鏡像和 containerd 鏡像本質上格式兼容(都遵循 OCI 鏡像規范),但默認情況下 “不能互相識別”,核心原因是存儲位置、命名空間和工具鏈的隔離,而非鏡像格式本身的差異。具體來說:
一、核心原因:存儲與工具鏈的隔離
1. 鏡像存儲位置不同
Docker 和 containerd 會將鏡像存儲在各自獨立的目錄中,默認情況下不會共享存儲:
Docker:鏡像存儲在 /var/lib/docker/overlay2(或 /var/lib/docker/image),由 Docker 自身的存儲驅動(如 overlay2)管理。
containerd:鏡像存儲在 /var/lib/containerd/io.containerd.content.v1.content,由 containerd 的存儲系統管理。
即使是同一個鏡像(如 nginx:latest),Docker 拉取后會存在于 Docker 的存儲目錄,containerd 拉取后會存在于 containerd 的存儲目錄,兩者互不可見。
2. containerd 的 “命名空間” 隔離
containerd 引入了內部命名空間(namespace) 機制,用于隔離不同場景的鏡像 / 容器(類似 K8s 的命名空間,但作用于 containerd 內部):
默認情況下,Docker 鏡像對應的 containerd 命名空間是 moby(Docker 專屬)。
K8s 中使用的 containerd 命名空間是 k8s.io(K8s 專屬)。
crictl(K8s 配套的容器工具)默認只查詢 k8s.io 命名空間的鏡像,而 Docker 拉取的鏡像在 moby 命名空間,因此 crictl 看不到 Docker 鏡像。
3. 工具鏈的 “視角” 不同
Docker 和 containerd 的命令行工具(docker、crictl、nerdctl)默認只訪問自己管理的存儲和命名空間:
docker images 只會顯示 Docker 存儲目錄 + moby 命名空間的鏡像。
crictl images 只會顯示 containerd 存儲目錄 + k8s.io 命名空間的鏡像。
即使是同一個鏡像,只要不在工具默認的 “存儲 + 命名空間” 范圍內,就無法被識別。
具體操作
說明之后,實際上鏡像是可以直接識別的,問題主要是存儲路徑和命名空間的問題,我們只需要注意下這兩個問題就行,并且操作起來很簡單。
首先查看docker鏡像
docker images
把其中docker.1ms.run/tensorflow/tensorflow:1.15.5-gpu-py3這個docker鏡像改成container鏡像
先導出成tar包
sudo docker save -o tensorflow-gpu.tar docker.1ms.run/tensorflow/tensorflow:1.15.5-gpu-py3
然后使用ctr命令指定命名空間導入
sudo ctr -n k8s.io images import tensorflow-gpu.tar
導入成功后的提示
最后通過crictl查看被k8s識別到的鏡像
crictl images
這樣就完成了鏡像的使用,很簡單