容器化技術的發展日新月異,Docker 長期以來一直是容器領域的領頭羊。然而,新興的 Podman 以其獨特的架構和功能,正逐漸成為 Docker 的有力競爭者。Podman 不僅提供與 Docker 相似的使用者經驗,更具備無 Daemon 架構、原生 Pod 管理以及與 Kubernetes 和 Systemd 的深度整合等優勢。這些特性使得 Podman 在安全性、效能和可擴充套件性方面都有著顯著的提升,也讓它成為容器技術領域的一顆新星。本文將深入比較 Docker 與 Podman 的差異,剖析 Podman 的核心優勢,並提供實際操作範例,協助讀者瞭解如何從 Docker 平滑遷移至 Podman。
在早期,從 Docker 轉換到 Podman 非常容易,只需設定 alias docker=podman 即可沿用大部分 Docker 指令。這主要歸功於 Podman 對 OCI 標準的相容性,讓使用者能直接使用現有的 Docker 映象。然而,Podman 並非單純的 Docker 替代品,它更著重於 Pod 的管理,這也是其名稱的由來。Pod 作為 Kubernetes 中最小的佈署單元,Podman 能夠直接操作 Pod,簡化了容器在 Kubernetes 環境中的佈署和管理。相較之下,Docker 需要透過複雜的網路設定才能模擬 Pod 的功能。此外,Podman 提供了 podman generate kube 和 podman generate systemd 等指令,方便使用者將容器快速佈署到 Kubernetes 或以 Systemd 服務的形式執行,展現了其與現代化基礎設施的良好整合能力。例如,OpenStack 已將 Podman 作為預設容器引擎,透過 systemd 管理所有容器化服務,證明瞭 Podman 在生產環境中的實用性和可靠性。
Docker 採用 Daemon 架構,所有容器操作都需透過 Daemon 進行,這可能造成單點故障,與 Daemon 本身也存在安全風險。而 Podman 則採用無 Daemon 的 fork/exec 模型,直接與底層容器執行時互動,提升了系統的穩定性和安全性。雖然架構不同,但 Podman 的 CLI 與 Docker 高度相似,使用者幾乎可以無縫切換。這也降低了 Docker 使用者遷移到 Podman 的學習成本。
玄貓(BlackCat)觀察:Podman 如何挑戰 Docker 的容器霸主地位?
容器技術近年來蓬勃發展,Docker 無疑是其中最耀眼的明星。然而,隨著容器技術的演進,Podman 作為一個強力的競爭者,正逐漸嶄露頭角。究竟 Podman 有何獨特之處,足以挑戰 Docker 的地位?本文將探討 Docker 與 Podman 的差異,助您瞭解這兩大容器引擎的優劣。
從 Docker 到 Podman:平滑轉移的可能性?
在 Podman 剛推出時,曾有說法指出,現有的 Docker 指令稿只需透過簡單的別名設定(alias docker=podman)即可順利執行。甚至有人建立了一個套件,將一個假的 Docker 指令放置在 /usr/bin 目錄下,實際上卻指向 Podman 的二進位檔案。因此,對於 Docker 使用者而言,一旦準備就緒,轉移到 Podman 的過程預期會相當平滑。
更重要的是,Docker 建立的映象與 OCI 標準相容,這意味著您可以輕鬆遷移或重新提取先前在 Docker 中使用的任何映象。
Podman 的獨特優勢:Pod、Kubernetes 與 Systemd 的整合
深入研究 Podman 的指令選項後,您會發現它具備一些 Docker 所沒有的額外指令,同時也缺少一些 Docker 的指令。
例如,Podman 除了可以管理容器之外,還可以管理 Pod(這也是 Podman 這個名稱的由來)。Pod 的概念源自 Kubernetes,代表 Kubernetes 叢集中最小的執行單元。
透過 Podman,使用者可以輕鬆建立空的 Pod,然後使用以下指令在其中執行容器:
$ podman pod create --name mypod
$ podman run --pod mypod -d docker.io/library/nginx
在 Docker 中,要實作類別似的功能並不容易,使用者必須先執行一個容器,然後建立新的容器並將其連線到第一個容器的網路名稱空間。
Podman 還具備其他功能,可以協助使用者將容器遷移到 Kubernetes 環境中。透過 podman generate kube 指令,Podman 可以為正在執行的容器建立一個 Kubernetes YAML 檔案,該檔案可用於在 Kubernetes 叢集中建立一個 Pod。
使用 podman generate systemd 指令,可以輕鬆地將容器作為 systemd 服務執行。該指令接受一個正在執行的容器或 Pod,並生成一個 systemd 單元檔案,該檔案可用於在系統啟動時自動執行服務。
一個值得注意的例子是:OpenStack 專案,一個開源雲端運算基礎設施,採用 Podman 作為其容器化服務的預設管理器,這些服務透過 TripleO 佈署。所有服務都由 Podman 執行,並由 control plane 和計算節點中的 systemd 進行協調。
玄貓(BlackCat)分析:Docker 的 Daemon 中心化 vs. Podman 的 Fork/Exec
在 Docker 環境中執行容器,如前所述,需要使用 Docker 命令列客戶端與 Docker Daemon 進行通訊,Docker Daemon 將執行使容器啟動並執行的所需操作。為了總結本章中解釋的概念,我們可以看一下下圖:
(此處應插入 Docker 簡化架構圖)
Podman 則直接與映象倉函式庫、儲存體以及 Linux 核心互動,透過容器執行時行程(而不是 Daemon),並使用 Conmon 作為 Podman 和 OCI 執行時之間執行的監控行程,如下圖所示:
(此處應插入 Podman 簡化架構圖)
這兩種架構的核心差異在於 Docker 的 Daemon 中心化願景與 Podman 的 Fork/Exec 方法。
為何 Podman 如此吸引人?
Docker 的 Daemon 架構一直備受爭議,許多 Docker 使用者對此感到擔憂,原因如下:
- Daemon 可能是單點故障。
- 如果發生故障,則會產生孤立行程。
- Daemon 擁有所有正在執行的容器作為子行程。
儘管存在架構差異,並且有上述的別名解決方案可以輕鬆遷移專案而無需更改任何指令稿,但對於最終使用者而言,使用 Docker 或 Podman 從命令列執行容器幾乎是相同的:
$ docker run -d --rm docker.io/library/nginx
$ podman run -d --rm docker.io/library/nginx
因此,CLI 指令的大多數命令列引數都已盡可能地與 Docker 中的原始版本保持一致。
延伸閱讀
如需更多關於本章涵蓋主題的訊息,您可以參考以下內容:
- https://developers.redhat.com/blog/2020/09/25/rootless-containers-with-podman-the-basics
- https://developers.redhat.com/blog/2020/11/19/transitioning-from-docker-to-podman
- https://github.com/opencontainers/runc/blob/master/docs/cgroup-v2.md
- https://www.redhat.com/sysadmin/introduction-crun
- https://ebpf.io/what-is-ebpf/
執行您的第一個容器
在之前的章節中,我們討論了容器的歷史、它們的採用以及促成它們傳播的各種技術,同時還研究了 Docker 和 Podman 之間的主要差異。
現在,是時候開始使用真實的例子了:在本章中,我們將學習如何在您喜歡的 Linux 作業系統上啟動並執行 Podman,以便我們可以啟動我們的第一個容器。我們將探索各種安裝方法、所有先決條件,然後啟動一個容器。
在本章中,我們將介紹以下主要主題:
- 選擇作業系統和安裝方法
- 準備您的環境
- 執行您的第一個容器