Docker networking

Let's now review how docker networking works before getting into Kubernetes networking. For container networking, there are different modes: bridge, none, overlay, macvlan, and host. We've learned about the major modes in Chapter 2DevOps with Containers. Bridge is the default networking model. Docker creates and attaches a virtual Ethernet device (also known as veth) and assigns a network namespace to each container.

The network namespace is a feature in Linux that is logically another copy of a network stack. It has its own routing tables, ARP tables, and network devices. This is a fundamental concept of container networking.

Veth always comes in pairs; one is in the network namespace and the other is in the bridge. When the traffic comes into the host network, it will be routed into the bridge. The packet will be dispatched to its veth, and will go into the namespace inside the container, as shown in the following diagram:

Let's take a closer look at this. In the following example, we'll use a minikube node as the docker host. First, we'll have to use minikube ssh to ssh into the node because we're not using Kubernetes yet. After we get into the minikube node, we'll launch a container to interact with us:

// launch a busybox container with `top` command, also, expose container port 8080 to host port 8000.
# docker run -d -p 8000:8080 --name=busybox busybox top
737e4d87ba86633f39b4e541f15cd077d688a1c8bfb83156d38566fc5c81f469 

Let's see the implementation of outbound traffic within a container. docker exec <container_name or container_id> can run a command in a running container. Let's use ip link list to list all the interfaces:

// show all the network interfaces in busybox container
// docker exec <container_name> <command>
# docker exec busybox ip link list
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1
   link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: sit0@NONE: <NOARP> mtu 1480 qdisc noop qlen 1
   link/sit 0.0.0.0 brd 0.0.0.0
53: eth0@if54: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> 
mtu 1500 qdisc noqueue link/ether 02:42:ac:11:00:07 brd ff:ff:ff:ff:ff:ff

We can see that we have three interfaces inside the busybox container. One has an ID of 53 with the name eth0@if54. The number after if is the other interface ID in the pair. In this case, the pair ID is 54. If we run the same command on the host, we can see that the veth in the host is pointing to eth0 inside the container:

// show all the network interfaces from the host
# ip link list
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue
state UNKNOWN mode DEFAULT group default qlen 1 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc
pfifo_fast state UP mode DEFAULT group default qlen
1000 link/ether 08:00:27:ca:fd:37 brd ff:ff:ff:ff:ff:ff ... 54: vethfeec36a@if53: <BROADCAST,MULTICAST,UP,LOWER_UP>
mtu 1500 qdisc noqueue master docker0 state UP mode
DEFAULT group default link/ether ce:25:25:9e:6c:07 brd ff:ff:ff:ff:ff:ff link-netnsid 5

We have a veth on the host named vethfeec36a@if53. This pairs with eth0@if54 in the container network namespace. veth 54 is attached to the docker0 bridge, and eventually accesses the internet via eth0. If we take a look at the iptables rules, we can find a masquerading rule (also known as SNAT) on the host that docker creates for outbound traffic, which will make internet access available for containers:

// list iptables nat rules. Showing only POSTROUTING rules which allows packets to be altered before they leave the host.
# sudo iptables -t nat -nL POSTROUTING
Chain POSTROUTING (policy ACCEPT)
target     prot opt source               destination
...
MASQUERADE  all  --  172.17.0.0/16        0.0.0.0/0
...

On the other hand, as regards the inbound traffic, docker creates a custom filter chain on prerouting and dynamically creates forwarding rules in the DOCKER filter chain. If we expose a container port, 8080and map it to a host port, 8000, we can see that we're listening to port 8000 on any IP address (0.0.0.0/0), which will then be routed to container port 8080:

// list iptables nat rules
# sudo iptables -t nat -nL
Chain PREROUTING (policy ACCEPT)
target     prot opt source               destination
...
DOCKER     all  --  0.0.0.0/0            0.0.0.0/0            ADDRTYPE match dst-type LOCAL
...
Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination
DOCKER     all  --  0.0.0.0/0           !127.0.0.0/8          ADDRTYPE match dst-type LOCAL
...
Chain DOCKER (2 references)
target     prot opt source               destination
RETURN     all  --  0.0.0.0/0            0.0.0.0/0
...
DNAT       tcp  --  0.0.0.0/0            0.0.0.0/0            tcp dpt:8000 to:172.17.0.7:8080
...

Now that we know how a packet goes in/out of containers, let's look at how containers in a pod communicate with each other.

User-defined custom bridges:
As well as the default bridge network, docker also supports user-defined bridges. Users can create the custom bridge on the fly. This provides better network isolation, supports DNS resolution through embedded DNS server, and can be attached and detached from the container at runtime. For more information, please refer to the following documentation: https://docs.docker.com/network/bridge/#manage-a-user-defined-bridge.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset