Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
2.2k views
in Technique[技术] by (71.8m points)

docker - Why a service configured with only `expose` is able to communicate with internet?

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:

According to this answer, 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.

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 

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:*
...

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

I can verify that only the 3000/TCP port of foo service is opened:

PORT     STATE SERVICE
3000/tcp open  ppp

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?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

The answer to which you have linked is old and incorrect.

  1. 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.

    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.

  2. 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
    

    The first rule passes packets that are part of an existing TCP connection. This permits the return packets for your outbound connections.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...