I know by default docker creates a virtual bridge docker0
, and all container network are linked to docker0
.
As illustrated above:
- container
eth0
is paired withvethXXX
vethXXX
is linked todocker0
same as a machine linked to switch
But what is the relation between docker0
and host eth0
?
More specifically:
- When a packet flows from container to docker0, how does it know it will be forwarded to eth0, and then to the outside world?
- When an external packet arrives to eth0, why it is forwarded to docker0 then container? instead of processing it or drop it?
Question 2 can be a little confusing, I will keep it there and explained a little more:
- It is a return packet that initialed by container(in question 1): since the outside does not know container network, the packet is sent to host
eth0
. How it is forwarded to container? I mean, there must be some place to store the information, how can I check it?
Thanks in advance!
After reading the answer and official network articles, I find the following diagram more accurate that docker0
and eth0
has no direct link,instead they can forward packets:
http://dockerone.com/uploads/article/20150527/e84946a8e9df0ac6d109c35786ac4833.png
You can detect the relation by network interface
iflink
from a container andifindex
on the host machine.Get
iflink
from a container:Then find this
ifindex
among interfaces on the host machine:There is no direct link between the default
docker0
bridge and the hosts ethernet devices. If you use the--net=host
option for a container then the host and containers network stack will be linked.The
docker0
bridge has the.1
address of the Docker network assigned to it, this is usually something around a 172.17 or 172.18.Containers are assigned a veth interface which is attached to the
docker0
bridge.Containers created on the default Docker network receive the
.1
address as their default route.Docker uses NAT MASQUERADE for outbound traffic from there and it will follow the standard outbound routing on the host, which may or may not default to
eth0
.iptables handles the connection tracking and return traffic.
If you are asking about return outbound traffic, see iptables above.
If you mean new inbound traffic, Packets are not forwarded into a container by default. The standard way to achieve this is to setup a port mapping. Docker launches a daemon that listens on the host on port X and forwards to the container on port Y.
I'm not sure why NAT wasn't used for inbound traffic as well. I've run into some issues trying to map large numbers of ports into containers which led to mapping real world interfaces completely into containers.