为什么仅配置了"expose"的服务能够与互联网通信? [英] Why a service configured with only `expose` is able to communicate with internet?
问题描述
某些事情使我对Docker网络感到困惑.我有一个 docker-compose.yml
文件,可以这样简化:
Something confuse me about docker networking. I've a docker-compose.yml
file which can be simplified like this:
version: '3.8'
services:
foo:
...
networks:
- main_network
ports:
- "3000:3000"
bar:
...
networks:
- main_network
expose:
- "5000"
networks:
main_network:
根据此答案,公开
...
暴露端口而不将其发布到主机上-只有链接的服务才能访问它们.只能指定内部端口.
Expose ports without publishing them to the host machine - they’ll only be accessible to linked services. Only the internal port can be specified.
如果这是真的, bar
应该只将5000端口公开给 foo
服务.而且它似乎按预期工作.如果可以,我将 bash
运行到 bar
服务中并执行:
If this is true, bar
should only expose the 5000 port to foo
service. And It seems to work as expected. If, I run bash
into bar
service and execute:
$ ss -lntu
5000端口已正确打开:
The 5000 port is opened correctly:
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:*
...
按预期,从容器外部,例如,使用Web浏览器,我无法连接到该主机.另外,如果我跑步
As expected, from outside of my container, using a web browser for example, I cannot connect to this host. Also, If I run
$ nmap -p1-65535 127.0.0.1
我可以验证仅 foo
服务的3000/TCP端口已打开:
I can verify that only the 3000/TCP port of foo
service is opened:
PORT STATE SERVICE
3000/tcp open ppp
所以,我不明白的是,IRL,我的 bar
服务能够在线连接到Mongo Atlas或ping Internet.如果未暴露/未打开端口以接收端口,它将如何得到答案?
So, what I don't understand is that IRL, my bar
service is able to connect to Mongo Atlas online or ping internet. How does it get it's answer if the ports aren't Exposed/Opened in order to receive it?
推荐答案
您所链接的答案是古老且错误的.
The answer to which you have linked is old and incorrect.
-
EXPOSE
关键字主要是禁止操作的关键字.它提供了很多信息(此映像将在这些端口上提供服务"),但是对操作没有任何影响.
The
EXPOSE
keyword is primarily a no-op. It's informative ("this image will offer services on these ports"), but it doesn't have any operational impact.
在较旧的Docker版本中, EXPOSE
关键字可以用于链接容器的服务发现,但是(a)它仍然没有任何操作影响-端口是否可用,无论是否没有匹配的 EXPOSE
-容器链接"已弃用了相当长一段时间.
In older versions of Docker, the EXPOSE
keyword could be used for service discovery by linked containers, but (a) it still didn't have any operational impact -- the ports were available whether or not there was a matching EXPOSE
-- and container "linking" has been deprecated for a quite some time.
默认情况下,容器具有出站互联网访问权限.出站访问通过主机防火墙 nat
表中的简单NAT规则(以及 filter
FORWARD
链中的相应规则)进行管理.例如,在运行Docker 20.10.2的系统上,在 FORWARD
链中,我有:
Containers have outbound internet access by default. Outbound access is managed with a simple NAT rule in the host firewall nat
table (and corresponding rules in the filter
FORWARD
chain). E.g., on a system where I am running Docker 20.10.2, in the FORWARD
chain I have:
-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
第一个规则传递作为现有TCP连接一部分的数据包.这样可以为您的出站连接返回数据包.
The first rule passes packets that are part of an existing TCP connection. This permits the return packets for your outbound connections.
这篇关于为什么仅配置了"expose"的服务能够与互联网通信?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!