Docker compose端口转发无法正常工作

30

当我使用非常简单的命令来运行Docker时:

docker run -p 80:80 nginx

端口转发正常工作,当我使用浏览器 / curl 访问 localhost:80 时,可以获取nginx的“欢迎页面”。

同时,当我使用非常相似但是特定于docker-compose的配置时:

version: '3'
services:
  nginx:
    image: nginx
    ports:
     - "80:80"

当我执行docker-compose up并在浏览器中查看时,我看到无限加载,因此看起来端口转发未正确配置,但我无法理解配置中的错误。

这里提到的Nginx只是一个例子,因为它很简单,实际上,我在redis/mysql/java镜像中遇到了相同的问题,所以问题与nginx无关。

我还尝试了以下方法通过docker-compose启动容器:

docker-compose run -p 80:80 nginx

docker-compose run --service-ports nginx

但是没有运气,我得到了相同的结果。

在这两种情况下(docker rundocker-compose up),我都有相同的网络驱动程序类型-bridge

我比较了两种情况下的docker inspect <container id>结果:http://i.prntscr.com/obvxi0yESEa92znLDEu_PA.png

以及docker inspect <network id>的结果:http://i.prntscr.com/yyTpetvJSXa-dz4o9Pcl3w.png

ifconfig docker0的结果:

docker0   Link encap:Ethernet  HWaddr 02:42:f1:9a:b6:72  
          inet addr:172.17.0.1  Bcast:0.0.0.0  Mask:255.255.0.0
          inet6 addr: fe80::42:f1ff:fe9a:b672/64 Scope:Link
          UP BROADCAST MULTICAST  MTU:1500  Metric:1
          RX packets:174 errors:0 dropped:0 overruns:0 frame:0
          TX packets:837 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:47434 (47.4 KB)  TX bytes:107712 (107.7 KB)
的结果:

bridge name     bridge id               STP enabled     interfaces
br-f7adc3956101         8000.02427f870e7f       no
docker0         8000.0242f19ab672       no

在主机上运行ifconfig的结果为:https://pastebin.com/6ufWeYTE

在主机上运行route的结果为:

Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
default         gateway         0.0.0.0         UG    600    0        0 wlp4s0
link-local      0.0.0.0         255.255.0.0     U     1000   0        0 docker0
172.17.0.0      0.0.0.0         255.255.0.0     U     0      0        0 docker0
192.168.0.0     0.0.0.0         255.255.255.0   U     600    0        0 wlp4s0

使用官方网站提供的Linux安装说明,安装了dockerdocker-compose

主机操作系统:Ubuntu 17.04

更新:我尝试在组合配置中设置了“可连接”(attachable)网络属性,问题已得到解决。虽然仍然不清楚为什么会发生这种情况。

networks:
  default:
  attachable: true

我知道它不起作用是因为我无法连接到服务(nginx/数据库等),尽管我看到有尝试这样做(例如,浏览器不会立即返回“连接被拒绝”,而是尝试“加载”,数据库/Java等也发生了非常相似的情况)。 同时,在两种情况下(docker-compose up和docker run),'ps'命令显示正确的映射:0.0.0.0:80->80/tcp。 - XZen
不确定是否重要,但我在我的docker-compose.yml文件中不使用引号:ports:
  • 80:80 此外,在运行docker-compose up -d之后,docker ps的状态是什么?端口是否显示为映射?
- Chris Mitchell
我也会执行 nslookup 命令,以确保您已经连接成功。 - Mike Tung
1
端口是否被其他程序使用? - Innovative Inventor
1
我假设你正在使用docker-compose run而不是docker-compose up?如果是这样,你需要使用--service-ports来发布服务定义中的端口。 - Zymotik
显示剩余16条评论
4个回答

18
在我的情况下,我使用了docker-compose run命令但没有使用--service-ports参数,所以端口映射被忽略了。 示例: docker-compose.yml
version: "3"

services:
    app-host:
        image: nginx:1.19.0-alpine
        working_dir: /app
        volumes:
            - ./:/app/
        ports:
            - "80:3000"

命令

    docker-compose run --service-ports app-host

参考文献:讨论论坛 docker-compose文档


6

4
有人知道这个为什么有效吗? - Tom

0
我尝试在Compose配置中设置“可附加”的网络属性,问题得到了解决。虽然仍不清楚为什么会发生这种情况。
文章“Docker Stacks and Attachable networks”将可附加网络定义为一种Swarm覆盖网络类型。
这意味着在该网络上创建的服务将允许docker run命令:
docker service create --publish 80:80 --network=core-infra --name 
docker run --network=core-infra -ti ...

这些行可以在docker-compose.yml文件中指定,结果将是相同的:如果网络是可连接的,则docker run将能够使用它。

一旦您创建了容器,docker network inspect core-infra将显示网络的子网和其他诊断信息。

奇怪的是,自2.1以来,网络应该默认是可连接的,如docker-compose issue 4711所述。

可连接的网络有助于Docker Swarm服务与称为Swarm的先前编排版本进行互操作。
传统Swarm和Swarm Services之间的核心区别在于,传统提供允许以命令方式安排容器。声明性Swarm服务允许我们定义我们想要实现的最终状态,然后Swarm将应用并维护该状态。


OP没有使用Docker Swarm。 - Nicolae
我知道,但是attachable是专门为docker swarm引入的。如果它在这里有影响,我想记录它的官方角色。 - VonC

-1

我使用 docker-compose up 运行了这个程序,它正常工作。

version: '3'
services:
  nginx:
      image: nginx
      ports:
             - 80:80

1
尝试了这个配置的完全复制,不幸的是没有帮助。 - XZen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接