使用 pasta 的 –map-guest-addr 选项
从 Podman 5.0 开始,我们默认使用 “pasta” 作为无根网络应用程序来为无根容器提供网络连接。与我们之前的默认值 slirp4netns 相比,pasta 的工作方式略有不同。例如,pasta 默认情况下不使用网络地址转换 (NAT)。这意味着它会将主机地址复制到容器中,这意味着主机和容器命名空间都使用相同的 IP 地址。反过来,这意味着如果你尝试从容器连接到主机 IP,它将引用自身,而不是主机。许多用户对这种情况下的主机和容器之间缺乏连接感到困惑。
此外,podman 很长一段时间以来一直在容器中提供 host.containers.internal 主机条目,以允许容器访问主机。Podman 试图足够聪明,不会添加容器命名空间中已使用的相同主机 IP 以避免此问题。但是,在许多情况下,主机只有一个 IP 地址(不包括 localhost),因此在这种情况下,Podman 无法为 host.containers.internal
提供合适的 IP 地址;因此,该条目未添加。
由于这是一个常见的用例,pasta 开发人员添加了一个名为 --map-guest-addr <ip>
的新 pasta 选项,允许用户选择命名空间内的给定 IP 地址来引用主机命名空间上的实际主机 IP。从 Podman 5.3 开始,我们将默认使用此选项:地址 169.254.1.2 将映射到主机。
我们还确保 host.containers.internal 条目将设置为该 IP,这将使主机名再次工作,即使没有辅助 IP 可用;因此,请不要对 IP 进行硬编码,而应使用 host.containers.internal
代替。
还可以选择使用另一个 IP,就像使用任何其他 pasta 选项一样,你可以将其直接传递给 Podman,它会将其添加到 pasta 命令行中。在这种情况下,主机名也将被正确更新以使用新的正确 IP,例如:
$ podman run --network pasta:--map-guest-addr,10.0.0.1 quay.io/libpod/testimage:20241011 \
grep host.containers.internal /etc/hosts
10.0.0.1 host.containers.internal host.docker.internal
要使用 --map-guest-addr
,需要 passt 版本 2024_08_14 或更高版本,因此请确保已安装。如果存在旧版本,Podman 将保留旧行为,除非用户显式设置 --map-guest-addr
,否则不会出错。
Quadlet 无根容器启动
另一个 常见问题 是从 quadlet 创建的无根 systemd 单位无法在启动时启动。这是因为 pasta 需要网络完全启动才能启动;否则,如果你的网络设置时间足够长,你可能会在你的单位日志中收到“外部接口不可用”错误,并且容器没有启动。
虽然生成的 systemd 单位使用了 After=network-online.target
,但事实证明,这没有任何作用,因为 systemd 用户会话无法看到诸如 network-online.target 之类的系统单位。因此,systemd 忽略了该 After=
行,并且容器单位在网络准备就绪之前过早启动,导致启动时出现随机故障。
使用 podman 5.3,我现在为此实施了解决方案。打包程序需要确保将新的 podman-user-wait-network-online.service
单位放在用户(而不是系统)目录中,以便它可以在所有用户会话中使用。此单位只是通过每半秒轮询一次 systemctl is-active network-online.target 来等待系统 network-online.target 单位变为活动状态。这样,quadlet 不再为用户单位添加 After=network-online.target
,而是添加 After=podman-user-wait-network-online.service
,这保证了容器单位在网络准备就绪之前等待,并且 pasta 正确启动。手动实施了类似解决方法的用户应该能够再次删除它。
如果由于任何原因,你不需要或不希望你的单位等待网络准备就绪,那么你可以在 quadlet 文件中新添加的 [Quadlet]
部分中使用新的 DefaultDependencies=false
选项。
发表评论