问题
我有一个 Docker 服务容器,它的端口为 *:8080
。
- 我无法通过
localhost:8080
访问容器。使用 Chrome 或者curl
时会一直卡住。 - 但是如果我使用其他本地IP,例如
127.0.0.1
,就可以访问容器。
这让我很困惑,因为在我的 hosts
文件中,localhost
被重定向到 127.0.0.1
。
为什么会这样?这与IPv4/IPv6双栈有关系吗?
环境
我正在使用基于 Ubuntu 的 PopOS,并启用了 Docker Swarm。
我使用此测试堆栈文件:traefik.docker-compose.yml
:
version: '3'
services:
reverse-proxy:
image: traefik # The official Traefik docker image
command: --api --docker # Enables the web UI and tells Traefik to listen to docker
ports:
- "80:80" # The HTTP port
- "8080:8080" # The Web UI (enabled by --api)
volumes:
- /var/run/docker.sock:/var/run/docker.sock # So that Traefik can listen to the Docker events
为了运行堆栈,我使用:
docker stack deploy -c traefik.docker-compose.yml traefik
一旦服务启动,我确认它通过以下两种方式监听 8080
端口:
docker service ls
ID NAME MODE REPLICAS IMAGE PORTS
4ejfsvenij3p traefik_reverse-proxy replicated 1/1 traefik:latest *:80->80/tcp, *:8080->8080/tcp
sudo ss -pnlt | grep 8080
LISTEN 3 128 *:8080 *:* users:(("dockerd",pid=2119,fd=45))
供参考,这是我 /etc/hosts
的内容:
127.0.0.1 localhost
::1 localhost ipv6-localhost
127.0.1.1 pop-os.localdomain pop-os pop1810x220
我只是用 curl
进行测试:
- 可以使用:
curl http://127.0.0.1:8080
- 会卡住不动:
curl http://localhost:8080
curl 'http://[::1]:8080'
(IPv6版的localhost
)怎么样? - Charles Duffylocalhost
出了什么问题。请记住,/etc/hosts
不是名称解析中唯一涉及的部分 - 您需要评估系统的NSS模块以了解所有组件的作用,因此您不能相信/etc/hosts
会覆盖所有其他内容而不调查您的发行版(或本地覆盖的系统管理员)如何设置名称解析。 - Charles Duffynetstats -tulpn
,就会发现正常的容器是通过docker-proxy
监听的,而 swarm 则是通过dockerd
监听的。我不确定这是什么原因导致的差异。希望能有更新解决方案。 - Yuanyi Wu