Podman 保姆級(jí)使用教程,太頂了!

作者:華龍飛。主要負(fù)責(zé) Red Hat 產(chǎn)品與技術(shù)棧的培訓(xùn)交付,客戶主要涉及金融、通信、汽車、醫(yī)療等行業(yè)。熱愛并研究開源技術(shù),熟悉 RHEL 各版本,SuSE Linux 各版本,熱衷研究云原生與 DevOps 相關(guān)技術(shù)。曾負(fù)責(zé)多家銀行數(shù)據(jù)中心 OpenStack 平臺(tái)與 VMware 平臺(tái)集成項(xiàng)目,某銀行數(shù)據(jù)中心主機(jī)雙核異構(gòu)集成項(xiàng)目,某軟件開發(fā)中心 Linux 開放系統(tǒng)集成等。
文檔說明:
實(shí)驗(yàn)用 OS 版本: CentOS 7.9、RHEL 8.0、RHEL 8.2、Ubuntu 20.04.3 LTS 實(shí)驗(yàn)用 kernel 版本: 3.10.0-1160.41.1.el7.x86_64 4.18.0-193.el8.x86_64 5.14.0-1.el7.elrepo.x86_64 實(shí)驗(yàn)用 Podman 版本:1.6.4、3.2.3、3.3.1 實(shí)驗(yàn)用 podman-compose 版本:0.1.8 若未做特殊說明,以下示例均于 RHEL 8.2(4.18.0-193.el8.x86_64)上執(zhí)行,Podman 版本為3.2.3。該文檔中未涉及 podman 命令的基礎(chǔ)使用方法,可參閱 ??該文檔 加以熟悉。
文檔目錄:
Podman 的特性概述 Podman 版本兼容性比較 Podman 的擴(kuò)展功能 Podman 在不同 OS 版本中的安裝 Podman 的網(wǎng)絡(luò)實(shí)現(xiàn)原理(rootfull 與 rootless) Podman rootless 容器用戶映射實(shí)現(xiàn)方式 Podman 的 macvlan 網(wǎng)絡(luò)實(shí)現(xiàn) podman 與 podman-compose 使用示例 Podman 使用報(bào)錯(cuò)示例 Podman 有待測(cè)試功能 參考鏈接
Podman 的特性概述:
LXC、 LXD(Go 語言開發(fā))、systemd-nspawn均可作為 Linux 容器,但缺少容器跨主機(jī)運(yùn)行與應(yīng)用打包的能力。Docker 與 Podman 可使用容器鏡像實(shí)現(xiàn)應(yīng)用打包發(fā)布,快速且輕量。 Docker 與 Podman 都使用 runC(Go 語言開發(fā))作為底層oci-runtime。Docker 與 Podman 都支持 OCI Image Format(Go 語言開發(fā)),都能使用 DockerHub 上的容器鏡像,而 systemd-nspawn 無法使用它們的鏡像。?? Podman 使用 CNI(Go 語言開發(fā))作為 rootfull 容器網(wǎng)絡(luò)底層,實(shí)現(xiàn)比 Docker 網(wǎng)絡(luò)層略微簡(jiǎn)單但原理相同。相對(duì)于 LXD 與 systemd-nspawn,CNI 可以避免編寫大量的網(wǎng)絡(luò)規(guī)則。 ?? 為了實(shí)現(xiàn)普通用戶 rootless 容器網(wǎng)絡(luò),Podman 可以使用 slirp4netns程序,避免kernel space中的大量veth pair虛擬接口的出現(xiàn), 并且性能更好。Docker 運(yùn)行容器必須使用守護(hù)進(jìn)程且使用 root 權(quán)限,存在系統(tǒng)安全問題,而 Podman 針對(duì)此問題使用以下兩個(gè)特性加以解決,如下所示: Podman 支持無守護(hù)進(jìn)程( no-daemon)運(yùn)行容器。Podman 支持普通用戶運(yùn)行 rootless容器,即,普通用戶直接運(yùn)行容器無需提權(quán)具有 root 權(quán)限。雖然 Docker 與 Podman 的實(shí)現(xiàn)原理不同,但對(duì)于使用者而言其 CLI 十分相似,可平滑地從 Docker 過渡至 Podman。 Podman 的目標(biāo)不是容器的編排,編排可以使用更加專業(yè)的 Kubernetes、OpenShift、Rancher 等,使用 Podman 可以更輕量的運(yùn)行容器且不受 root 權(quán)限的安全問題,即便是 root 用戶也無法查看其它普通用戶空間下的容器,Podman 通過 user namespace進(jìn)行隔離。?? Podman 可使用 systemd service單元文件直接管理容器,實(shí)現(xiàn)容器服務(wù)隨系統(tǒng)啟動(dòng)而啟動(dòng)。?? Podman 里集成了 CRIU,因此 Podman 中的容器可以在單機(jī)上熱遷移。由于 Kubernetes 將從 v1.24.x版本后放棄使用dockershim接口層,容器運(yùn)行時(shí)可選擇使用Containerd或者CRI-O,兩者雖然均支持 OCI image 規(guī)范,但它們不是面向使用者或開發(fā)者直接管理容器或鏡像的工具,而 Podman 可直接面向使用者或開發(fā)者操作容器或鏡像。
Podman 版本兼容性比較:
Podman 版本、kernel 版本與 OS 版本的兼容性將直接影響普通用戶使用 rootless 容器。
如下所示,kernel 不支持 rootless 容器:

普通用戶 rootless 容器兼容性比較:
Podman 版本 OS 版本 kernel 版本 是否支持 rootless 1.6.4 CentOS 7.9 3.10.0-1160.41.1.el7.x86_64 no 1.6.4 CentOS 7.9 5.14.0-1.el7.elrepo.x86_64 yes 3.2.3 RHEL 8.0/8.2 4.18.0-193.el8.x86_64 yes ?? 注意:rootless 容器特性的支持取決于 kernel 的版本,不取決于 OS 與 Podman 的版本。
由于
user namespace特性在 kernel4.9.0之后出現(xiàn),因此升級(jí) kernel 即可解決 rootless 問題。關(guān)于 rootless 特性在 RHEL 8 中的設(shè)置,可 點(diǎn)擊此處[1] 參考 Red Hat 的官方配置說明。
Podman 的擴(kuò)展功能:
cockpit-podman軟件包作為 cockpit 插件可集成于Web UI中,實(shí)現(xiàn) Web UI 管理容器。cockpit-podman 服務(wù)安裝與啟用:
$?sudo?yum?install?-y?cockpit-podman
$?sudo?systemctl?enable?--now?cockpit.socket
$?sudo?systemctl?status?cockpit.service
#?安裝 cockpit-podman 軟件包,并啟用 cockpit 服務(wù)。
$?sudo?netstat?-tunlp?|?grep?9090
#?查看?systemd?監(jiān)聽的?9090?端口是否啟用在 Web UI 中可查看并管理 podman 容器與鏡像:


podman-compose旨在使用更輕量的方式實(shí)現(xiàn)單機(jī)容器編排,以用于替換docker-compose,這種方式將不再依賴守護(hù)進(jìn)程與 root 權(quán)限,同時(shí)可使用 rootless 容器,詳細(xì)示例見下文。podman-compose 使用
Python開發(fā),因此可直接使用pip3安裝該組件,或使用 rpm 軟件包方式安裝。由于 podman-compose 依然處于
dev階段,僅作為功能測(cè)試使用,暫未受到 GA 環(huán)境支持。
Podman 在不同 OS 版本中的安裝:
CentOS 7.x/8.x 或 RHEL 7.x/8.x 中:yum 命令使用 podman
rpm軟件包安裝$?sudo?yum?install?-y?podman-3.2.3-0.11.module_el8.4.0+942+d25aada8.x86_64
#?安裝 podman 最新版本,低版本 podman 存在較多 bug。
#?注意:
#???1.?需配置?CentOS?8?的?yum?軟件源以安裝最新版的?podman?及其依賴軟件包
#???2.?yum?安裝?podman?時(shí)也將安裝?containernetworking-plugins?軟件包?? Ubuntu 20.04.2 LTS 中:apt-get 命令使用 podman
deb軟件包安裝$?.?/etc/os-release
#?查看當(dāng)前的系統(tǒng)發(fā)行版
$?echo?"deb?https://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable/xUbuntu_${VERSION_ID}/?/"?|?sudo?tee?/etc/apt/sources.list.d/devel:kubic:libcontainers:stable.list
$?curl?-L?"https://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable/xUbuntu_${VERSION_ID}/Release.key"?|?sudo?apt-key?add?-
#?添加?podman?軟件源與?apt?公鑰
$?sudo?apt-get?update?-y
$?sudo?apt-get?upgrade?-y
#?更新系統(tǒng)軟件源并升級(jí)系統(tǒng)軟件包
$?sudo?apt-get?install?-y?podman
??Reading?package?lists...?Done
??Building?dependency?tree
??Reading?state?information...?Done
??...
??The?following?NEW?packages?will?be?installed:
????catatonit?conmon?containernetworking-plugins?containers-common?criu?crun?fuse-overlayfs?fuse3?libfuse3-3?libnet1?libprotobuf-c1
????podman?podman-machine-cni?podman-plugins
??...
#?安裝 podman 與相關(guān)的軟件包,包括 conmon、containernetworking-plugins、crun 等。安裝參考鏈接:
Podman Doc - installation[2] Easy to Install Podman on Ubuntu 20.04[3] podman from devel:kubic:libcontainers:stable project[4]
Podman 的網(wǎng)絡(luò)實(shí)現(xiàn)原理(rootfull 與 rootless):
Podman 支持的容器網(wǎng)絡(luò)模式如下所示:

root 用戶運(yùn)行 rootfull 容器網(wǎng)絡(luò)分析:
默認(rèn)情況下,rootfull 容器使用 bridge 網(wǎng)絡(luò)模式,并且在未創(chuàng)建任何容器前系統(tǒng)上不會(huì)自動(dòng)創(chuàng)建
cni-podman0網(wǎng)橋,只有創(chuàng)建容器后自動(dòng)生成。root 用戶使用全局范圍內(nèi)的 CNI 插件,podman 默認(rèn)使用
bridge、portmap插件,其配置文件如下:$?cat?/etc/cni/net.d/87-podman-bridge.conflist
{
??"cniVersion":?"0.4.0",
??"name":?"podman",
??"plugins":?[
????{
??????"type":?"bridge",
??????"bridge":?"cni-podman0",
??????"isGateway":?true,
??????"ipMasq":?true,
??????"hairpinMode":?true,
??????"ipam":?{
????????"type":?"host-local",
????????"routes":?[{?"dst":?"0.0.0.0/0"?}],
????????"ranges":?[
??????????[
????????????{
??????????????"subnet":?"10.88.0.0/16",
??????????????"gateway":?"10.88.0.1"
????????????}
??????????]
????????]
??????}
????},
????{
??????"type":?"portmap",
??????"capabilities":?{
????????"portMappings":?true
??????}
????},
????{
??????"type":?"firewall"
????},
????{
??????"type":?"tuning"
????}
??]
#?該配置文件位于?Podman?源碼?cni/87-podman-bridge.conflist
#?Podman?可調(diào)用?bridge、portmap?等?CNI?插件
$?sudo?podman?inspect??|?jq?.[0].HostConfig.NetworkMode
??"bridge"
#?root?用戶創(chuàng)建的容器網(wǎng)絡(luò)模式root 用戶創(chuàng)建具有端口映射的容器時(shí),iptables filter 表與 nat 表規(guī)則將相應(yīng)增加:
#?-----?filter?表中創(chuàng)建新容器后的新增規(guī)則?-----
*filter
-A?FORWARD?-m?comment?--comment?"CNI?firewall?plugin?rules"?-j?CNI-FORWARD
-A?CNI-FORWARD?-m?comment?--comment?"CNI?firewall?plugin?admin?overrides"?-j?CNI-ADMIN
-A?CNI-FORWARD?-d?10.88.0.3/32?-m?conntrack?--ctstate?RELATED,ESTABLISHED?-j?ACCEPT
#?新增規(guī)則:允許 3 層轉(zhuǎn)發(fā)目標(biāo)地址為 10.88.0.3 的流量(進(jìn)入容器的流量),conntrack 模塊進(jìn)行連接狀態(tài)追蹤。
#?當(dāng)容器通過?MASQUERADE?對(duì)外訪問,回包再次進(jìn)入容器宿主機(jī)時(shí)不再通過?DNAT?轉(zhuǎn)發(fā),而通過?conntrack
#?記錄的連接狀態(tài)直接轉(zhuǎn)發(fā)至該規(guī)則并通過 cni-podman0?網(wǎng)橋進(jìn)入容器。
-A?CNI-FORWARD?-s?10.88.0.3/32?-j?ACCEPT
#?新增規(guī)則:允許 3 層轉(zhuǎn)發(fā)源地址為 10.88.0.3 的流量(出容器的流量)。
#?-----?nat?表中創(chuàng)建新容器后的新增規(guī)則?-----
*nat
-A?PREROUTING?-m?addrtype?--dst-type?LOCAL?-j?CNI-HOSTPORT-DNAT
-A?POSTROUTING?-m?comment?--comment?"CNI?portfwd?requiring?masquerade"?-j?CNI-HOSTPORT-MASQ
-A?POSTROUTING?-s?10.88.0.3/32?-m?comment?--comment?"name:?\"podman\"?id:?\"2d2b3521457cb1d9b7ae6657304d05789a854e7a48916276a40da543df9aa217\""?-j?CNI-b6c5fb6c593e895d843cb5bd
#?新增規(guī)則:來自于 10.88.0.3 容器的流量轉(zhuǎn)發(fā)至 CNI-b6c5fb6c593e895d843cb5bd 鏈
-A?OUTPUT?-m?addrtype?--dst-type?LOCAL?-j?CNI-HOSTPORT-DNAT
#?啟用?CNI?后即創(chuàng)建的規(guī)則,該規(guī)則接收來自本地應(yīng)用的流量并轉(zhuǎn)發(fā)至?CNI-HOSTPORT-DNAT?鏈
-A?CNI-HOSTPORT-SETMARK?-m?comment?--comment?"CNI?portfwd?masquerade?mark"?-j?MARK?--set-xmark?0x2000/0x2000
-A?CNI-HOSTPORT-MASQ?-m?mark?--mark?0x2000/0x2000?-j?MASQUERADE
###?以下?6?條在創(chuàng)建新容器時(shí)同時(shí)創(chuàng)建
-A?CNI-HOSTPORT-DNAT?-p?tcp?-m?comment?--comment?"dnat?name:?\"podman\"?id:?\"2d2b3521457cb1d9b7ae6657304d05789a854e7a48916276a40da543df9aa217\""?-m?multiport?--dports?8843?-j?CNI-DN-b6c5fb6c593e895d843cb
#?自定義 DNAT 鏈,發(fā)送至本地 8843 端口的流量轉(zhuǎn)發(fā)至 CNI-DN-b6c5fb6c593e895d843cb 鏈。
-A?CNI-b6c5fb6c593e895d843cb5bd?-d?10.88.0.0/16?-m?comment?--comment?"name:?\"podman\"?id:?\"2d2b3521457cb1d9b7ae6657304d05789a854e7a48916276a40da543df9aa217\""?-j?ACCEPT
#?允許轉(zhuǎn)發(fā)目標(biāo)網(wǎng)段為 10.88.0.0/16 的流量(進(jìn)入容器的流量),該網(wǎng)段為容器所在的網(wǎng)絡(luò)。
-A?CNI-b6c5fb6c593e895d843cb5bd?!?-d?224.0.0.0/4?-m?comment?--comment?"name:?\"podman\"?id:?\"2d2b3521457cb1d9b7ae6657304d05789a854e7a48916276a40da543df9aa217\""?-j?MASQUERADE
#?MASQUERADE?出容器流量
-A?CNI-DN-b6c5fb6c593e895d843cb?-s?10.88.0.0/16?-p?tcp?-m?tcp?--dport?8843?-j?CNI-HOSTPORT-SETMARK
-A?CNI-DN-b6c5fb6c593e895d843cb?-s?127.0.0.1/32?-p?tcp?-m?tcp?--dport?8843?-j?CNI-HOSTPORT-SETMARK
-A?CNI-DN-b6c5fb6c593e895d843cb?-p?tcp?-m?tcp?--dport?8843?-j?DNAT?--to-destination?10.88.0.3:443
#?自定義?DNAT?鏈實(shí)現(xiàn)容器宿主機(jī)至容器的端口映射?? 示例:外部訪問容器內(nèi) Web 服務(wù)時(shí),涉及的宿主機(jī) iptables:

從外部訪問容器內(nèi) Web 服務(wù)時(shí),流量將通過 PREROUTING 鏈及自定義鏈(
CNI-HOSTPORT-DNAT、CNI-DN-xxxx、DNAT),經(jīng)由 FORWARD 鏈及自定義鏈(CNI-FORWARD)的三層轉(zhuǎn)發(fā)與cni-podman0網(wǎng)橋的二層轉(zhuǎn)發(fā)進(jìn)入容器,容器對(duì)外響應(yīng)的流量將經(jīng)過 cni-podman0 網(wǎng)橋轉(zhuǎn)發(fā),并經(jīng)過 CNI-FORWARD 鏈與 POSTROUTING 鏈及自定義鏈(CNI-HOSTPORT-MASQ)出容器宿主機(jī)。?? 示例:直接從容器內(nèi)訪問外部時(shí),返回容器的回包將直接使用 conntrack 模塊追蹤的連接狀態(tài),流量通過
CNI-FORWARD鏈的三層轉(zhuǎn)發(fā)與 cni-podman0 的二層轉(zhuǎn)發(fā)至容器中,即,回包進(jìn)入容器宿主機(jī)不再通過CNI-HOSTPORT-DNAT鏈。如下所示,相關(guān)的 DNAT 鏈無流量通過(藍(lán)框),CNI-FORWARD 鏈均有流量通過(藍(lán)框)。

?? Kubernetes 相關(guān)問題提示:
使用
iperf3工具的容器測(cè)試不同 rootfull 容器之間的網(wǎng)絡(luò)性能,如下所示:
容器或 pod 通過 cni 網(wǎng)橋橋接的方式在 Kubernetes 或 OpenShift3 中需在計(jì)算節(jié)點(diǎn)(worker node)上配置 net.bridge.bridge-nf-call-iptables與net.bridge.bridge-nf-call-iptables6內(nèi)核參數(shù),使 cni 二層網(wǎng)橋可調(diào)用 iptables 的 conntrack 模塊,以解決前后端 pod 在同一節(jié)點(diǎn)上時(shí),由于 pod 直連 cni 二層網(wǎng)橋,而二層網(wǎng)橋只實(shí)現(xiàn)二層轉(zhuǎn)發(fā),無法追蹤前后端的連接狀態(tài),造成后端 pod 向前端 pod 回包時(shí)無法處于同一連接鏈路的問題,可 點(diǎn)擊此處[5] 獲得更多幫助。使用以上內(nèi)核參數(shù)時(shí),需加載 br_netfilter內(nèi)核模塊方能生效。普通用戶運(yùn)行 rootless 容器網(wǎng)絡(luò)分析:
slirp4netns程序支持 user rootless network namespace,而非通過iptables與 CNI 實(shí)現(xiàn)。普通用戶創(chuàng)建的容器網(wǎng)絡(luò)模式為
slirp4netns(slirp4netns 軟件包實(shí)現(xiàn))。$?podman?inspect??|?jq?.[0].HostConfig.NetworkMode
??"slirp4netns"
#?普通用戶創(chuàng)建的?rootless?容器網(wǎng)絡(luò)模式每個(gè)普通用戶運(yùn)行 rootless 容器都將生成 slirp4netns 進(jìn)程用于隔離該用戶的
network namespace,以下分別使用 godev 與 hualf 用戶運(yùn)行 rootless 容器:

slirp4netns 實(shí)現(xiàn)的網(wǎng)絡(luò)模式與帶寬比較:

使用
iperf3工具的容器測(cè)試不同 rootless 容器之間的網(wǎng)絡(luò)性能,如下所示:
對(duì)比 rootfull 容器之間的網(wǎng)絡(luò)性能來看,slirp4netns 實(shí)現(xiàn)的 rootless 容器在不同的網(wǎng)絡(luò)命名空間內(nèi)的通信性能損耗較大,而 rootfull 容器之間的網(wǎng)絡(luò)性能相比前者在此次測(cè)試中高出近 5 倍。
關(guān)于 slirp4netns 更加詳細(xì)的內(nèi)容,請(qǐng)參考 Github 項(xiàng)目[6]。
Podman rootless 容器用戶映射實(shí)現(xiàn)方式:
Podman rootless 容器的實(shí)現(xiàn)核心在于解決 network namespace(NetNS) 與 user namespace(UserNS) 的問題,前文已介紹 NetNS 的實(shí)現(xiàn)方式,后文將介紹 UserNS 的實(shí)現(xiàn)方式。
若要使用 rootless 容器,需確認(rèn) OS 是否開啟 user namespace 功能:
$?sudo?sysctl?-a?|?grep?user\.max_user_namespaces
??user.max_user_namespaces?=?47494
系統(tǒng)上每創(chuàng)建一個(gè)用戶就會(huì)在
/etc/subuid與/etc/subgid中生成對(duì)應(yīng)用戶在其用戶命名空間中的映射規(guī)則,以 /etc/subuid 為例,參數(shù)以冒號(hào)分隔,每個(gè)參數(shù)含義如下所示:第一個(gè)參數(shù)(uid):用戶名稱
第二個(gè)參數(shù)(loweruid):用戶命名空間中起始的映射 uid
第三個(gè)參數(shù)(count):用戶命名空間內(nèi)部與外部可映射 uid 數(shù)量(可理解為所有容器普通用戶的 uid 數(shù)量和)

以上兩個(gè)文件允許運(yùn)行進(jìn)程的 uid 映射范圍,在
/proc/中定義。/uid_map 可過濾容器
conmon進(jìn)程的 pid 確認(rèn)每個(gè)容器中的 uid 映射情況,參見以下示例。關(guān)于以上兩個(gè)文件的具體說明可參考
newuidmap與newgidmap命令的 man 手冊(cè)。可參考 Podman 官方推薦的命令創(chuàng)建 uid 的映射,如下所示:
$?sudo?usermod?--add-subuids?10000-75535?$(whoami)
#?-----?示例?-----
$?sudo?cat?/etc/subuid
??appuser:10000:500
$?sudo?cat?/etc/subgid
??appuser:500:50
#?該用戶創(chuàng)建的 user namespace 中可以使用從 10000?開始的 500?個(gè) UID 和從 500?開始的 50?個(gè) GID 的映射。?? 示例:
普通用戶 hualf 在 /etc/subuid 中映射為 hualf:165536:65536,說明在該用戶的用戶命名空間中可嵌套一個(gè)或多個(gè)用戶命名空間(或容器),每個(gè)容器中的 root 用戶 uid 0 都映射為 hualf 用戶的 uid 1001(運(yùn)行容器進(jìn)程的用戶),而容器中普通用戶的 uid 映射至宿主機(jī)的 subuid 范圍中,對(duì)于此例 subuid 范圍為 165536~231071,容器中的 uid 1 用戶映射為宿主機(jī) uid 165536,因此容器中 admin 用戶 uid 1000 映射為宿主機(jī) uid 166535(165536+999)。
通過容器宿主機(jī)上每個(gè)普通用戶的用戶命名空間的 subuid 映射范圍,可分配眾多 uid 在 rootless 容器中運(yùn)行應(yīng)用進(jìn)程。


Podman 的 macvlan 網(wǎng)絡(luò)實(shí)現(xiàn):
macvlan作為 CNI 在 Kubernetes 與 OpenShift v4 中作為Multus CNI支持的額外插件類型使用愈加廣泛,集群中除了常規(guī)使用的 Flannel、Calico 等作為slow path的插件外,要求高性能的業(yè)務(wù)流量可使用 macvlan 直連 pod 宿主機(jī)物理網(wǎng)口實(shí)現(xiàn)fast path。為后續(xù)熟悉以上場(chǎng)景的實(shí)現(xiàn),因此在 Podman
rootfull容器中使用 macvlan 網(wǎng)絡(luò)模式。關(guān)于 macvlan 的基礎(chǔ)知識(shí)可參考 Linux 虛擬網(wǎng)卡技術(shù):Macvlan[7]
macvlan 特性由
Linux kernel支持,筆者的實(shí)驗(yàn)環(huán)境滿足 macvlan 的要求,請(qǐng)使用如下命令確定:$?sudo?lsmod?|?grep?macvlan
#?若無任何返回,說明還未加載 macvlan 內(nèi)核模塊。
$?sudo?modprobe?macvlan
#?加載 macvlan 內(nèi)核模塊,若執(zhí)行報(bào)錯(cuò),說明 kernel 不支持該特性。podman 與 macvlan 類型網(wǎng)絡(luò)的集成,如下所示:
$?sudo?podman?network?create?-d?macvlan?-o?parent=ens33?
??/etc/cni/net.d/.conflist
#?創(chuàng)建?macvlan?類型網(wǎng)絡(luò)
$?sudo?podman?network?ls
$?sudo?/opt/cni/bin/dhcp?daemon
#?在另一個(gè)窗口中啟動(dòng) dhcp 守護(hù)進(jìn)程供 macvlan 插件調(diào)用,為容器網(wǎng)口分配 IP 地址。
$?sudo?podman?run?-it?--rm?\
??--name??--network= ?\
??: ?/bin/sh
#?創(chuàng)建支持?macvlan?類型網(wǎng)絡(luò)的?rootfull?容器從與 rootfull 容器在同一廣播域的其他節(jié)點(diǎn)上 ping 該容器,可正常通信:

podman 與 podman-compose 使用示例:
示例 1:
?? 使用 podman 命令登錄
Quay公共容器鏡像倉庫并推送鏡像:
?? 搜索并拉取 Red Hat 容器鏡像倉庫中的鏡像列表:

示例 2:
?? 從頭創(chuàng)建 pod 并附加額外的容器:
$?podman?pod?create?--name??[-p? : ]
#?使用?pause?容器鏡像從頭創(chuàng)建?pod
#?若之后需在?pod?中創(chuàng)建使用端口映射的容器,需要在創(chuàng)建?pod?之初指定端口映射關(guān)系,無法在創(chuàng)建容器時(shí)指定,由于?pod
#?提供了其中所有容器的共享網(wǎng)絡(luò)命名空間。
#?注意:若需指定多個(gè)端口,可同時(shí)使用多個(gè)?-p 選項(xiàng)。
$?podman?run?-d?--name??--pod? ? :
#?創(chuàng)建容器將其附加到?pod?中
$?podman?pod?[ps|list|ls]
#?查看已存在的?pod
$?podman?pod?[stop|rm]?
#?停止或刪除 pod,將一并刪除 pod 中的所有容器。?? 注意:
?? 隨創(chuàng)建容器時(shí)同時(shí)創(chuàng)建 pod:
$?podman?run?-d?\
??--name??--pod?new: ?\
??[-p?: ]?\
??:
#?隨創(chuàng)建容器時(shí)同時(shí)創(chuàng)建?pod
$?podman?run?-d?\
??--name??--pod? ?\
??:
#?在?pod?中創(chuàng)建新的容器如下所示,創(chuàng)建名為 nginx-docs 的容器并同時(shí)創(chuàng)建名為 docker-docs 的 pod,也可創(chuàng)建其他容器添加至 pod 中,使用該容器即可訪問 nginx-docs 容器(兩者共享網(wǎng)絡(luò)命名空間):

?? 使用 Podman 在單個(gè) pod 中集成多容器的方法,可參考 之前發(fā)布的文檔[8],該文檔中將 Quay、MySQL 與 Redis 的單容器集成在單個(gè) pod 中,使用 pod 的
network namespace方便 Quay 鏡像倉庫的管理。k8s.gcr.io/pause:3.5鏡像拉取需要科學(xué)上網(wǎng)。若無法拉取,可先拉取 registry.aliyuncs.com/google_containers/pause:3.5鏡像,再更改其tag即可。示例 3:
?? 部署并使用云原生輕量級(jí)對(duì)象存儲(chǔ)
MinIO Server:

?? 注意:以上示例已將 podman 與 systemd 集成實(shí)現(xiàn)普通用戶的 rootless 容器開機(jī)自啟動(dòng)。

關(guān)于 MinIO Server 分布式對(duì)象存儲(chǔ)的詳細(xì)內(nèi)容,請(qǐng) 參考官網(wǎng)[9]
示例 4:
?? root 用戶運(yùn)行 rootfull 容器:多個(gè)容器間通過
cni-podman0網(wǎng)橋互相通信。?? 部署 loganalyzer 管理集中式日志[10]
示例 5:
?? 普通用戶或 root 用戶運(yùn)行容器:
?? 同一個(gè)
pod中的多個(gè)容器使用共享網(wǎng)絡(luò)命名空間,并通過link鏈接至指定的容器建立通信。?? 使用
podman-compose部署輕量級(jí) Git 代碼版本控制倉庫:Gogs + PostgreSQL?? 注意:可考慮如何使用 podman-compose 部署輕量級(jí)
Gitea + DroneCI 平臺(tái)Run User 值:默認(rèn) git。Domain 值:若要從其他主機(jī)連接至 Gogs 倉庫,Domian 必須配置為容器宿主機(jī)的 IP 地址或主機(jī)名。 SSH Port 值:podman-compose 定義文件中對(duì)外暴露的 SSH 端口號(hào)。 HTTP Port 值:默認(rèn) 3000端口。關(guān)于 Gogs 項(xiàng)目的詳細(xì)內(nèi)容可參考 Gogs GitHub 項(xiàng)目[12]
Gogs 代碼版本控制倉庫使用 Golang 語言開發(fā),可與后端 MySQL、PostgreSQL、SQLite3、TiDB 等集成。
此處使用容器化部署 Gogs,并與 PostgreSQL 集成。
部署用主機(jī)上必須先安裝 podman 與 podman-compose,并拉取相應(yīng)容器鏡像加速部署過程,如下所示:

?? 注意:
podman-compose 使用創(chuàng)建
pod將多個(gè)容器組建成 pod 的方式進(jìn)行容器編排,因此必須具有pause容器鏡像提供 pod 的共享網(wǎng)絡(luò)命名空間與掛載命名空間。使用普通用戶部署,過程如下所示:
$?mkdir?-p?gogs-app/gogs-data/{gogs,gogs-logs,postgresql}
#?創(chuàng)建用于存儲(chǔ)?gogs?與?postgresql?數(shù)據(jù)映射的目錄
$?sudo?chown?-R?100999:100999?gogs-app/gogs-data/{gogs,gogs-logs}
#?更改映射目錄的屬組,否則容器啟動(dòng)權(quán)限報(bào)錯(cuò)。
$?getenforce
??Enforcing
#?確認(rèn)系統(tǒng)處于 enforcing SELinux 狀態(tài),需設(shè)置目錄映射時(shí)的標(biāo)簽。
#?也可禁用 SELinux,若禁用 SELinux,以下兩步可不執(zhí)行并且去除 podman-compose 定義文件中的?"Z"。
$?sudo?semanage?port?-a?-t?http_port_t?-p?tcp?10800
$?sudo?semanage?port?-a?-t?ssh_port_t?-p?tcp?10022
#?添加自定義端口至 SELinux 數(shù)據(jù)庫中,否則由于權(quán)限問題無法訪問并安裝 Gogs。
$?vim?gogs-app/gogs-postgres-podman-compose.yaml
#?如下所示?podman-compose?的?yaml?定義文件version:?"3"
services:
??postgresql:
????image:?docker.io/library/postgres:14.1-bullseye
????container_name:?"gogs-postgresql"
????volumes:
??????-?"./gogs-data/postgresql:/var/lib/postgresql:Z"
????environment:
??????-?"POSTGRES_USER=gogs"
??????-?"POSTGRES_PASSWORD=redhat"
??????-?"POSTGRES_DB=gogs"
????ports:
??????-?"5432:5432"
??gogs:
????image:?docker.io/gogs/gogs:0.12
????container_name:?"gogs"
????volumes:
??????-?"./gogs-data/gogs:/data:Z"
??????-?"./gogs-data/gogs-logs:/app/gogs/log:Z"
????ports:
??????-?"10022:22"
??????-?"10800:3000"
????links:
??????-?postgresql$?podman-compose?-f?gogs-app/gogs-postgres-podman-compose.yaml?--project?gogs-app?up
#?啟動(dòng) Gogs 與 PostgreSQL 容器,并指定項(xiàng)目名稱。
#?若不指定項(xiàng)目名稱,項(xiàng)目默認(rèn)為 yaml 文件所在的目錄名稱。
#?首次啟動(dòng)容器時(shí),所有的啟動(dòng)與運(yùn)行日志將打印至終端屏幕上,該終端不可關(guān)閉,直至關(guān)閉所有服務(wù)容器后將自動(dòng)退出。
$?podman-compose?-f?gogs-app/gogs-postgres-podman-compose.yaml?--project?gogs-app?ps
??using?podman?version:?podman?version?3.2.3
??podman?ps?-a?--filter?label=io.podman.compose.project=gogs-app
??CONTAINER?ID??IMAGE?????????????????????????????????????COMMAND???????????????CREATED??????STATUS??????????PORTS???????????????????????????????????????????????????????????????????NAMES
??2bed211ffe60??docker.io/library/postgres:14.1-bullseye??postgres??????????????6?hours?ago??Up?3?hours?ago??0.0.0.0:10022->22/tcp,?0.0.0.0:10800->3000/tcp,?0.0.0.0:5432->5432/tcp??gogs-postgresql
??2c7d0de4b0a0??docker.io/gogs/gogs:0.12??????????????????/bin/s6-svscan?/a...??6?hours?ago??Up?3?hours?ago??0.0.0.0:10022->22/tcp,?0.0.0.0:10800->3000/tcp,?0.0.0.0:5432->5432/tcp??gogs
??0
#?查看?podman-compose?管理的容器服務(wù)
$?podman?ps
??CONTAINER?ID??IMAGE?????????????????????????????????????COMMAND???????????????CREATED??????STATUS??????????PORTS???????????????????????????????????????????????????????????????????NAMES
??b6df150a3a49??k8s.gcr.io/pause:3.5????????????????????????????????????????????6?hours?ago??Up?6?hours?ago??0.0.0.0:10022->22/tcp,?0.0.0.0:10800->3000/tcp,?0.0.0.0:5432->5432/tcp??c3a10da46f18-infra
??2bed211ffe60??docker.io/library/postgres:14.1-bullseye??postgres??????????????6?hours?ago??Up?3?hours?ago??0.0.0.0:10022->22/tcp,?0.0.0.0:10800->3000/tcp,?0.0.0.0:5432->5432/tcp??gogs-postgresql
??2c7d0de4b0a0??docker.io/gogs/gogs:0.12??????????????????/bin/s6-svscan?/a...??6?hours?ago??Up?3?hours?ago??0.0.0.0:10022->22/tcp,?0.0.0.0:10800->3000/tcp,?0.0.0.0:5432->5432/tcp??gogs
#?查看正在運(yùn)行的容器,包含 infra 容器。所有容器正常運(yùn)行后,使用
http://<容器宿主機(jī) IP 地址>:10800訪問 Gogs 安裝界面,需填入的值參考如下:
Web 頁面中最后需設(shè)置 Gogs 管理員賬號(hào)以完成安裝。
安裝完成后,使用管理員賬號(hào)登錄或重新注冊(cè)新賬號(hào)登錄與使用。
如下所示,使用
devops用戶創(chuàng)建新代碼庫并完成 commit 提交:
如需關(guān)閉 Gogs 代碼倉庫,請(qǐng)使用以下方法停止 gogs 與 postgresql 容器服務(wù)即可:
$?podman-compose?-f?gogs-app/gogs-postgres-podman-compose.yaml?--project?gogs-app?stop?gogs?postgresql
??using?podman?version:?podman?version?3.2.3
??podman?stop?-t?10?gogs
??gogs
??0
??podman?stop?-t?10?gogs-postgresql
??gogs-postgresql
??0
$?podman?ps
??CONTAINER?ID??IMAGE?????????????????COMMAND?????CREATED???????STATUS?????????????PORTS???????????????????????????????????????????????????????????????????NAMES
??b6df150a3a49??k8s.gcr.io/pause:3.5??????????????30?hours?ago??Up?39?minutes?ago??0.0.0.0:10022->22/tcp,?0.0.0.0:10800->3000/tcp,?0.0.0.0:5432->5432/tcp??c3a10da46f18-infra?? 注意:
切不可直接使用 podman-compose 命令的
down子命令,該子命令將所有相關(guān)的容器與 pod 全部刪除,pod 刪除后無法將其中的各容器映射至宿主機(jī)對(duì)應(yīng)的目錄中,即使原始數(shù)據(jù)依然保留于目錄中。重新啟動(dòng) Gogs 代碼倉庫的方式,如下所示:
$?podman-compose?-f?gogs-app/gogs-postgres-podman-compose.yaml?--project?gogs-app?start?gogs?postgresql
??using?podman?version:?podman?version?3.2.3
??podman?start?gogs
??gogs
??0
??podman?start?gogs-postgresql
??gogs-postgresql
??0以上 gogs-postgres-podman-compose.yaml 文件可參考 此處[13]。
關(guān)于 podman-compose 的安裝可參考 GitHub 項(xiàng)目[11]
Podman 報(bào)錯(cuò)示例:
podman 容器鏡像倉庫的配置方式:
全局配置:/etc/containers/registries.conf 局部配置:$HOME/.config/containers/registroes.conf 若 podman 安裝后在以上配置中未唯一指定的容器鏡像倉庫,那么在拉取容器鏡像時(shí),將交互式提示用戶選擇容器鏡像倉庫。
示例 1:
?? podman v3.2.3 登錄 Harbor v1.8.1 身份認(rèn)證報(bào)錯(cuò):
$?podman?login?harbor.domain12.example.com:8880
??Username:?admin
??Password:?redhat
??Error:?authenticating?creds?for?"harbor.domain12.example.com:8880":?error?pinging?docker?registry
??harbor.domain12.example.com:8880:?Get?"https://harbor.domain12.example.com:8880/v2/":
??http:?server?gave?HTTP?response?to?HTTPS?client
# Podman 未做任何配置登錄 Harbor 報(bào)錯(cuò),該 Harbor 容器鏡像倉庫未配置 TLS 加密傳輸。
#?報(bào)錯(cuò)顯示 Harbor 響應(yīng) HTTP 請(qǐng)求,而 Podman 發(fā)送 HTTPS 請(qǐng)求登錄。
#?因此,將 Podman 配置為發(fā)送 HTTP 請(qǐng)求的客戶端。?? 解決方式一:
$?podman?login?--tls-verify=false?harbor.domain12.example.com:8880
??Username:?admin
??Password:?redhat
??Login?Succeeded!
# Podman 未進(jìn)行任何配置,直接使用?--tls-verify=false 選項(xiàng)即可認(rèn)證登錄。?? 解決方式二:
$?mkdir?-p?~/.config/containers/?&&?cd?~/.config/containers/
#?創(chuàng)建普通用戶?rootless?容器的目錄
$?vim?~/.config/containers/registries.conf
??unqualified-search-registries?=?['harbor.domain12.example.com:8880']
??[[registry]]
??location?=?"harbor.domain12.example.com:8880"
??insecure?=?true
??#?If?true,?unencrypted?HTTP?as?well?as?TLS?connections?with?untrusted
??#?certificates?are?allowed.
??block?=?false
#?配置未加密傳輸?shù)?Harbor?容器鏡像倉庫的主機(jī)名與端口
$?podman?login?--log-level=debug?harbor.domain12.example.com:8880
??INFO[0000]?podman?filtering?at?log?level?debug
??DEBU[0000]?Called?login.PersistentPreRunE(podman?login?--log-level=debug?harbor.domain12.example.com:8880)
??DEBU[0000]?overlay?storage?already?configured?with?a?mount-program
??DEBU[0000]?Merged?system?config?"/usr/share/containers/containers.conf"
??DEBU[0000]?overlay?storage?already?configured?with?a?mount-program
??DEBU[0000]?Using?conmon:?"/usr/bin/conmon"
??...
??DEBU[0000]?Using?OCI?runtime?"/usr/bin/runc"
??DEBU[0000]?Default?CNI?network?name?podman?is?unchangeable
??INFO[0000]?Setting?parallel?job?count?to?13
??DEBU[0000]?Loading?registries?configuration?"/home/kiosk/.config/containers/registries.conf"
??DEBU[0000]?Loading?registries?configuration?"/etc/containers/registries.conf.d/000-shortnames.conf"
??DEBU[0000]?Loading?registries?configuration?"/etc/containers/registries.conf.d/001-rhel-shortnames.conf"
??DEBU[0000]?Loading?registries?configuration?"/etc/containers/registries.conf.d/002-rhel-shortnames-overrides.conf"
??DEBU[0000]?No?credentials?for?harbor.domain12.example.com:8880?found
??Username:?admin
??Password:?#?交互式輸入登錄密碼
??DEBU[0004]?Looking?for?TLS?certificates?and?private?keys?in?/etc/docker/certs.d/harbor.domain12.example.com:8880
??DEBU[0004]?GET?https://harbor.domain12.example.com:8880/v2/
??DEBU[0004]?Ping?https://harbor.domain12.example.com:8880/v2/?err?Get?"https://harbor.domain12.example.com:8880/v2/":?http:
??server?gave?HTTP?response?to?HTTPS?client?(&url.Error{Op:"Get",?URL:"https://harbor.domain12.example.com:8880/v2/",
??Err:(*errors.errorString)(0xc000590030)})
??...
??DEBU[0004]?GET?http://harbor.domain12.example.com:8880/service/token?account=admin&service=harbor-registry
??DEBU[0004]?GET?http://harbor.domain12.example.com:8880/v2/
??DEBU[0004]?Stored?credentials?for?harbor.domain12.example.com:8880?in?credential?helper?containers-auth.json
??Login?Succeeded!
??DEBU[0004]?Called?login.PersistentPostRunE(podman?login?--log-level=debug?harbor.domain12.example.com:8880)
#?Podman?默認(rèn)使用?TLS?加密傳輸
#?以上配置文件將使 Podman 以 HTTP 方式認(rèn)證登錄 Harbor。示例 2:
?? podman v3.2.3 推送容器鏡像至 Harbor v1.8.1 中顯示 "不完整":
$?podman?push?harbor.domain12.example.com:8880/library/apache-rhce8.2-alpine:1.0
??Getting?image?source?signatures
??Copying?blob?551db21ded82?skipped:?already?exists
??Copying?blob?8213d0880f11?skipped:?already?exists
??Copying?blob?e2eb06d8af82?skipped:?already?exists
??...
??Copying?blob?05e56f8d5aae?skipped:?already?exists
??Copying?blob?631e8a8040bb?skipped:?already?exists
??Copying?blob?dedba5c062fc?skipped:?already?exists
??Copying?blob?0e609f35aa06?[--------------------------------------]?0.0b?/?0.0b
??Copying?config?34f32c2e7a?[======================================]?10.0KiB?/?10.0KiB
??Writing?manifest?to?image?destination
??Storing?signatures從推送的返回結(jié)果顯示,具有 2 層容器鏡像層似乎未推送成功,但將該鏡像從 Harbor 中拉取并重新運(yùn)行容器后,容器能正常提供服務(wù),因此最后 2 層鏡像層實(shí)際推送成功。
示例 3:
?? 容器鏡像無任何運(yùn)行或退出狀態(tài)容器占用,但依然無法刪除鏡像,可嘗試使用
--force選項(xiàng)將其強(qiáng)制刪除。
示例 4:
?? 由于從
dockerbub上直接拉取的鏡像為docker image format,無法使用podman commit命令提交為新的容器鏡像,該命令對(duì)于-m選項(xiàng)不能對(duì) docker image format 鏡像生效,默認(rèn)只支持OCI image format,因此使用 -m 選項(xiàng)對(duì)容器執(zhí)行提交時(shí)需強(qiáng)制指定-f docker才能生效。?? 注意:可使用
skopeo工具轉(zhuǎn)換 docker image format 與 OCI image format。
示例 5:
?? podman 運(yùn)行 rootfull 或 rootless busybox 容器后,
ping外網(wǎng)報(bào)錯(cuò)權(quán)限問題無法 ping 通外網(wǎng),但使用其他工具可與外網(wǎng)通信,通過 該文檔[14] 中可知,ping 命令對(duì)capability敏感,容器可能缺少CAP_NET_RAWcapability 無法通過宿主機(jī) ping 通外網(wǎng)。?? 當(dāng)然,運(yùn)行容器時(shí)指定
--privileged選項(xiàng)可使容器獲得與宿主機(jī) root 用戶同樣的與宿主機(jī)交互的權(quán)限能力,但賦予的權(quán)限過高,應(yīng)當(dāng)壓制該權(quán)限,更好的選擇是對(duì)運(yùn)行容器添加適當(dāng)?shù)?Linux capabilities。
Podman 有待測(cè)試功能:
前文所述,使用 podman pod 命令或使用 podman-compose 組件單機(jī)編排容器,而且 Podman 支持 podman play kube命令基于 YAML 資源定義文件創(chuàng)建 pod,該方法類似 Kubernetes 或 OpenShift,有待測(cè)試。Podman 日志驅(qū)動(dòng)目前只支持 k8s-file、journald與none,暫時(shí)不支持容器日志的JSON格式輸出,因此不能與日志收集引擎fluentd集成,由其實(shí)現(xiàn) ELK/EFK 集中式的存儲(chǔ)、索引等。Podman 與 Linux capabilities的關(guān)系與應(yīng)用在最后一個(gè)示例中有所提及,但更全面的關(guān)系有待測(cè)試。
參考鏈接:
Reintroduction of Podman[15] Using pods with Podman on Fedora[16] Configuring container networking with Podman[17] RedHat docs - Building, running, and managing Linux containers on Red Hat Enterprise Linux 8[18] 容器安全拾遺 - Rootless Container 初探[19] Documentation for /proc/sys/user/[20] docker docs - Overview of Docker Compose[21] CNI docs - firewall plugin[22] CNI docs - Port-mapping plugin[23] https://fossies.org/linux/podman/docs/tutorials/basic_networking.md
引用鏈接
點(diǎn)擊此處: https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/8/html/building_running_and_managing_containers/assembly_starting-with-containers_building-running-and-managing-containers#proc_setting-up-rootless-containers_assembly_starting-with-containers
[2]Podman Doc - installation: https://podman.io/getting-started/installation
[3]Easy to Install Podman on Ubuntu 20.04: https://www.hostnextra.com/kb/easy-to-install-podman-on-ubuntu-20-04/
[4]podman from devel:kubic:libcontainers:stable project: https://software.opensuse.org//download.html?project=devel%3Akubic%3Alibcontainers%3Astable&package=podman
[5]點(diǎn)擊此處: https://imroc.cc/k8s/faq/why-enable-bridge-nf-call-iptables/
[6]Github 項(xiàng)目: https://github.com/rootless-containers/slirp4netns
[7]Linux 虛擬網(wǎng)卡技術(shù):Macvlan: https://mp.weixin.qq.com/s?__biz=MzU1MzY4NzQ1OA==&mid=2247484064&idx=1&sn=ffd745069b6c4aeac0589de00467b2f2&chksm=fbee426dcc99cb7bdf26f5e6a21bbeaebba7ccd384a02f850d4461ea92331ed140edf98ffaec&mpshare=1&scene=1&srcid=03049MKwF55OVgEZ4OCH39wd&sharer_sharetime=1583337046541&sharer_shareid=8eaca72194dae7b3d51d5c708436eee4#rd
[8]之前發(fā)布的文檔: https://jsdelivr.fuckcloudnative.io/gh/Alberthua-Perl/tech-docs@master/Red%20Hat%20Quay%20v3%20registry%E5%8E%9F%E7%90%86%E4%B8%8E%E5%AE%9E%E7%8E%B0.md
[9]參考官網(wǎng): https://min.io/
[10]部署 loganalyzer 管理集中式日志: https://github.com/Alberthua-Perl/scripts-confs/tree/master/deploy-rsyslog-viewer
[11]GitHub 項(xiàng)目: https://github.com/containers/podman-compose
[12]Gogs GitHub 項(xiàng)目: https://github.com/gogs/gogs
[13]此處: https://github.com/Alberthua-Perl/dockerfile-s2i-demo/blob/master/gogs-postgres-compose/gogs-postgres-podman-compose.yaml
[14]該文檔: https://www.redhat.com/sysadmin/container-networking-podman
[15]Reintroduction of Podman: https://projectatomic.io/blog/2018/02/reintroduction-podman/
[16]Using pods with Podman on Fedora: https://fedoramagazine.org/podman-pods-fedora-containers/
[17]Configuring container networking with Podman: https://www.redhat.com/sysadmin/container-networking-podman
[18]RedHat docs - Building, running, and managing Linux containers on Red Hat Enterprise Linux 8: https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/8/html/building_running_and_managing_containers/index
[19]容器安全拾遺 - Rootless Container 初探: https://developer.aliyun.com/article/700923
[20]Documentation for /proc/sys/user/: https://www.kernel.org/doc/html/latest/admin-guide/sysctl/user.html
[21]docker docs - Overview of Docker Compose: https://docs.docker.com/compose/
[22]CNI docs - firewall plugin: https://www.cni.dev/plugins/current/meta/firewall/
[23]CNI docs - Port-mapping plugin: https://www.cni.dev/plugins/current/meta/firewall/
原文鏈接:https://github.com/Alberthua-Perl/tech-docs/blob/master/Podman%20%E5%AE%B9%E5%99%A8%E4%BD%BF%E7%94%A8%E4%B8%8E%E5%8E%9F%E7%90%86.md


你可能還喜歡
點(diǎn)擊下方圖片即可閱讀

云原生是一種信仰???
關(guān)注公眾號(hào)
后臺(tái)回復(fù)?k8s?獲取史上最方便快捷的 Kubernetes 高可用部署工具,只需一條命令,連 ssh 都不需要!


點(diǎn)擊?"閱讀原文"?獲取更好的閱讀體驗(yàn)!
發(fā)現(xiàn)朋友圈變“安靜”了嗎?


