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?
The answer to which you have linked is old and incorrect.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With