使用 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 的开发人员添加了一个新的 pasta 选项,名为 --map-guest-addr <ip>
,它允许用户在命名空间内选择一个给定的 IP 地址来引用主机命名空间上的实际主机 IP。从 Podman 5.3 开始,我们将默认使用此选项:地址 169.254.1.2 将映射到主机。
我们还确保 host.containers.internal 条目将设置为此 IP,这将使主机名再次起作用,即使没有辅助 IP 可用;因此,请不要硬编码 IP,而是使用 host.containers.internal
。
还可以选择使用另一个 IP,就像任何其他 pasta 选项一样,您可以直接将其传递给 Podman,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
选项。
发表回复