I. Why do we need to know about Docker Network
When you start using Docker on a large scale, you’ll find that you need to know a lot about the web. Docker, as the most popular lightweight container technology, has a lot of praiseworthy features, such as the image management of Docker. However, Docker also has many imperfections, and network is the weak part of Docker. Therefore, it is necessary for us to have a deep understanding of Docker’s network knowledge to meet higher network requirements. This paper first introduces the four network working modes of Docker itself, and then introduces some custom network modes.
II. Docker Network Theory
Docker uses Linux bridge (refer to Linux Virtual Network Technology) to create a Docker Container bridge (docker0) on the host machine. When Docker starts a Container, it will assign an IP address to the Container according to the network segment of Docker bridge, which is called container-ip. Meanwhile, the Docker bridge is the default gateway for each container. Because the containers in the host are connected to the same bridge in the same night, the containers can communicate directly with each other through the container-ip of the containers.
Docker bridge is a virtual network device created by the host, rather than a real network device. The external network cannot be addressed, which also means that the external network cannot access the Container through direct container-ip. If the container wants external access, it can be accessed by mapping the container port to the host (port mapping), which is enabled by the -p or -p parameter when Docker Run creates the container, and by accessing the container via [host IP]:[container port].
When you install Docker, it automatically creates three networks. You can list these networks using the following docker network ls command:
# docker network ls
NETWORK ID NAME DRIVER SCOPE
857db65319fa bridge bridge local
c16cf8722909 host host local
d39a88b56801 none null local
III. Docker’s four network modes
Network mode | configuration | instructions |
---|---|---|
Bridge pattern | –net=bridge | This mode assigns, sets IP, and so on to each container, connects the container to a Docker0 virtual bridge, and communicates with the host via the Docker0 bridge and Iptables NAT table configuration. |
Host mode | –net=host | Containers and hosts share a Network namespace. |
Container pattern | –net=container:NAME_or_ID | A container shares a Network namespace with another container. POD in Kubernetes is a Network namespace shared by multiple containers. |
None mode | –net=none | This mode turns off the network functionality of the container. |
3.1 bridge model
When the Docker process starts, a virtual bridge named docker0 is created on the host, and the Docker container started on that host is connected to this virtual bridge. The virtual bridge works like a physical switch, so that all containers on the host are connected via the switch to a two-layer network.
Assign an IP from the docker0 subnet to the container and set the docker0 IP address as the container’s default gateway. Create a pair of virtual network card veth pair devices on the host. Docker places one end of the veth pair device in the newly created container and names it eth0 (the container’s network card). The other end is placed in the host with a name similar to vethxxx, and adds the network device to the docker0 bridge. This can be viewed with the BRCTL show command.
The bridge mode is the default network mode for Docker. Without the –net parameter, it is the bridge mode. When Docker Run-P is used, Docker actually makes DNAT rules in iptables to realize the port forwarding function. You can see it using iptables -t nat-vnl.
Bridge mode is shown in the figure below:
3.2 the host mode
If the host mode is used when the container is started, then the container will not have a separate Network Namespace. Instead, the container will share a Network Namespace with the host. The container will not virtualize its own network card, configure its own IP, etc. Instead, it will use the host’s IP and port. However, other aspects of the container, such as the file system, process list, and so on, are still isolated from the host.
Container using host mode can directly use the host’s IP address to communicate with the outside world, and the service port inside the container can also use the host’s port, without the need for NAT. The biggest advantage of host is that the network performance is good, but the port already used on docker host can no longer be used, and the network isolation is poor.
The Host mode is shown in the figure below:
3.3 container pattern
This pattern specifies that a newly created container shares a Network Namespace with an existing container, rather than with the host. Instead of creating its own network card and configuring its own IP, the newly created container shares its IP, port range, and so on with a specified container. Also, the two containers are separated from each other except for the network aspects, such as file systems, process lists, etc. The processes of the two containers can communicate through LO network card devices.
Schematic diagram of Container pattern:
3.4 none mode
With the NONE pattern, the Docker container has its own Network Namespace, but there is no Network configuration for the Docker container. In other words, the Docker container has no network card, IP, route and other information. We need to add network card and configure IP for Docker container by ourselves.
In this network mode, the container only has LO loop network and no other network card. The NONE pattern can be specified when the container is created by –network=none. This type of network has no way to connect to the Internet, and a closed network is a good guarantee of container security.
None mode schematic diagram:
IV. Container communication in Bridge mode
4.1 Open state of firewall
In bridge mode, containers connected to the same bridge can communicate with each other (for security reasons, you can also disable communication between them by setting -icc =false in the DOCKER_OPTS variable so that the two containers can only communicate using -link).
Containers can also communicate with the outside world. If we look at the Iptable rule on the host, we can see this one
This rule converts packets with a source address of 172.17.0.0/16 (that is, packets generated from the Docker container) and not originating from the Docker0 network card to the address of the host network card. It’s a little hard to understand, but let me give you an example. Suppose the host has a network card of eth0, an IP address of 192.168.21.10/24, and a gateway of 192.168.21.255. Ping Baidu (www.baidu.com) from a container on the host with IP 172.17.0.1/16. The IP packet is first sent from the container to its default gateway, docker0. Once the packet reaches docker0, it reaches the host. The host’s routing table is then queried and it is found that the packet should be sent from the host’s eth0 to the host’s gateway 192.168.21.255/24. The packet is then forwarded to and sent from eth0 (IP_FORWARD forwarding for the host should already be on). At this point, the Iptable rule above comes into play and performs the SNAT translation on the packet, changing the source address to the address of eth0. Thus, to the outside world, the package is emitted from 192.168.21.10, and the Docker container is not visible to the outside world.
So, how does the outside machine access the Docker container’s services? We first create a container containing the Web application with the following command, mapping the container’s port 80 to the host’s port 80.
docker run -itd --name=nginx_bridge --net=bridge -p 80:80 nginx
Then look at the changes to the Iptable rule, and find that there is an additional rule:
-A DOCKER ! -i docker0-p TCP -m TCP --dport 80-j DNAT --to-destination 172.17.0.2:80
This rule is used to convert TCP traffic received by host eth0 to 172.17.0.2:80, which is the Docker container we created above. Therefore, the outside world only needs to access 192.168.21.10:80 to access the services in the container.
4.2 Firewall closed state
If the Docker network is in Bridge mode and does not require a firewall, simply turn off the Firewalld service. It can solve many problems caused by firewall network problems, such as port impassability of Docker container.
- Docker network official documentation: https://docs.docker.com/engin…