In many cases, multiple Docker containers need to be run on the same machine. Docker-compose mentioned above is a convenient tool for managing multiple containers at the same time. Then, how to access and communicate between containers? This paper discusses this problem.

Method 1: Internal network

When docker is installed, a default Bridge network Docker0 is automatically created. As follows:

$ifConfig Docker0 Link encap: Ethernet hardware address 02:42:7b:b6:74:3b Inet :172.17.0.1 Broadcast :0.0.0.0 Mask :255.255.0.0 Inet6 address: Fe80: : deep BFF: feb6:743 b / 64 Scope: Link UP BROADCAST RUNNING MULTICAST MTU: 1500 jump points: 1 packet received: 575938 error: 0 dropped: 0 overload: 0 frames: 0 Send packet :700716 Error :0 Discard :0 Overload :0 Carrier :0 Collision :0 Send queue Length :0 Receive byte :47416735 (47.4 MB) Send byte :1246042404 (1.2 GB)Copy the code

When each container is started, a network adapter (172.17.0.X) is created. Therefore, each container can be accessed using the corresponding IP address. Then, run the Ubuntu image:

Docker run it -rm Ubuntu bashCopy the code

Start another terminal on the same computer, start ubuntu image, and use the same command to start Ubuntu image:

docker run -it --rm ubuntu bash
Copy the code

The IP addresses of both containers are listed as follows:

root@4e097f487019:/# ifconfig eth0 Link encap:Ethernet HWaddr 02:42: AC :11:00:02 inet ADDR: 172.17.0.2bcast :0.0.0.0 Mask:255.255.0.0 UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:25 Errors :0 Dropped :0 Overruns :0 Frame :0 TX Packets :0 Errors :0 dropped:0 Overruns :0 Carrier :0 collisions:0 TXqueuelen :0 RX bytes:3653 (3.6 KB) TX bytes:0 (0.0b) root@c02729d604f6:/# ifconfig eth0 Link encap:Ethernet HWaddr 02:42: AC :11:00:03 inet ADDR: 172.17.0.3bcast :0.0.0.0 Mask:255.255.0.0 UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:23 Errors :0 Dropped :0 Overruns :0 Frame :0 TX Packets :0 Errors :0 dropped:0 Overruns :0 Carrier :0 collisions:0 TXQueuelen :0 RX bytes:3380 (3.3KB) TX bytes:0 (0.0b)Copy the code

Ping test results are as follows:

root@c02729d604f6:/# ping -c 3 172.17.0.2 ping 172.17.0.3 (172.17.0.3): 56 data bytes 64 bytes from 172.17.0.3: Icmp_seq =0 TTL =64 time=0.178 ms 64 bytes from 172.17.0.3: ICmp_seq =1 TTL =64 time=0.118 ms 64 bytes from 172.17.0.3: Icmp_seq =2 TTL =64 time= 0.139ms -- 172.17.0.2 ping statistics -- 3 packets transmitted, 3 packets received 0% packet loss round-trip min/avg/ Max /stddev = 0.118/0.138/0.178/0.028msCopy the code

This method can only be used in IP format, but the premise is to know the IP address of each container. This approach is not very practical.

Method 2: Use Link

With the –link option, you can ping the network alias (or container alias) method on top of method one. Start the Ubuntu image:

docker run -it --rm --name ubuntu1 ubuntu bash
Copy the code

I’ll call it ubnntu1. Then start the Ubuntu image on another terminal:

docker run -it --rm --name ubuntu2 --link ubuntu1:ubuntu1  ubuntu bash
Copy the code

The container was named ubuntu2 and connected to ubuntu1. Note –link Ubuntu1: Ubuntu1 The first ubuntu1 represents the container and the second ubuntu1 represents the network/container alias. For the sake of uniformity, it is recommended that both be the same (in this case, just write –link Ubuntu1, this is just an example of its optional usage). View the hosts file in the container as follows:

root@f8199115a731:/# cat /etc/hosts 127.0.0.1 localhost ::1 localhost ip6-localhost ip6-loopback fe00::0 ip6-localnet Ff00 ::0 ip6-mcastPrefix FF02 ::1 IP6-allNodes FF02 ::2 IP6-allRouters 172.17.0.2 Ubuntu1 e288b5D2F0A4 172.17.0.3 f8199115a731Copy the code

The second-to-last line shows that IP address 172.17.0.2 has been mapped to ubuntu1 (container ID e288b5d2f0A4). The following ping test

root@f8199115a731:/# ping -c 3 172.17.0.2 ping 172.17.0.2 (172.17.0.2): 56 data bytes64 bytes from 172.17.0.2: Icmp_seq =0 TTL =64 time=0.123 ms64 bytes from 172.17.0.2: ICmp_seq =1 TTL =64 time=0.111 ms64 bytes from 172.17.0.2: icmp_seq=1 TTL =64 time=0.111 ms64 bytes from 172.17.0.2: Icmp_seq =2 TTL =64 time= 0.139ms -- 172.17.0.2 ping statistics --3 packets transmitted, 3 packets received 0% packet lossround-trip min/avg/ Max /stddev = 0.109/0.114/0.123/0.000 msroot@f8199115a731:/#Copy the code

You can also use ping -c 3 Ubuntu1.

root@f8199115a731:/# ping -c 3 ubuntu1 ping ubuntu1 (172.17.0.2): 56 data bytes64 bytes from 172.17.0.2: Icmp_seq =0 TTL =64 time=0.134 ms64 bytes from 172.17.0.2: ICmp_seq =1 TTL =64 time=0.121 ms64 bytes from 172.17.0.2: icmp_seq=1 TTL =64 time=0.121 ms64 bytes from 172.17.0.2: Icmp_seq =2 TTL =64 time= 0.75ms -- ubuntu1 ping statistics --3 packets transmitted, 3 packets transmitted, 0% packet lossround-trip min/avg/ Max /stddev = 0.121/0.125/0.134/0.000 msCopy the code

To use A –link connection between containers A and B, you must first start one of them, such as container A, and then connect it to container A when container B is started. This allows you to connect container A in container B using A network alias. Take GitLab for Jenkins as an example. In practical application, it is necessary to start GitLab first, then start Jenkins and connect to the GitLab container.

Method 3: Customize the Bridge network

To create a network on the host, run the following command:

docker network create mynet
Copy the code

Run the ifconfig command on the host to check the network status. The corresponding NIC address is as follows:

Br-49d34a6504d1 Link encap: Ethernet hardware address 02:42: BC: BA :62:17 INET address :172.18.0.1 Broadcast :0.0.0.0 Mask :255.255.0.0 Inet6 address: Fe80: : 42: BCFF: feba: 6217/64 the Scope: the Link UP BROADCAST RUNNING MULTICAST MTU: 1500 jump points: 1 packet received: 1400 error: 0 dropped: 0 overload: 0 frames: 0 Send packet :1558 Error :0 Discard :0 Overload :0 Carrier :0 Collision :0 Send queue Length :0 Received bytes :79757 (79.7KB) Send bytes :3650465 (3.6MB)Copy the code

Note: You can create multiple networks, each with a different IP address range. Then, run the Ubuntu image:

docker run -it --rm --network mynet --network-alias ubuntu1  ubuntu bash
Copy the code

Where –network mynet indicates that the mynet network is used, and –network-alias ubuntu1 indicates that the container is running under the network alias ubuntu1. (A network alias is similar to hostname and can be used regardless of the container IP.) Next, start another terminal on the same computer and start the Ubuntu image:

docker run -it --rm --network mynet --network-alias ubuntu2 ubuntu bash
Copy the code

The command form is the same as above. Just change the network alias to Ubuntu2. Use ifconfig to view the IP address of the Ubuntu container as follows:

root@74f4089ce79c:/# ifConfigeth0 Link encap:Ethernet HWaddr 02:42: AC :12:00:02 inet ADDR: 172.18.0.2bcast :0.0.0.0 Mask:255.255.0.0 UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:1575 Errors :0 Dropped :0 Overruns :0 Frame :0 TX packets:1405 Errors :0 dropped:0 Overruns :0 Carrier :0 collisions:0 TXQueuelen :0 RX bytes:3652734 (3.6 MB) TX Bytes: 99679 (99.6 KB)Copy the code

Another container, Ubuntu2, was pinged.

root@74f4089ce79c:/# ping ubuntu2PING Jenkins (172.18.0.3): 56 data bytes64 bytes from 172.18.0.3: Icmp_seq =0 TTL =64 time=0.142 MS64 bytes from 172.18.0.3: ICmp_seq =1 TTL =64 time=0.131 msCopy the code

Similarly, ping Ubuntu from the Ubuntu2 container will work.

root@927fe3bab506:/# ping ubuntu ping Ubuntu (172.18.0.2): 56 data bytes64 bytes from 172.18.0.2: Icmp_seq =0 TTL =64 time=0.122 MS64 bytes from 172.18.0.2: ICmp_seq =1 TTL =64 time=0.113 msCopy the code

This is recommended. The default link is static and does not allow the link container to restart, while the custom link is dynamic and supports the link container restart (and IP change). Therefore, the container linked with –link must be created in advance on the default network, and does not need to be created in advance on the custom network. When you use a network alias, you can connect based on the alias regardless of how the container IP address changes.

Docker network related commands

To create a network on the host, run the following command:

docker network create mynet
Copy the code

The following commands are used to view the customized bridge network:

docker network inspect mynet
Copy the code

Removing a network Requires all containers on the network to close or disconnect from the network before you can run the remove command:

Docker network Disconnet MyNET container IDCopy the code

Then remove the network

docker network rm mynet
Copy the code