First, what is the Docker network

Learning Docker, you will learn Docker network, a network is a group of endpoints that can communicate with each other. Docker creates three networks when it is installed

#Check the network
docker network ls
Copy the code

The other two are self-created networks, which can be ignored for the time being

Host Network: In the same Network with the host, the host and the host share a Network Namespace. Instead of virtualizing its own network card and IP, the container will use the host’s IP and port. This mode cannot be used if ports conflict

None network: Turn off the network of containers. Containers placed on top do not need a network. For example, the ability to generate random passwords

Bridge Network: Containers use a separate Network Namespace and are connected to the Docker0 virtual bridge. If no network is specified, containers created by default will hang in Docker0. The container communicates with the host through the Docker0 bridge and Iptables NET configuration.

What is Bridge network

When Docker Server starts, the host will automatically create a virtual bridge for Docker0. All newly created containers will connect to this bridge, so that the host container is equivalent to a layer 2 network. The Bridge network assigns veth pairs to each container, with one end of the network card in the container and the other end hanging on the Bridge docker0.

#View the network bridge of the host
brctl show
Copy the code

You can see that the Docker0 bridge is already mounted with three network cards. Three containers have been created, and these three containers are the virtual network cards of the containers.

#View information about bridge networks
docker network inspect bridge
Copy the code

You can see that the bridge network segment is 172.17.0.0/16. The gateway occupies the first IP address (172.17.0.1), and the remaining IP addresses are randomly assigned to the created container

Let’s look at the container’s network configuration:

Let’s look at the network configuration of the mysqlTest container:

Apt-get install net-tools // Install ifconfig

Apt-get install iputils-ping // install ping

Apt-get install iproute2 // install IP

You can see that the IP address assigned to the container is 172.17.0.3 and the network adapter on the container side is eth0@if1232.

Run IP addr to locate the other network adapter vethc991ce1See vethc991ce1 hanging on docker0 from the BRCTL show commandMysqltest: vethC991CE1: vethC991ce1: vethC991ce1: vethC991ce1: vethC991ce1: vethC991ce1 This is equivalent to eth0@if1232 also hanging on docker0 to connect the container to the Bridge network

The current container network topology is as follows:

How do containers communicate with each other

1. Inside the host, the same network

Docker is based on the Network card pair of Veth pair to realize communication between the same network, not directly end-to-end, but indirectly through the bridge.

Ping mysql1’s IP address inside mysql2, you can see that it is interoperable

The routing table can be seen inside the mysql2 container: the interface is eth0, and the information is transmitted to docker0 through the nic. Docker0 broadcasts the address, and mysqL1 is found through the nic

2. Inside the host, different networks

Different networks cannot directly communicate with each other. That is, 172.18.0.4 cannot be pinged from inside 172.17.0.2. The following figure shows the network topology that is disconnected:

You can use the following two methods to achieve direct communication between different networks:

Method 1: Add containers to another network, and put the containers you want to communicate with in the same container

The peer0.org2 container is added to the Bridge. Ifconfig shows that the peer0.org2 container has added an eth1 nic to the previous nic (LO,eth0) and assigned an IP address in the Bridge network segment

#Add the 04AEC1064812 (Peer0.org 2) container to the Bridge network
[centos@wunaichi-fabric ~]$ docker network connect bridge 04aec1064812
#Enter the 04AEC1064812 container
[centos@wunaichi-fabric ~]$ docker exec -it 04aec1064812 bash
#Check the IP address. You can see that an ETH1 network adapter is added and an IP address in the BRIDG network segment is allocatedroot@04aec1064812:/opt/gopath/src/github.com/hyperledger/fabric/peer# ifconfig eth0: Flags = 4163 < UP, BROADCAST, RUNNING, MULTICAST > mtu 1500 inet 172.18.0.4 netmask 255.255.0.0 BROADCAST 0.0.0.0 Mr 02:42: AC :12:00:04 TXQueuelen 0 (Ethernet) RX packets 2487840 bytes 433949085 (413.8 MiB) RX errors 0 Dropped 0 Overruns 0 frame 0 TX packets 2455380 bytes 426722690 (406.9 MiB) TX errors 0 Dropped 0 Overruns 0 carrier 0 collisions 0 eth1: Flags = 4163 < UP, BROADCAST, RUNNING, MULTICAST > mtu 1500 inet 172.17.0.5 netmask 255.255.0.0 BROADCAST 0.0.0.0 Mr 02:42: AC :11:00:05 TXQueuelen 0 (Ethernet) RX packets 8 bytes 656 (656.0b) RX errors 0 Dropped 0 Overruns 0 frame 0 TX Packets 0 bytes 0 (0.0b) 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 38 bytes 3151 (3.0 KiB) RX errors 0 dropped 0 Overruns 0 Frame 0 TX packets 38 bytes 3151 (3.0 KiB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0Copy the code

Check the Bridge network to see the Peer0.org 2 container as well

Enter the peer0.org2 container and you can see that the container belongs to both networks

Our network topology would look like this:

When peer0.org2 is added to the new network, a veth pair is created on the Bridge network, which is consistent with communication on the same network.

Method 2: Modify the underlying iptables to achieve network communication
#Iptables -save Displays iptables rules[centos@wunaichi-fabric ~]$ sudo iptables-save ... -A DOCKER-ISOLATION -i br-b86310df8e66 -o br-7a0183b7dfed -j DROP -A DOCKER-ISOLATION -i br-7a0183b7dfed -o br-b86310df8e66 -j DROP -A DOCKER-ISOLATION -i docker0 -o br-7a0183b7dfed -j DROP -A DOCKER-ISOLATION -i br-7a0183b7dfed  -o docker0 -j DROP -A DOCKER-ISOLATION -i docker0 -o br-b86310df8e66 -j DROP -A DOCKER-ISOLATION -i br-b86310df8e66 -o docker0 -j DROP ...Copy the code

The iptables rule drops the bidirectional traffic between bridge Docker0 and Br-b86310DF8e66. The rule name docker-isolation can also be known that DOCKER is designed to isolate different networks.

So the most straightforward solution here is to change the Iptables rules: add bidirectional relationships

sudo iptables -I DOCKER-USER -i docker0 -o br-b86310df8e66 -j ACCEPT
sudo iptables -I DOCKER-USER -i br-b86310df8e66 -o docker0 -j ACCEPT
Copy the code

Check it out: perfect

Communication between the external world and the container

Ping www.baidu.com in the container works

As you can see, the container has access to the Internet by default. But how does it work?

Check the iptables rules. There is a rule in the NAT table:

-a POSTROUTING -s 172.17.0.0/16! -o docker0 -j MASQUERADECopy the code

This statement indicates that bridge Docker0 receives an outbound packet from 172.17.0.0/16 and sends it to MASQUERADE. MASQUERADE’s way of doing this is to replace the source address of the packet with the address of host and send it out, which is a network address translation (NAT).

Looking at the routing table, you can see that the default route is sent through eth0

How do we capture packets using tcpdump

Step 1: Let docker0 network container ping Baidu url

Step 2: See the docker0 packet capture situation

Docker0 receives the ping package from mysqltest whose source address is 172.17.0.3, and sends it to MASQUERADE for processing.

Step 3: See the eth0 packet capture

In eth0, the source IP address of the ping packet is translated to 10.0.0.234. This is the result of NAT rules to ensure that the packet reaches the Internet. This is the process below:

How do containers communicate with each other? I’ll leave that for next time