Podman 作為新一代容器管理工具,其網路設定至關重要。本文不僅深入剖析了 Podman 根據 CNI 的網路組態,包含 bridge、host-local 等外掛的協同運作,也詳細介紹了 Podman 4 引入的 Netavark 網路後端,比較其與 CNI 設定的差異。透過 Nginx 容器的實際操作範例,讀者可以清楚瞭解容器建立前後網路介面的變化、路由表設定、iptables 規則,以及如何使用 traceroute 指令驗證網路連線。此外,文章也針對 veth pair、網路名稱空間等核心概念進行了詳細說明,有助於讀者更全面地掌握 Podman 容器網路的運作原理。
容器網路與Podman設定實作
在容器技術中,網路設定是至關重要的一環。Podman作為一種容器管理工具,其網路功能主要依賴於Container Networking Interface(CNI)外掛來實作。本文將探討Podman的網路組態及其背後的CNI外掛機制。
CNI Meta外掛的作用
CNI Meta外掛用於組態主機上的特定行為,例如調整系統引數、設定防火牆規則以及進行埠對映。這些外掛與介面建立外掛一起被執行,形成一個鏈式結構。目前,參考外掛倉函式庫中維護的Meta外掛包括:
- portmap:負責容器與主機之間的埠對映。它透過主機防火牆(iptables)來應用組態,並建立源網路位址轉換(SNAT)和目的網路位址轉換(DNAT)規則。預設情況下,該外掛在Podman中是啟用的。
- firewall:組態防火牆規則以允許容器的輸入和輸出流量。該外掛在Podman中預設啟用。
- tuning:自定義網路名稱空間中的系統引數(使用sysctl引數)和介面屬性。該外掛在Podman中同樣是預設啟用的。
- bandwidth:利用Linux流量控制子系統對容器的流量進行速率限制。
- sbr:用於在介面上組態根據源的路由(SBR)。
Podman預設網路組態解析
在Podman的預設組態中,使用了bridge外掛搭配host-local IP位址管理,並且將portmap、tuning和firewall外掛連結在一起。在為Podman建立的預設網路中,分配給容器網路的子網是10.88.0.0/16,而橋接介面cni-podman0作為容器的預設閘道器,其IP位址為10.88.0.1。這意味著所有從容器發出的流量都會被導向該橋接介面的IP位址。
Podman容器網路實作詳解
當建立一個新的rootfull容器時,Podman會利用CNI作為網路後端。下面我們將詳細探討在這種情況下發生的網路事件。
建立Nginx容器範例
首先,我們執行以下命令來執行一個Nginx容器,並將其內部的80/tcp埠對映到主機的8080/tcp埠:
# podman run -d -p 8080:80 --name net_example docker.io/library/nginx
在執行上述命令之前,我們先檢查主機的IP組態:
# ip addr show
輸出的結果顯示了主機的主要介面eth0和一個名為cni-podman0的橋接介面,其IP位址為10.88.0.1/16。此時,橋接介面的狀態是DOWN。
網路介面變化
執行Nginx容器後,我們再次檢查網路介面的狀態:
# ip addr show
結果顯示,一個新的虛擬介面被建立:
5: vethcf8b2132@if2: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master cni-podman0 state UP group default
link/ether b6:4c:1d:06:39:5a brd ff:ff:ff:ff:ff:ff link-netns cni-df380fb0-b8a6-4f39-0d19-99a0535c2f2d
inet6 fe80::90e3:98ff:fe6a:acff/64 scope link
valid_lft forever preferred_lft forever
這個新的介面是一個veth對的一部分。veth對是一種本地隧道,由一對虛擬乙太網路裝置組成。當資料包被傳送到veth對的一端時,它會立即被另一端接收。
防火牆規則與路由變化
除了網路介面的變化外,防火牆規則和路由也會相應地更新。我們可以透過以下命令來檢查相關的變更:
# iptables -L
# iptables -L -t nat
# ip route show dev cni-podman0
這些命令將顯示由於容器的建立而新增的防火牆規則和路由規則。
內容解密:
- veth對的作用:veth對是一種虛擬網路裝置,用於連線不同的網路名稱空間。它使得資料包可以在不同的網路名稱空間之間傳遞。
- CNI Meta外掛的功能:CNI Meta外掛負責組態主機上的特定行為,如埠對映、防火牆規則設定等。
- Podman預設網路組態:Podman預設使用
bridge外掛和host-localIP位址管理,並啟用portmap、tuning和firewall等Meta外掛。 - 容器建立對網路的影響:當建立一個新的rootfull容器時,Podman會建立一個新的veth對,並更新防火牆規則和路由,以實作容器與外界的通訊。
透過本文的詳細解析,讀者可以更深入地理解Podman的網路機制及其背後的技術原理。
容器網路實作概念詳解
容器網路的組態與管理是現代雲端與虛擬化技術中的重要環節。透過深入分析Linux網路名稱空間、虛擬網路介面(veth pairs)以及網橋(bridge)等核心元件,我們可以更全面地理解容器如何與外部世界進行通訊。
網路名稱空間的檢查與驗證
首先,系統中存在一個名為 cni-df380fb0-b8a6-4f39-0d19-99a0535c2f2d 的網路名稱空間,該名稱空間與一個特定的容器相關聯。我們可以使用 ip netns 指令來檢查其是否存在:
# ip netns
cni-df380fb0-b8a6-4f39-0d19-99a0535c2f2d (id: 0)
內容解密:
ip netns指令用於列出系統中所有可見的網路名稱空間。- 當建立一個新的網路名稱空間時,系統會在
/var/run/netns/目錄下建立一個同名的檔案,該檔案具有與/proc/<PID>/ns/net下的符號連結相同的 inode 編號。 - 當開啟此檔案時,傳回的檔案描述符提供了對該名稱空間的存取許可權。
容器內的網路介面檢查
接下來,我們可以透過 ip netns exec 指令進入指定的網路名稱空間,並執行 ip addr show 指令來檢查容器內的網路介面組態:
# ip netns exec cni-df380fb0-b8a6-4f39-0d19-99a0535c2f2d ip addr show
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eth0@if5: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
link/ether fa:c9:6e:5c:db:ad brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet 10.88.0.3/16 brd 10.88.255.255 scope global eth0
valid_lft forever preferred_lft forever
inet6 fe80::f8c9:6eff:fe5c:dbad/64 scope link
valid_lft forever preferred_lft forever
內容解密:
ip netns exec指令允許我們在指定的網路名稱空間中執行命令。ip addr show顯示了該名稱空間內的網路介面組態,包括迴環介面(lo)和虛擬乙太網介面(eth0@if5)。- eth0@if5 的 IPv4 位址被設定為
10.88.0.3/16,表示該容器的 IP 位址。
路由表的檢查
進一步地,我們可以檢查容器的路由表,以瞭解其如何與外部網路進行通訊:
# ip netns exec cni-df380fb0-b8a6-4f39-0d19-99a0535c2f2d ip route
default via 10.88.0.1 dev eth0
10.88.0.0/16 dev eth0 proto kernel scope link src 10.88.0.3
內容解密:
- 該容器的預設路由是透過
10.88.0.1,該位址被分配給cni-podman0網橋。 - 所有前往外部網路的流量將透過該預設閘道進行轉發。
iptables 設定檢查
為了實作容器埠對映和 SNAT/DNAT 功能,系統會在主機的 iptables 中新增相應的規則:
# iptables -L -t nat -n | grep -B4 10.88.0.3
Chain POSTROUTING (policy ACCEPT)
target prot opt source destination
CNI-HOSTPORT-MASQ all -- 0.0.0.0/0 0.0.0.0/0 /* CNI portfwd requiring masquerade */
CNI-fb51a7bfa5365a8a89e764fd all -- 10.88.0.3 0.0.0.0/0 /* name: "podman" id: "a5054cca3436a7bc4dbf78fe4b901ceef0569ced24181d2e7b118232123a5fe3" */
--
Chain CNI-DN-fb51a7bfa5365a8a89e76 (1 references)
target prot opt source destination
CNI-HOSTPORT-SETMARK tcp -- 10.88.0.0/16 0.0.0.0/0 tcp dpt:8080
CNI-HOSTPORT-SETMARK tcp -- 127.0.0.1 0.0.0.0/0 tcp dpt:8080
DNAT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:8080 to:10.88.0.3:80
內容解密:
- 在 nat 表中增加了 SNAT 和 DNAT 規則,以實作容器的埠對映。
- DNAT 規則將所有到達主機 8080/tcp 連線埠的流量轉發到容器的
10.88.0.3:80。
網路路徑追蹤
最後,我們可以透過 traceroute 命令來追蹤從容器到外部目標主機的網路路徑:
# ip netns exec cni-df380fb0-b8a6-4f39-0d19-99a0535c2f2d traceroute -I 1.1.1.1
traceroute to 1.1.1.1 (1.1.1.1), 30 hops max, 60 byte packets
1 _gateway (10.88.0.1) 0.071 ms 0.025 ms 0.003 ms
2 192.168.121.1 (192.168.121.1) 0.206 ms 0.195 ms 0.189 ms
3 ... (omitted for brevity)
內容解密:
- traceroute 命令顯示了從容器到目標主機
1.1.1.1的網路路徑。 - 第一個躍點是預設閘道
10.88.0.1,即cni-podman0網橋。
容器網路與 Podman 設定詳解
在容器技術中,網路設定是至關重要的一環。Podman 作為一種容器管理工具,其網路設定的靈活性和可組態性對於容器的佈署和管理具有重要意義。本文將探討 Podman 的網路設定,包括其預設的 CNI(Container Network Interface)實作以及新引入的 Netavark 實作。
CNI 實作與設定
CNI 是容器網路介面的標準,它定義了一套容器網路設定的規範。Podman 支援 CNI 實作,允許使用者透過 CNI 設定檔來組態容器的網路。
traceroute 指令的使用
在探討 CNI 實作之前,我們先來瞭解如何使用 traceroute 指令來追蹤網路路徑。traceroute 是一個用於追蹤網路封包傳輸路徑的工具,可以用來檢測網路連線問題。
sudo dnf install traceroute
執行 traceroute 指令後,我們可以看到一系列的躍點(hop),這些躍點代表了封包從源到達目的地的過程中經過的路由器或網路裝置。
CNI 設定檔解析
CNI 的設定檔通常以 JSON 格式儲存,定義了容器的網路設定。下面是一個 CNI 設定檔的例子:
{
"cniVersion": "0.4.0",
"name": "podman",
"plugins": [
{
"type": "bridge",
"bridge": "cni-podman0",
"isGateway": true,
"ipMasq": true,
"ipam": {
"type": "host-local",
"subnet": "10.88.0.0/16",
"routes": [
{ "dst": "0.0.0.0/0" }
]
}
}
]
}
內容解密:
cniVersion: 指定 CNI 的版本。name: 網路名稱。plugins: 一個包含多個外掛的陣列,這裡使用了bridge外掛。type("bridge"): 指定使用的 CNI 外掛型別為橋接模式。bridge("cni-podman0"): 指定橋接介面的名稱。isGateway: 是否啟用閘道器功能。ipMasq: 是否啟用 IP 偽裝。ipam: IP 位址管理設定,使用host-local外掛進行本地 IP 位址分配。subnet: 定義子網範圍。
Netavark:Podman 4 的新網路後端
Podman 4.0.0 版本引入了 Netavark 作為預設的網路後端。Netavark 提供了多項改進,包括對雙堆疊 IPv4/IPv6 的支援、原生 DNS 解析、無根容器支援以及對不同防火牆實作的支援。
Netavark 設定檔解析
Netavark 的設定檔同樣採用 JSON 格式,但相比 CNI 設定檔更為簡潔。下面是一個 Netavark 設定檔的例子:
[
{
"name": "netavark-example",
"id": "d98700453f78ea2fdfe4a1f77eae9e121f3cbf4b6160dab89edf9ce23cb924d7",
"driver": "bridge",
"network_interface": "podman1",
"created": "2022-02-17T21:37:59.873639361Z",
"subnets": [
{
"subnet": "10.89.4.0/24",
"gateway": "10.89.4.1"
}
],
"ipv6_enabled": false,
"internal": false,
"dns_enabled": true,
"ipam_options": {
"driver": "host-local"
}
}
]
內容解密:
name: 網路名稱。id: 網路唯一識別碼。driver: 網路驅動程式型別,這裡使用的是bridge。network_interface: 與網路相關聯的網路介面名稱。subnets: 子網和閘道器物件的列表。ipv6_enabled: 是否啟用 IPv6 支援。internal: 是否組態為內部使用並阻止外部路由。dns_enabled: 是否啟用 DNS 解析,由aardvark-dns守護程式提供服務。ipam_options: IP 位址管理選項,這裡使用host-local驅動程式。
Podman Netavark 操作例項
當使用 Netavark 建立容器時,Podman 會自動建立必要的網路組態,包括 veth 對和 Linux 橋接器。
建立 Nginx 容器
podman run -d -p 8080:80 --name nginx-netavark docker.io/library/nginx
在建立容器後,可以觀察到 podman0 橋接介面和一對 veth 介面的建立。
# ip addr show
內容解密:
- 容器建立前後的網路介面變化:在容器建立之前,系統只有預設的網路介面,如
lo和eth0。建立容器後,會出現新的podman0橋接介面和一對 veth 介面,其中一端在容器內,另一端在主機上並與podman0橋接介面相連。