天天看點

蘋果 M1 上使用 Podman 替換 Docker Desktop

随着近幾年微服務的興起,加上雲原生的蓬勃發展,大家已經對 Docker 不在陌生。Docker Desktop 是一個可以讓大家在非 Linux 系統上,使用 Docker 進行開發調試的工具,非常容易上手,安裝也非常簡單。在蘋果 m1 晶片出來後,Docker Desktop 第一時間釋出了 beta 版本,也在前一段時間更新成了正式版。但是使用過程中還是有一些問題,例如運作一些 x86 的鏡像會出錯。最近 Docker 公司改變了收費模式,雖然說是不影響個人/小企業開發者,但誰叫咱是大公司,還是要看看替代方案的。

Podman 是一個 RedHat 公司釋出的開源容器管理工具,初衷就是 docker 的替代品,在使用上與 Docker 的相似,但又有着很大的不同。它與 Docker 的最大差別是架構。Docker 是以 C/S 架構運作的,我們平時使用的 <code>docker</code> 指令是隻一個指令行前端,它需要調用 dockerd 來完成實際的操作,而 dockerd 預設是一個有 root 權限的守護程序。Podman 不需要守護程序,直接通過 fork/exec 的形式啟動容器,不需要 root 權限。

關于 Docker 和 Podman 的比較,可以進一步檢視:

podman 2.0 改進與systemd的內建

為什Podman值得一試

Podmain rootless 的缺點

在 mac 上使用 homebrew 安裝 Podman 非常簡單。同 Docker Desktop 一樣,在 mac 上 podman 也需要虛拟機才能運作容器。podman 使用 qemu 建立 Linux 的虛拟機,是以需要一并安裝,指令如下。由于國内網絡問題,要有足夠的耐心。

對于 m1 的晶片,目前 qemu 正式版本還沒有支援蘋果的 Hypervisor.framework 功能,如果想要 hvf 來加速虛拟機運作,就需要編譯帶 patch 的 qemu 版本。當然也可以用别人做好的,如下指令

安裝好了這兩個工具後,需要先初始化虛拟機,才能繼續使用。因為要下載下傳 coreos 的鏡像,又是漫長的等待。

初始化完成後,還需要打開虛拟機

關于虛拟機還有如下指令

如果啟動沒有報錯,那麼就可以使用 podman 替代 docker 指令了,下列常用的指令都可以運作。還可以通過 <code>alias docker=podman</code> 指令無縫替換。

在使用的過程中碰到兩個詭異的問題

<code>podman machine init</code> 執行失敗,列印 <code>Error: exit status 1</code> 。如果忽略它,podman machine start 時會報如下日志

查了一番之後發現,在初始化虛拟機的時候,用到了dd指令。這個指令蘋果版的和gnu版的實作不一緻,蘋果版的bs參數隻接收小寫機關,而gnu版的隻接收大寫的機關。而我用的是 gnu 版本的,是以執行到這裡一定會錯。随把它從 PATH 中移出去,問題就解決了。

運作 <code>podman run nginx</code> 報錯 <code>Error: short-name resolution enforced but cannot prompt without a TTY</code>

這個錯誤看起來很奇怪,得先了解什麼 short-name 才能了解。它指的是鏡像的名字,鏡像名字前沒有域名的就是短名字。docker 碰到這種情況會在前面加上 docker.io/ ,但是 podman 沒有這個操作。據說是因為安全原因,避免拉錯鏡像,是以給它做了二次确認的功能,但是因為使用的控制台不支援,是以沒有展示出來,直接失敗了。這個功能還可以修改配置檔案控制是否開啟。

但是奇怪的是,執行 centos 不會有這樣的提示,執行 nginx 就會報錯。這是因為 podman 對一些系統級的鏡像有特殊對待,它維護了一個鏡像名到鏡像倉庫的對應關系。詳見:

鏡像的短名稱

收集鏡像短名稱的倉庫

從 docker 遷移到 Podman

<code>podman run -p</code> 不能暴露端口

這是 podman 轉發端口端口的 bug,預計 v3.3.2 會修複。

有一個 workaround 的辦法是,在執行的時候加上<code>--network bridge</code> 。例如:

https://github.com/containers/podman/issues/11396

還有個辦法是修改配置檔案,檔案路徑是<code>~/.config/containers/containers.conf</code>,在<code>[containers]</code> 内加上<code>rootless_networking = "cni"</code>。

在 M1 上體驗 podman 的過程不夠平順,還沒有覆寫全部功能就已經碰到不少問題。除了本身 bug 不少外,它使用的 Coreos 鏡像還是 beta 版,也存在不穩定的可能性。但是,Podman 的代碼比較規整,能比較快的閱讀并定位問題,社群對問題的修複速度也很快。背後還有紅帽這樣的大公司支撐,還是很有希望達到一個穩定狀态。

關于運作速度,感覺很贊,沒有完全虛拟機的笨重感。

Podman 相對于 docker 還多了一些的功能,比如 pod 功能,還需要進一步深度體驗。%