我在绑定(bind)到 127.0.0.1:8888 的容器内运行服务.
我想将此端口公开给主机。
docker-compose 支持这个吗?

我在 docker-compose.yml 中尝试了以下操作但没有用。

expose:  
  - "8888" 
ports: 
  - "8888:8888" 

附言在我的情况下,将服务绑定(bind)到容器内的 0.0.0.0 是不可能的。

更新:提供一个简单的例子:
docker-compose.yml
version: '3' 
services:   
  myservice: 
    expose:  
      - "8888" 
    ports: 
      - "8888:8888" 
    build: . 
Dockerfile
FROM centos:7 
RUN yum install -y nmap-ncat 
CMD ["nc", "-l", "-k", "localhost", "8888"] 

命令:
$> docker-compose up --build 
$> # Starting test1_myservice_1 ... done 
$> # Attaching to test1_myservice_1 
 
$> nc -v -v localhost 8888 
$> # Connection to localhost 8888 port [tcp/*] succeeded! 
TEST 
$> 

输入后 TEST在控制台 连接关闭 ,这意味着 端口没有真正暴露 ,尽管最初的成功消息。我的真实服务也会出现同样的问题。
但是,如果我绑定(bind)到容器内的 0.0.0.0(而不是 localhost),一切正常。

请您参考如下方法:

通常答案是否定的,并且在几乎所有情况下,您都应该重新配置您的应用程序以监听 0.0.0.0。任何避免更改应用程序以监听容器内所有接口(interface)的尝试都应被视为增加项目技术债务的黑客行为。

为了扩展我的评论,默认情况下,每个容器都在其自己的网络命名空间中运行。容器内的环回接口(interface)与主机和其他容器中的环回接口(interface)是分开的。因此,如果您在容器内监听 127.0.0.1,则该网络命名空间之外的任何内容都无法访问该端口。这与在您的 VM 上监听环回并尝试从另一个 VM 连接到该端口没有什么不同,Linux 不允许您连接。

有一些解决方法:

  • 您可以破解 iptables 以转发连接,但我个人会避免这种情况。 Docker 很大程度上基于对 iptables 规则的自动更改,因此您的风险与该自动化发生冲突或在下次重新创建容器时被破坏。
  • 您可以在容器内设置一个代理,该代理监听所有接口(interface)并转发到环回接口(interface)。像nginx这样的东西会起作用。
  • 您可以在同一个网络命名空间中获取内容。

  • 最后一个有两种实现方式。在容器之间,您可以在另一个容器的网络命名空间中运行一个容器。这通常用于调试网络,这也是 pod 在 Kubernetes 中的工作方式。这是运行第二个容器的示例:
    $ docker run -it --rm --net container:$(docker ps -lq) nicolaka/netshoot /bin/sh 
    / # ss -lnt 
    State       Recv-Q Send-Q        Local Address:Port    Peer Address:Port 
    LISTEN      0      10                127.0.0.1:8888                  *:* 
    LISTEN      0      128             127.0.0.11:41469                  *:* 
    / # nc -v -v localhost 8888 
    Connection to localhost 8888 port [tcp/8888] succeeded! 
    TEST 
    / # 
    

    注意 --net container:... (我使用 docker ps -lq 来获取我实验室中最后启动的容器 ID)。这使得两个独立的容器在同一个命名空间中运行。

    如果您需要从 docker 外部访问它,您可以删除网络命名空间,并将容器直接附加到主机网络。对于一次性容器,这可以通过
    docker run --net host ... 
    

    在 compose 中,这看起来像:
    version: '3' 
    services:   
      myservice: 
        network_mode: "host" 
        build: . 
    

    你可以看到 docker compose documentation on this option here .这在 swarm 模式下不受支持,并且您不要在此模式下发布端口,因为您将尝试在相同的网络命名空间之间发布端口。

    旁注, expose这一切都不需要。它仅用于文档和一些自动化工具,但不会影响容器到容器的网络,也不会影响发布特定端口的能力。


    评论关闭
    IT序号网

    微信公众号号:IT虾米 (左侧二维码扫一扫)欢迎添加!