在 Podman 世界中,我们经常被问到的一个问题是:“为什么我的容器不能通过名称解析其他容器?”在许多情况下,答案是……因为您正在运行的网络禁用了名称解析。事实上,您很可能正在运行*默认*网络;而该网络确实没有启用名称解析。接下来的问题是“为什么 Podman 会这样做?”标准答案是什么?“因为 Docker 就是这样做的,人们希望尽可能与 Docker 兼容。”
让我们通过示例来仔细看看。我将使用由特权用户创建的容器,因为这有点像 Docker 的标准。在每个示例中,我将在同一个网络上启动两个命名容器,并展示名称解析的成功与失败。
在第一个示例中,我们确认只存在默认的 Podman 网络。它被称为 podman 并且无法删除。请记住,默认网络没有启用名称解析,任何尝试都会失败。请注意,test2 无法通过名称解析 test1。
$ sudo podman network ls NETWORK ID NAME DRIVER 2f259bab93aa podman bridge $ sudo podman run --rm -dt --name test1 alpine top 3703d80740513421772db407972111ad6f535f5ca214f11ddb714a7d64ee140c $ sudo podman run --rm -it --name test2 alpine /bin/sh / # ping test1 ping: bad address 'test1' / # exit
一个解决方案是创建一个我称之为 new 的新网络。默认情况下,所有创建的网络都启用了名称解析,并且必须选择退出才能禁用它。然后我以与之前相同的方式运行两个容器,不同的是我指定了一个不同的网络,并且名称解析按预期工作。
$ sudo podman network create new new $ sudo podman network ls NETWORK ID NAME DRIVER d9376e135b46 new bridge 2f259bab93aa podman bridge $ sudo podman run --rm -dt --name test1 --network new alpine top f5a8d256f29221676dc7fca36bca0b680dd7de4a5aa20af2a9d9a02072b34fc7 $ sudo podman run --rm -it --name test2 --network new alpine /bin/sh / # ping test1 PING test1 (10.89.0.2): 56 data bytes 64 bytes from 10.89.0.2: seq=0 ttl=42 time=0.114 ms 64 bytes from 10.89.0.2: seq=1 ttl=42 time=0.107 ms ^C
我前面提到,Podman 这样表现的原因之一是因为 Docker 也是如此。使用 Docker 的默认网络进行相同的测试,我们可以看到名称解析也无法工作。解决方案与 Podman 相同,您需要创建一个新网络并在其中运行容器。
ubuntu@ubuntu:~$ sudo docker network ls NETWORK ID NAME DRIVER SCOPE cb0c4d38339a bridge bridge local 5d0fce56bcad host host local 18c31437e8d0 none null local ubuntu@ubuntu:~$ sudo docker run -dt --name test1 alpine top b23e15c969d253f33f99bd2cecb00b4b061e2a7605190eae683f546692ea34cc ubuntu@ubuntu:~$ sudo docker run -it --name test2 alpine /bin/sh / # ping test1 ping: bad address 'test1' / # exit
如果您总是希望容器具有名称解析,但又不想为每个容器都指定不同的网络,您可以将任何网络设为容器的默认网络。这需要在 /etc/containers/containers.conf 中进行少量更改(如果 containers.conf 不存在,则只需添加)。
$ sudo cat /etc/containers/containers.conf [network] default_network = "new" $ sudo podman run -dt --rm --name test1 alpine top 18d033aeec0640100bf8165c23b01e55c03fbd5bc320d874a3f4f01f755512c7 $ sudo podman run -it --rm --name test2 alpine /bin/sh / # ping test1 PING test1 (10.89.0.5): 56 data bytes 64 bytes from 10.89.0.5: seq=0 ttl=42 time=0.137 ms 64 bytes from 10.89.0.5: seq=1 ttl=42 time=0.106 ms ^C --- test1 ping statistics --- 2 packets transmitted, 2 packets received, 0% packet loss round-trip min/avg/max = 0.106/0.121/0.137 ms / # exit
请注意,这里 new 是默认网络,并且名称解析有效。
我们也被问到,为什么 Podman 会模仿 Docker 的这种行为,尤其是在很多人都希望默认启用名称解析的情况下。我个人的答案是两方面的。我不知道 Docker 为什么这样做,但我不想去探究,而且当我们与 Docker 不完全兼容时,Podman 用户会指责我们。我*不想*默认启用名称解析的第二个原因是,容器运行需要*稍微*长一点的时间。Podman 总是需要使用 netavark 来设置网络,但当启用名称解析时,netavark 还必须调用 aardvark-dns。所需的时间可能微乎其微,但在某些情况下这很重要。

Brent Baude
高级首席软件工程师,Podman 架构师
发表回复