为什么只配置了 `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
...
公开端口而不将它们发布到主机——它们只能被链接的服务访问.只能指定内部端口.
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 互联网.如果端口没有暴露/打开以接收它,它如何得到它的答案?
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.
默认情况下,容器具有出站 Internet 访问权限.出站访问通过主机防火墙 nat
表(以及 filter
FORWARD
链中的相应规则)中的简单 NAT 规则进行管理.例如,在我运行 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屋!