news 2026/9/20 4:09:24

Podman 容器网络实战指南:Bridge、Macvlan 与 Pasta 三大网络模式完全解析

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Podman 容器网络实战指南:Bridge、Macvlan 与 Pasta 三大网络模式完全解析
  • 容器运行时
  • 云原生
  • CLI

【免费下载链接】podman

Podman: A tool for managing OCI containers and pods.

项目地址:https://gitcode.com/gh_mirrors/po/podman
点击查看免费下载

本指南以 Podman 官方基础网络教程(docs/tutorials/basic_networking.md)为骨架,系统讲解 rootful 与 rootless 容器在网络上的本质差异、防火墙对容器流量的影响,以及 Bridge、Macvlan、Pasta 三种最常用网络模式的原理、配置与完整可复现示例,并深入解析容器与 Pod 之间共享网络命名空间的通信方式。读完本文,你将掌握为不同运行身份(root/非 root)选择正确网络模式、配置端口映射、创建 macvlan 网络并启用 DHCP、以及解决容器间互访问题的完整实战能力。

rootful 与 rootless 容器网络的根本差异

决定 Podman 容器采用哪种网络路径的首要因素是容器由 root 用户还是非特权用户运行。其根本原因在于:非特权用户无法在宿主机上创建网络接口(这需要 root 权限),因此两者的默认网络模式截然不同:

  • rootful 容器:默认网络模式为netavark(桥接网络),容器能够获得一个可路由(routable)的 IP 地址,直接参与宿主所在网络的通信;
  • rootless 容器:默认网络模式为pasta,通过用户态网络栈实现无特权联网。

从源码角度可以印证这一设计:在 libpod/define/info.go 中,RootlessNetworkCmd字段明确指出默认 rootless 网络命令为pasta,而RootlessPortForwarder字段则记录了 rootless 桥接网络的端口转发机制(默认rootlessport,可选实验性的pasta)。你可以在任意机器上通过podman info查看这两项的实际取值。

此外,当 rootless 容器运行时,其网络操作会发生在额外的网络命名空间(network namespace)中。要加入该命名空间排查问题,使用:

$ podman unshare --rootless-netns

防火墙:不改变网络配置,但决定流量是否可达

防火墙的角色不是影响网络本身的搭建与配置,而是影响这些网络上的流量,尤其是从外部(宿主机外)进入容器宿主、再通过端口映射转发给容器的入站流量。要点如下:

  • 部分防火墙实现(如 firewalld 等)在检测到容器发布端口映射时,会自动打开对应端口
  • 如果容器流量表现异常,应首先检查防火墙,放行容器正在使用的端口;
  • 一个非常常见的问题:重新加载防火墙会删除 netavark 生成的 iptables 规则,导致 rootful 容器立即失去网络连通性。Podman v3 起提供的podman network reload命令可以在不重启容器的情况下恢复这些规则。

三种基础网络模式概览

大多数 Podman 容器与 Pod 只遵循几种简单场景,对应的三种模式分别为:

网络模式默认适用身份核心机制
Bridge(桥接)rootful(默认)容器与宿主挂接在内部桥接网络上,通过 NAT 访问外部网络
Macvlan仅 root将宿主机整块物理网络接口"透传"给容器,容器直接接入宿主所在网络
Pastarootless(默认)用户态网络,非特权用户无需在宿主上创建接口即可联网

Bridge 桥接网络

桥接网络的定义是:创建一个内部网络,容器与宿主机都挂接其上,随后该网络允许容器与宿主机外部通信。

如上图所示:笔记本用户运行了 web 与 db 两个容器,它们与宿主机处于同一虚拟网络中;默认情况下容器可以主动发起对外通信(例如访问互联网);虚拟网络上的容器通常持有不可路由的私有 IP 地址

当外部客户端需要访问容器时,通常必须访问宿主机的外部网络接口与指定端口号:宿主机在允许入站流量后,通过为容器请求转发的端口添加防火墙转发规则,将入站流量转发给特定容器。

默认网络与自定义网络
  • 桥接网络是root 身份创建容器的默认网络,Podman 提供一个默认桥接网络(名为podman),也可以使用podman network create创建更多网络;
  • 容器在创建时可通过--network标志加入网络,创建后可使用podman network connect/podman network disconnect动态挂接或摘除网络;
  • 创建网络时不指定子网,Podman 会从10.89.0.0/24 到 10.255.255.0/24的池中自动挑选空闲子网(见 podman-network.1.md),可通过containers.conf[network]default_subnet_pools修改默认分配范围与大小。
rootless 用户使用 netavark 桥接

rootless 用户同样可以使用 netavark 桥接网络,体验与 rootful 高度相似,唯一区别是没有默认网络配置——只需手动创建一个网络,它即会按桥接网络方式建立:

$ podman network create
默认网络 podman 的特殊性

netavark 下的默认网络podman纯内存(memory-only)的:出于与 Docker 的向后兼容性考虑,它不支持 DNS 解析。若需要修改其配置,可先导出内存中的网络,再修改导出文件:

  • rootful 默认网络:
podman network inspect podman | jq .[] > /etc/containers/networks/podman.json
  • rootless 默认网络:
podman network inspect podman | jq .[] > ~/.local/share/containers/storage/networks/podman.json
端口转发:rootlessport 与实验性的 pasta

rootless 桥接网络默认使用rootlessport进行端口转发——它是一个用户态代理,不会保留客户端源 IP。若容器需要看到真实的客户端 IP,可在containers.conf[network]节中设置:

[network] rootless_port_forwarder = "pasta"

该选项使用pesto配置 pasta 的内核级转发,使容器看到真实的客户端 IP 而非桥接网关地址。注意:此选项目前为实验特性,行为可能发生变化,且要求安装携带pesto二进制的 passt 版本(>= passt-0^20260507.g1afd4ed)。从源码看,pasta/pesto 的端口转发在容器库(container-libs)的 netavarkSetup()内完成,Podman 侧仅在需要时对 rootlessport 做显式配置(见 libpod/networking_linux.go)。

Bridge 实战示例:对外暴露 Web 服务

默认情况下(未从 Podman v3 迁移时),rootful 容器使用 netavark 作为默认网络后端,无需指定网络名。下面的示例分别以 rootful 与 rootless 身份运行 Web 服务器并对外暴露,同时展示外部客户端如何连接。

rootful 方式(将容器 80 端口映射到宿主 8080):

(rootful) $ sudo podman run -d --name webserver -p 8080:80 quay.io/libpod/banner 00f3440c7576aae2d5b193c40513c29c7964e96bf797cf0cc352c2b68ccbe66a

rootless 方式(加入自定义网络 podman1,映射到宿主 8081):

$ podman run -d --name webserver --network podman1 -p 8081:80 quay.io/libpod/banner 269fd0d6b2c8ed60f2ca41d7beceec2471d72fb9a33aa8ca45b81dc9a0abbb12

注意:上述命令将容器内 Nginx 监听的80 端口映射到了宿主8080/8081 端口,特意选择了非 80 端口来演示宿主端口与容器端口的映射关系(其实也可直接映射为 80,rootless 用户除外——非特权用户无法绑定 1024 以下端口)。

外部客户端访问时,只需将 HTTP 客户端指向宿主 IP 的对应端口:

(outside_host): $ curl 192.168.99.109:8080 ___ __ / _ \___ ___/ /_ _ ___ ____ / ___/ _ \/ _ / ' \/ _ `/ _ \ /_/ \___/\_,_/_/_/_/\_,_/_//_/ (outside_host): $ curl 192.168.99.109:8081 ___ __ / _ \___ ___/ /_ _ ___ ____ / ___/ _ \/ _ / ' \/ _ `/ _ \ /_/ \___/\_,_/_/_/_/\_,_/_//_/

端口发布语法补充(详见 options/publish.md):--publish/-p的完整格式为[[hostIP:][hostPort]:]containerPort[/protocol]。宿主与容器端口均可指定为区间;hostIP缺省时绑定宿主全部 IPv4/IPv6 地址,0.0.0.0仅绑定 IPv4,[::]仅绑定 IPv6;默认发布 TCP 端口,发布 UDP 需显式指定udp,rootful 容器还支持sctp;省略hostPort时会随机分配宿主端口,可用podman port $CONTAINER $CONTAINERPORT查看实际映射。端口发布仅对使用自身网络命名空间的bridge网络与pasta模式生效。

Macvlan

使用 macvlan 时,容器获得宿主机上一块物理网络接口的访问权。该接口可配置多个子接口,每个子接口拥有独立的MAC 地址与 IP 地址;对 Podman 容器而言,它会在网络上表现得如同与宿主机处于同一网络的普通主机。

如上图所示,外部客户端可以直接通过容器自身的 IP 地址访问 Web 容器。通常容器的网络信息(含 IP 地址)像网络中的其他客户端一样,由DHCP 服务器租约分配。如果笔记本运行了 firewalld 之类的防火墙,需要相应放行以保证正常访问。

重要限制:使用 macvlan 必须以 root 身份运行 Podman。

Macvlan 实战示例

首先创建 macvlan 网络。你需要知道宿主连接可路由网络的接口名,示例中为eth0

$ sudo podman network create -d macvlan -o parent=eth0 webnetwork webnetwork

下一步确保DHCP 服务正在运行,它负责处理来自网络的 DHCP 租约。如果不需要 DHCP,可以在上面的network create命令中使用--subnet选项分配静态子网。

Podman 使用 netavark 实现网络功能,使用 DHCP 要求 netavark v1.6 或更高版本(配合 Podman v4.5+)

启用 netavark DHCP 的两种方式——systemd 系统启用 socket 激活:

$ sudo systemctl enable --now netavark-dhcp-proxy.socket

或非 systemd 系统手动启动守护进程:

$ /usr/libexec/podman/netavark dhcp-proxy --activity-timeout 0

然后运行容器并确保挂接上刚创建的网络:

$ sudo podman run -d --name webserver --network webnetwork quay.io/libpod/banner 03d82083c434d7e937fc0b87c25401f46ab5050007df403bf988e25e52c5cc40 [baude@localhost ~]$ sudo podman exec webserver ip address show eth0 2: eth0@if3: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue state UP link/ether 0a:3c:e2:eb:87:0f brd ff:ff:ff:ff:ff:ff inet 192.168.99.186/24 brd 192.168.99.255 scope global eth0 valid_lft forever preferred_lft forever inet6 fe80::83c:e2ff:feeb:870f/64 scope link valid_lft forever preferred_lft forever

从输出可见,容器 eth0 直接获得了局域网内的可路由地址192.168.99.186/24。由于容器持有该网络上的可路由 IP 且不受 firewalld 管理,无需改动防火墙,外部客户端可直接访问:

(outside_host): $ curl http://192.168.99.186 ___ __ / _ \___ ___/ /_ _ ___ ____ / ___/ _ \/ _ / ' \/ _ `/ _ \ /_/ \___/\_,_/_/_/_/\_,_/_//_/

Pasta

pasta 是 rootless 容器与 Pod 的默认网络模式,专为无法在宿主机创建网络接口的非特权用户提供用户态网络(user-mode networking)。pasta 在容器的网络命名空间中创建一个TAP 设备,并提供完整的用户态 TCP/IP 协议栈。

如上图所示:笔记本上的非特权用户创建了 db 与 web 两个容器,二者都能访问笔记本之外的网络;只要容器绑定到宿主端口且笔记本防火墙放行,外部客户端即可访问容器。需要注意,非特权用户只能使用 1024–65535 的端口,低端口需要 root 权限(对应CAP_NET_BIND_SERVICE能力);该限制可通过sysctl net.ipv4.ip_unprivileged_port_start调整。

pasta 的一个固有局限是:默认情况下容器之间彼此隔离,与 bridge 的虚拟网络不同,没有共享的内部网络。容器间通信有两种途径:一是借助宿主系统上的端口映射,二是放入同一个 Pod共享网络命名空间(详见下文"容器与 Pod 之间的通信")。

从源码看,pasta 还内建了 DNS 转发能力(见 libpod/container_internal_common.go),并会在容器内注入对应的 DNS 服务器地址(见 libpod/container_internal_linux.go)。

Pasta 的默认参数细节

根据 options/network.md 的说明,Podman 调用 pasta 时默认附带若干参数,理解它们有助于排查网络问题:

  • --config-net:容器启动时自动配置网络(默认给出);
  • --no-map-gw:默认禁止容器通过网关地址直接访问宿主;可通过在 pasta 专用选项中传--map-gw覆盖(--map-gw并非真正的 pasta(1) 选项,由 Podman 特判处理);
  • --dns-forward 169.254.1.1:默认启用 DNS 转发并将该地址写入容器resolv.conf作为首选解析器,也可显式传--dns-forward指定其他地址;
  • --map-guest-addr 169.254.1.2:默认启用,用于让容器内host.containers.internal/etc/hosts条目生效,使容器能够连接宿主机;
  • 未配置任何--publish或 pasta 的-t/-u选项时,默认传递-t none -u none关闭基于绑定端口的自动转发;同理-T none -U none关闭容器到宿主方向的自动转发。

pasta 常用选项示例(通过--network pasta:OPTIONS传入,多个选项用逗号分隔):

选项作用
--network pasta:--map-gw允许容器通过网关地址直接访问宿主
--network pasta:--mtu,1500设置容器内 tap 接口 MTU 为 1500 字节
--network pasta:-t,auto,-u,auto,-T,auto,-U,auto基于观察到的绑定端口,自动启用宿主机与容器两侧的端口转发
--network pasta:-T,5201将容器 TCP 5201 端口转发到宿主(走回环接口,性能更佳)
--network pasta:-t,5201将宿主 TCP 5201 端口转发到容器

所有 pasta 选项也可在containers.conf[network]pasta_options键中统一配置。

Pasta 实战示例

下面的示例演示两个 rootless 容器如何通过端口映射通信,以及宿主网络中的客户端如何访问 rootless Web 服务器。

首先运行 rootless Web 服务器,将容器 80 端口映射到非特权端口 8080:

$ podman run -d --name webserver -p 8080:80 quay.io/libpod/banner 17ea33ccd7f55ff45766b3ec596b990a5f2ba66eb9159cb89748a85dc3cebfe0

由于 rootless 容器之间无法直接通过 IP 地址进行 TCP/IP 通信,需要借助宿主机 IP 与端口映射。先查询宿主接口 IP:

$ ip address show eth0 3: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000 link/ether 3c:e1:a1:c1:7a:3f brd ff:ff:ff:ff:ff:ff altname eth0 inet 192.168.99.109/24 brd 192.168.99.255 scope global dynamic noprefixroute eth0 valid_lft 78808sec preferred_lft 78808sec inet6 fe80::5632:6f10:9e76:c33/64 scope link noprefixroute valid_lft forever preferred_lft forever

从另一个 rootless 容器中,使用宿主 IP 与端口即可成功通信:

$ podman run -it quay.io/libpod/banner curl http://192.168.99.109:8080 ___ __ / _ \___ ___/ /_ _ ___ ____ / ___/ _ \/ _ / ' \/ _ `/ _ \ /_/ \___/\_,_/_/_/_/\_,_/_//_/

宿主机外的客户端同样可以借助 IP 与端口访问:

(outside_host): $ curl http://192.168.99.109:8080 ___ __ / _ \___ ___/ /_ _ ___ ____ / ___/ _ \/ _ / ' \/ _ `/ _ \ /_/ \___/\_,_/_/_/_/\_,_/_//_/

容器与 Pod 之间的通信

大多数容器用户都熟悉容器间及容器与外部世界的通信方式:通常每个容器拥有独立的 IP 地址与网络信息,通过常规 TCP/IP 手段(IP 地址,或基于容器名的 DNS 名称)互相通信。但Pod 是一个或多个容器的集合,因此继承了一些特殊性。

按定义,Podman Pod 中的所有容器共享同一个网络命名空间——这意味着它们拥有相同的 IP 地址、MAC 地址与端口映射。因此,Pod 内容器之间可以方便地使用localhost通信。

上图描绘了一个挂接在桥接网络上的 Pod:Pod 内"装"有 db 与 web 两个容器。由于共享网络命名空间,二者可通过localhost(127.0.0.1)互相通信;同时它们也都能通过Pod 自身分配到的 IP 地址(以及适用的 DNS 名称)被外部寻址。

这一设计意味着:在 pasta 模式下被"隔离"的容器,一旦放进同一个 Pod,即可像在桥接网络中一样使用 localhost 自由互访,这正是 pasta 场景下推荐用 Pod 组织多容器应用的根本原因。

小结与排障要点

  • 身份决定默认网络:rootful 默认 netavark 桥接(容器拥有可路由 IP),rootless 默认 pasta(用户态网络,容器无独立 IP);
  • 端口映射是外部访问的统一入口:无论哪种模式,外部客户端通常都经宿主 IP + 映射端口访问容器,语法遵循[[hostIP:][hostPort]:]containerPort[/protocol]
  • macvlan 仅限 root,容器直接暴露在局域网,需自行管理 DHCP(netavark v1.6+/Podman v4.5+)或静态子网,并注意宿主防火墙放行;
  • rootless 端口受限:1024 以下端口需要特权,可用sysctl net.ipv4.ip_unprivileged_port_start调整;
  • 容器不通先查防火墙:重载防火墙可能清掉 netavark 的 iptables 规则,rootful 容器可用podman network reload恢复;
  • 容器互访:rootless 场景下通过宿主端口映射,或直接放入同一 Pod 共享网络命名空间以 localhost 互访;
  • rootless 网络命名空间排查:使用podman unshare --rootless-netns进入容器网络命名空间查看。

关于 rootless 环境的前置准备(/etc/subuid/etc/subgid配置、pasta 安装要求等),可进一步参阅 docs/tutorials/rootless_tutorial.md;--network各模式的完整选项清单见 options/network.md,端口发布细节见 options/publish.md。

  • 容器运行时
  • 云原生
  • CLI

【免费下载链接】podman

Podman: A tool for managing OCI containers and pods.

项目地址:https://gitcode.com/gh_mirrors/po/podman
点击查看免费下载

相关推荐

上一篇:高级特性解析:DeferredTexturing延迟贴花系统与聚类技术应用
下一篇:CUE多环境配置:开发、测试、生产环境的统一管理终极指南

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/20 4:08:48

GetQzonehistory|零门槛导出QQ空间全部历史说说

GetQzonehistory&#xff5c;零门槛导出QQ空间全部历史说说 【免费下载链接】GetQzonehistory 获取QQ空间发布的历史说说 项目地址: https://gitcode.com/GitHub_Trending/ge/GetQzonehistory 网页版翻不到几年前&#xff0c;QQ空间旧说说到底怎么备份 网页版QQ空间只能…

作者头像 李华
网站建设 2026/9/20 4:08:28

Codex账号切换与第三方API接入报错排查指南:从配置到会话恢复

最近在折腾 Codex 的人越来越多了&#xff0c;不光是拿它当终端里的 AI 编程助手&#xff0c;还有不少人为了省订阅费、换模型、切账号&#xff0c;把它接到第三方 API 上。结果就是——安装 5 分钟&#xff0c;排错两小时。尤其是涉及 ChatGPT 账号切换&#xff08;比如个人号…

作者头像 李华
网站建设 2026/9/20 4:05:57

Codex PPT Skill 实测:五个技能包对比与组合工作流

1. 为什么我要把 Codex 的 PPT Skill 挨个试一遍用 Codex 做 PPT 这件事&#xff0c;我一开始是持怀疑态度的。原因很简单&#xff1a;过去两年我试过不下十款号称能“一键生成演示文稿”的工具&#xff0c;结果大多是把一段文字硬塞进模板里&#xff0c;排版全靠运气&#xff…

作者头像 李华
网站建设 2026/9/20 4:05:38

GD32嵌入式sin函数优化:定点查表法提速14倍实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/20 4:02:04

ChatTTS-ui 本地部署教程:三步跑通语音合成服务,含 API 接入

ChatTTS-ui 本地部署教程&#xff1a;三步跑通语音合成服务&#xff0c;含 API 接入 【免费下载链接】ChatTTS-ui 一个简单的本地网页界面&#xff0c;使用ChatTTS将文字合成为语音&#xff0c;同时支持对外提供API接口。A simple native web interface that uses ChatTTS to s…

作者头像 李华