Podman 的网络栈使用两种不同的方式,具体取决于容器是无 root 权限(rootless)还是有 root 权限(rootfull)。当是有 root 权限(rootfull)时,即由 root(或同等权限)用户运行,Podman 主要依赖于 container-networking-plugins 项目。当是无 root 权限(rootless)时,即由普通用户运行,Podman 则使用 slirp4netns 项目。
根据定义,Podman pod 中的所有容器共享相同的网络命名空间。这意味着它们将拥有相同的 IP 地址、MAC 地址和端口映射。你可以通过使用 localhost 方便地在 pod 内的容器之间进行通信。
安装 Podman 软件包时,默认网络配置通常会安装到 /etc/cni/net.d 目录下,文件名为 87-podman-bridge.conflist。此外,默认网络名称在 /usr/share/containers/libpod.conf 文件中通过 cni_default_network 键来定义。在未修改的 libpod.conf 文件中,默认网络名称与软件包提供的默认配置名称一致。如果想要修改其任何默认设置,可以将 libpod.conf 文件复制到 /etc/cont
要为 Rootfull 创建新网络,请使用 podman network 命令。你可以通过命令标志自定义网络,也可以在之后手动编辑进行自定义。podman network create命令会为你提供新创建的网络配置文件路径:
$ sudo podman network create
/etc/cni/net.d/cni-podman4.conflist要显示当前配置的网络,请使用 podman network ls 命令;要删除指定的一个或多个网络,请使用 podman network rm。
注意:所有 podman network 命令仅适用于 Rootfull。
请查看下面的示例,了解如何让 Rootfull 之间实现各种形式的通信。与许多网络主题一样,根据限制条件和需求,实现特定结果的方法有多种。这些示例展示的是其中最简单的方法。
要在主机容器系统和 nginx 容器之间进行通信,请使用端口映射,这可以通过 podman port 命令来查看:
# podman run -dt --rm --publish-all alpine_nginx
34e3b5c686baa2298c37475864457e1b3a383c6d172266a8847257a33d790cc4
# podman port -l
80/tcp -> 0.0.0.0:40109
# curl http://localhost:40109
podman rulez在同一网络上的两个 Rootfull 之间进行通信,可以通过使用它们的 IP 地址来实现:
# podman run -dt --rm --name nginx alpine_nginx
2e383ec1ca1873c3665e975bbaf40f98020a288534f686ce08fb243d321a653c
# sudo podman inspect -f "{{.NetworkSettings.IPAddress}}" nginx
10.88.6.9
# podman run -it --rm alpine_nginx /bin/sh
/ # curl http://10.88.6.9
podman rulez在一个 Pod 中的两个容器之间进行通信可能是所有方法中最简单的。因为它们处于相同的网络命名空间中,所以可以使用 localhost:
[root@localhost libpod]# podman run -dt --pod new:mypod --rm --name nginx alpine_nginx
b72432387f603cd4da14348537cfad6b85424ee5dbc1e3af79a527b01c2e59a6
[root@localhost libpod]# podman run --pod mypod -it --rm alpine_nginx /bin/sh
/ # curl http://localhost
podman rulez当以无 root 权限用户身份使用 Podman 时,网络设置是自动的。从技术上讲,容器本身没有 IP 地址,因为没有 root 权限,就无法实现网络设备关联。此外,从无 root 权限容器中执行 ping 操作无法生效,因为它缺少 ping 命令所需的 CAP_NET_RAW 安全能力。如果想要从无 root 权限容器内部进行 ping 操作,可以使用以下 sysctl 命令允许用户发送 ICMP 数据包:
# sysctl -w "net.ipv4.ping_group_range=0 2000000"此操作将允许这些组内的任何进程发送ping数据包。
要在两个或多个无 root 权限容器之间进行通信,有两种选择。最简单的方法是将所有容器放入一个单独的 Pod 中。这些容器随后可以使用 localhost 进行通信。另一个好处是,无需打开端口,容器之间就可以直接通信。
第二种选择是使用端口映射技术将端口映射到容器,然后使用这些端口将流量定向到特定的容器。查看下面的示例,了解如何在无 root 权限容器之间实现各种形式的通信。如前所述,根据限制和需求,有多种方法可以实现特定的结果。这些示例展示了其中最简单的方法。
要在容器主机和无 root 权限容器之间进行通信,你只需使用端口映射,并将流量定向到 Podman 分配的端口即可:
$ podman run -dt --rm -P alpine_nginx
95faeb0c9010d78fd6073ae4aea2e8a8baf10b77391218790682637c51c3ab4e
[bbaude@localhost libpod (master)]$ podman port -l
80/tcp -> 0.0.0.0:38997
[bbaude@localhost libpod (master)]$ curl http://localhost:38997
podman rulez有多种并非轻而易举的方法可以实现两个无 root 权限容器之间的通信。最直接的方法是使用上一个示例中的端口映射技术,然后从第二个容器与主机进行通信:
$ podman run -dt --rm -P alpine_nginx
d73e09326390d5de9a8784daf25a13093e9012c7a1a8bef1febc585fd94f8a5f
$ podman port -l
80/tcp -> 0.0.0.0:35527
$ ip addr show enp0s31f6
2: enp0s31f6: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
link/ether c8:5b:76:f3:e9:f8 brd ff:ff:ff:ff:ff:ff
inet 192.168.1.115/24 brd 192.168.1.255 scope global dynamic noprefixroute enp0s31f6
valid_lft 78662sec preferred_lft 78662sec
inet6 fe80::ee11:476a:eea:7924/64 scope link noprefixroute
valid_lft forever preferred_lft forever
[bbaude@localhost libpod (master)]$ podman run -it --rm alpine_nginx /bin/sh
/ # curl http://192.168.1.115:35527[4] [5]
podman rulez这通常是两个无 root 权限容器进行通信的最简单方法。将它们放在一个 Pod 中,就可以通过 localhost 直接通信:
$ podman run -dt --rm --pod new:mypod alpine_nginx
e2add389417957f2871503aeda82b1d826db3c8e00a5241528b59bf5060d5d94
[bbaude@localhost libpod (master)]$ podman run -it --rm --pod mypod alpine_nginx /bin/sh
/ # curl http://localhost
podman rulez使用 Podman 时要记住,在为有 root 权限和无 root 权限的容器实现网络的方式上存在一些细微差别。对于多个容器之间的通信,最简单的方法通常是将这些容器放在同一个 pod 中,这样它们就可以共享一个网络命名空间。对于无 root 权限的用户,如果容器不在同一个 pod 中,那么就必须使用主机上暴露的端口才能让它们相互通信。