0

Premise:

I'm trying to pull together recent learning about network interfaces and ports and try to tie that new learning with Docker.

A quick summary of the things I learned relevant to this question:

  • Every computer can have multiple IP addresses, one for each network interface.
  • IP addresses are assigned to interfaces, not computers, etc.
  • A socket is an IP+port.
  • DHCP is often/likely what assigns an IP address to an interface.

As with many aspects of working with software, I first do things per the "ritual" that I learn, because "that's how it's done". Then with time and experience, I begin to ponder and probe into the whys and wherefores. So I'd like to tie this new learning with Docker.

The "ritual" I'd learned is that if a containerized application is listening at a TCP socket, you need to "expose" that socket's port so that traffic arriving at one of the host's interfaces at that port, gets "forwarded" to the container.
E.g. docker run -d -p 81:80 httpd sets things up so that if I point my web browser to 127.0.0.81, that HTTP/TCP/IP traffic is "forwarded" to the httpd container's port 80.

So when I point my web browser to 127.0.0.1:81, I see Apache's "It works!" message.

But also: if I point my web browser to 127.0.0.2:81 or 127.0.0.16:81, then also I see Apache's "It works!" message.

As I learned from the linked posts, DHCP assigned my NIC's interface the IP address 10.0.0.17, and if I point my web browser to 10.0.0.17:81, here again, I see Apache's "It works!" message.
It also works if I point the web browser of another PC on the same network to 10.0.0.17:81.


Question:

My primary question is: for which of the host PC's interfaces (IP addresses) are ports forwarded from host to container when you do docker run with the -p argument? By the noted observation, the answer appears to be "all interfaces" -- is that the case?

More broadly, though: what is the relationship between interfaces and ports between a host PC and Docker container?


What I have tried

I tried reading the docker run help-text, but its text on -p isn't at a level that I can relate it to the questions I'm asking:

-p, --publish list Publish a container's port(s) to the host

I tried running looking at ifconfig in the context of my PC and the running httpd container.
ifconfig on host PC:

$ ifconfig
docker0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 172.17.0.1  netmask 255.255.0.0  broadcast 172.17.255.255
        inet6 fe80::42:caff:fe23:f0f4  prefixlen 64  scopeid 0x20<link>
        ether 02:42:ca:23:f0:f4  txqueuelen 0  (Ethernet)
        RX packets 3079  bytes 322688 (322.6 KB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 6429  bytes 15942682 (15.9 MB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        inet6 ::1  prefixlen 128  scopeid 0x10<host>
        loop  txqueuelen 1000  (Local Loopback)
        RX packets 17975  bytes 1557651 (1.5 MB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 17975  bytes 1557651 (1.5 MB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

wlp1s0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 10.0.0.17  netmask 255.255.255.0  broadcast 10.0.0.255
        inet6 fe80::5f8c:c301:a6a3:6e35  prefixlen 64  scopeid 0x20<link>
        ether f8:59:71:01:89:cf  txqueuelen 1000  (Ethernet)
        RX packets 1672559  bytes 2237440808 (2.2 GB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 726083  bytes 113598143 (113.5 MB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

ifconfig in the running httpd container (I installed it with apt-get):

# ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 172.17.0.3  netmask 255.255.0.0  broadcast 172.17.255.255
        ether 02:42:ac:11:00:03  txqueuelen 0  (Ethernet)
        RX packets 1326  bytes 8916833 (8.5 MiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 1134  bytes 76866 (75.0 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        loop  txqueuelen 1000  (Local Loopback)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

Putting this question in the context of the above ifconfig output, what is the relationship between those interfaces on the host PC and the interfaces in the docker container?
From here, my understanding is that DHCP assigned 10.0.0.17 to the NIC on my host PC. But where does the 172.17.0.3 come from?

1 Answer 1

1

[NB: You seem to have three questions here, at least one of which is too broad to have a clear acceptable answer. Generally SuperUser works best if you only ask one narrowly-defined question per Question post.]

My primary question is: for which of the host PC's interfaces (IP addresses) are ports forwarded from host to container when you do docker run with the -p argument? By the noted observation, the answer appears to be "all interfaces" -- is that the case?

Yes.

More broadly, though: what is the relationship between interfaces and ports between a host PC and Docker container?

This is a bit too broad to answer well without pointing you back at Docker's networking documentation. Docker contains lots of different networking options that change the relationships between interfaces and ports between host PCs and Docker containers. It's very flexible.

But where does the 172.17.0.3 come from?

Docker's default networking mode, bridge networking, creates a software bridge (like a virtual Ethernet switch) on the host, and connects the container(s) to it via virtual network interfaces. Like a little virtual Ethernet LAN all within the host. It then uses NAT (much like a home gateway router would use) to allow your containers to reach the network beyond the host. The NAT uses the 172.17.0.0/16 subnet as its private subnet.

Docker uses that subnet because it is part of the RFC 1918 private address space, just like 192.168.0.0/16, 10.0.0.0/8, and the rest of 172.16.0.0/12.

It appears that Docker programmatically configures the containers with static addresses in that subnet (DHCP would needlessly complicate things).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.