为什么只配置了“expose”的服务能够与互联网通信?

sno*_*ogg 3 networking docker docker-compose

关于 docker 网络的一些事情让我感到困惑。我有一个docker-compose.yml可以像这样简化的文件:

version: '3.8'
services:
    foo:
        ...
        networks:
            - main_network
        ports:
            - "3000:3000"
    bar:
        ...
        networks:
            - main_network
        expose:
          - "5000"
networks:
    main_network:
Run Code Online (Sandbox Code Playgroud)

根据这个答案expose...

公开端口而不将它们发布到主机——它们只能被链接的服务访问。只能指定内部端口。

如果这是真的,bar应该只将 5000 端口公开给foo服务。它似乎按预期工作。如果,我运行bashbar服务和执行:

$ ss -lntu 
Run Code Online (Sandbox Code Playgroud)

5000端口正确打开:

Netid    State     Recv-Q  Send-Q   Local Address:Port    Peer Address:Port
...
tcp      LISTEN    0       128      0.0.0.0:5000          0.0.0.0:*
...
Run Code Online (Sandbox Code Playgroud)

正如预期的那样,从我的容器外部,例如使用 Web 浏览器,我无法连接到该主机。另外,如果我跑

$ nmap -p1-65535 127.0.0.1
Run Code Online (Sandbox Code Playgroud)

我可以验证foo打开了服务的 3000/TCP 端口:

PORT     STATE SERVICE
3000/tcp open  ppp
Run Code Online (Sandbox Code Playgroud)

所以,我不明白的是,IRL,我的bar服务能够在线连接到 Mongo Atlas 或 ping 互联网。如果端口没有暴露/打开以接收它,它如何得到它的答案?

lar*_*sks 12

您链接的答案既旧又不正确。

  1. EXPOSE关键字主要是空操作。它提供了信息(“此图像将在这些端口上提供服务”),但它不会对操作产生任何影响。

    在旧版本的 Docker 中,该EXPOSE关键字可用于链接容器的服务发现,但是 (a) 它仍然没有任何操作影响——无论是否存在匹配,端口都可用EXPOSE——以及容器“链接” "已被弃用一段时间。

  2. 默认情况下,容器具有出站 Internet 访问权限。出站访问通过主机防火墙nat表中的简单 NAT 规则(以及filter FORWARD链中的相应规则)进行管理。例如,在我运行 Docker 20.10.2 的系统上,在FORWARD链中我有:

    -A FORWARD -o docker0 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
    -A FORWARD -o docker0 -j DOCKER
    -A FORWARD -i docker0 ! -o docker0 -j ACCEPT
    -A FORWARD -i docker0 -o docker0 -j ACCEPT
    
    Run Code Online (Sandbox Code Playgroud)

    第一条规则传递属于现有 TCP 连接一部分的数据包。这允许出站连接的返回数据包。

  • 请注意,正如本答案中所述,“EXPOSE”关键字实际上在“Dockerfile”中已被弃用。但是“docker-compose.yml”中的“expose”仍然执行其预期功能:将端口暴露给其他服务。在我看来,OP的问题指的是后者。 (4认同)
  • 在 `docker-compose.yml` 中公开不会向其他服务公开端口:无论您是否使用 `expose` 关键字,服务都可以访问其他容器中的端口。它充其量只是提供严格的信息。 (2认同)
  • 对于第一个回复... EXPOSE 并未弃用:https://docs.docker.com/engine/reference/builder/ (2认同)