In-depth understanding of Docker network principles

295d0026450a851d323e13994c02b9a3.gif

Author |

Source | CSDN Blog

Docker network principle

The container is a relatively independent environment, which is equivalent to a small Linux system, which cannot be directly accessed by the outside world. So how does it do it? Here we first understand the Linux veth pair.

1. Linux veth pair

A veth pair is a virtual network device interface that appears in pairs, one end is connected to the network protocol stack, and the other end is connected to each other. As shown below:

126c6787025d3472fa63c2714f685d6e.png

The veth pair connects the two networks veth0 and veth1.

2. Understand Docker0

Let's check the local ip first

b2cbd5ea1464096240fe7be93a123d2d.png


Here we can analyze that there are three networks:

lo      127.0.0.1      # 本机回环地址
eth0    172.31.179.120   # 阿里云的私有IP(如果你是虚拟机就是虚拟机的ip)
docker0 172.17.0.1       # docker网桥

lo and eth0 are created when our virtual machine starts, but docker0 is created when we install docker. docker0 is used to communicate with the virtual machine.

Question: How does Docker handle container network access?

We first start a tomcat container to illustrate.

[root@jiangnan tomcat1]# docker pull tomcat
[root@jiangnan tomcat1]# docker images
REPOSITORY   TAG       IMAGE ID       CREATED        SIZE
tomcat       latest    fb5657adc892   2 months ago   680MB
[root@jiangnan tomcat1]# docker run -d -p 8081:8080 --name tomcat01 tomcat
914a7d82b017f63f81c6eba49af5471441f1946c9d45509b69ab2c50c2713b6f
[root@jiangnan tomcat1]#

Here tomcat01 is started, let's check the network again

bf755e20a7218eecbc04300617cc7ec1.png

Discovery: When we checked before, there were still three sets of network cards. After starting a tomcat container, there was an additional set of network cards 201: vethad33778@if200, and they were still in pairs. Similarly, if we start another tomcat02, there will be another pair of network cards.

After entering the tomcat01 container, you can see that the ip address corresponding to tomcat01 is: 172.17.0.2

2aabf155edf6b1e54fcee69690c535eb.png

It can also be pinged on the host computer.

7deab5a7fe11906a4f4d0d1c1e40d6d5.png

Note: The ip corresponding to tomcat02 is 172.17.0.3, which can also be pinged.

Conclusion: Every time we start a container, there will be an additional pair of network cards, and they are connected to docker0, which in turn is connected to the virtual machine.

2d4a25be65e1bc582f7d920b466e4252.png

It can also be viewed through inspect.

[root@jiangnan tomcat1]# docker network ls
NETWORK ID     NAME      DRIVER    SCOPE
4d3e75606593   bridge    bridge    local   # 这个就是docker0
8e92ee24e5f6   host      host      local
e85ffb1f2cc3   none      null      local
[root@jiangnan tomcat1]# docker inspect 4d3e75606593
"IPAM": {   
            "Driver": "default",
            "Options": null,
            "Config": [
                {
                    "Subnet": "172.17.0.0/16",
                    "Gateway": "172.17.0.1"    # 网关
                }
            ]
        },




"Containers": {   # 容器
            "15910ee083965d60c46bf9b3b292570fef9b8925905aa4df90c6d48142bb2eee": {
                "Name": "tomcat01",
                "EndpointID": "9c7a5ab65f1fc91b1d92ad61dec9b2f518f67f69f662522483dca789616f42aa",
                "MacAddress": "02:42:ac:11:00:02",
                "IPv4Address": "172.17.0.2/16",
                "IPv6Address": ""
            },
            "6c9a6a5d8eca9ad52926008c7b30516d23293ff8ad1f38947957d571431d5297": {
                "Name": "tomcat02",
                "EndpointID": "f83c1e643236cd65f50fba03929ca14d5df8d135b1f6cb8adf203cf96084f7aa",
                "MacAddress": "02:42:ac:11:00:03",
                "IPv4Address": "172.17.0.3/16",
                "IPv6Address": ""
            }
        },

We can abstract to such a network model.

9c13d5a8da5c28e113e17727e04a19d9.png

Here, we can see that Docker0 is equivalent to a router, and any container startup is the docker0 network by default.

By default, docker will assign an available ip to the container and connect it to docker0. The veth pair technology is used.

3. Container Interconnection – Link

As can be seen in the network model diagram, containers cannot be directly connected to each other.

eac36aaed34c13772db6dc08163f65b6.png

The hosts corresponding to the two tomcats we started earlier are as follows:

[root@jiangnan tomcat1]# docker exec -it tomcat01 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  3ecb3204e2dc
root@3ecb3204e2dc:/usr/local/tomcat#
[root@jiangnan tomcat1]# docker exec -it tomcat02 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.3  6c9a6a5d8eca
[root@jiangnan tomcat1]#

Discovery: They only have their own ip addresses in their hosts.

But in actual work, the container uses a virtual ip, and the ip will change every time it is started. Thinking about a scenario, we write a microservice. The database connection address used to use ip. If the ip changes, it will not work, then we can Can't use the service name to access it?

We are starting a tomcat03 and use --link to bind to tomcat02. Then see what its hosts look like.

[root@jiangnan tomcat1]# docker run -d -p 8083:8080 --name tomcat03 --link tomcat02 tomcat
db75c42f7f7f609218deb290d3e923e3c7da6bcf8c0b38cde27962fb2b9e9a54
[root@jiangnan tomcat1]# docker exec -it tomcat03 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.3  tomcat02 e4060ea4ee28   # 发现tomcat2直接被写在这里
172.17.0.4  db75c42f7f7f
root@db75c42f7f7f:/usr/local/tomcat#

Found: using –link, not only has its own ip, but also the service name of tomcat02. But there is no tomcat03 in tomcat02, because --link is one-way.

88da8453dd71f3c5c6abd14fc34ea93c.png

In this way, the communication between the container and the container is realized. You don't need to connect by ip address, but by service name.

But the method of using --link is outdated, we generally use custom network.

4. Custom network (recommended)

Features of docker0:

  • it's the default

  • The domain name cannot be accessed

  • –link The domain name is available, but it doesn’t work if I delete it

Docker provides us with three network modes

[root@jiangnan tomcat1]# docker network ls
NETWORK ID     NAME      DRIVER    SCOPE
4d3e75606593   bridge    bridge    local
8e92ee24e5f6   host      host      local
e85ffb1f2cc3   none      null      local
[root@jiangnan tomcat1]#

The bridge is used by default, which is our docker0 network card.

40905371da45e15d0db117b25beba1a1.png

When we start the container, it is actually the following command

[root@jiangnan tomcat1]# docker run -d -P --name tomcat01 --net bridge tomcat

This --net is the default, so is omitted.

Below we customize a network mynet.

# 自定义创建的默认default "bridge"
[root@jiangnan tomcat1]# docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet
3136d64109c6f285bc69d3ee4be901524292d0e5ddd9e414d49197dfa6c19ba1
[root@jiangnan tomcat1]# docker network ls
NETWORK ID     NAME      DRIVER    SCOPE
4d3e75606593   bridge    bridge    local
8e92ee24e5f6   host      host      local
3136d64109c6   mynet     bridge    local   # 多了一个mynet
e85ffb1f2cc3   none      null      local


[root@jiangnan tomcat1]# docker network inspect mynet
[
    {
        "Name": "mynet",
        "Id": "3136d64109c6f285bc69d3ee4be901524292d0e5ddd9e414d49197dfa6c19ba1",
        "Created": "2022-02-27T14:15:44.676693958+08:00",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": {},
            "Config": [
                {
                    "Subnet": "192.168.0.0/16",  # 子网地址
                    "Gateway": "192.168.0.1"   # 网关
                }
            ]
        },
        "Internal": false,
        "Attachable": false,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
        "Containers": {},
        "Options": {},
        "Labels": {}
    }
]
[root@jiangnan tomcat1]#

Below we use the custom network to start tomcat

[root@jiangnan tomcat1]# docker run -d  -p 8081:8080 --name tomcat-net-01 --net mynet tomcat
675439c851dc29355c03f82bb163f9e5a326e230447d86d40d53ff08766cfd06
[root@jiangnan tomcat1]# docker run -d  -p 8082:8080 --name tomcat-net-02 --net mynet tomcat
31f12c9332e8b4b6e66619dc988533f2863b80e71dbf490c8313694637814ca1
[root@jiangnan tomcat1]# docker ps
CONTAINER ID   IMAGE     COMMAND             CREATED          STATUS          PORTS                                       NAMES
31f12c9332e8   tomcat    "catalina.sh run"   3 seconds ago    Up 2 seconds    0.0.0.0:8082->8080/tcp, :::8082->8080/tcp   tomcat-net-02
675439c851dc   tomcat    "catalina.sh run"   12 seconds ago   Up 12 seconds   0.0.0.0:8081->8080/tcp, :::8081->8080/tcp   tomcat-net-01
[root@jiangnan tomcat1]#

View the network

[root@jiangnan tomcat1]# docker inspect mynet
[
    {
        "Name": "mynet",
        "Id": "3136d64109c6f285bc69d3ee4be901524292d0e5ddd9e414d49197dfa6c19ba1",
        "Created": "2022-02-27T14:15:44.676693958+08:00",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": {},
            "Config": [
                {
                    "Subnet": "192.168.0.0/16",
                    "Gateway": "192.168.0.1"
                }
]
        },
        "Internal": false,
        "Attachable": false,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
        "Containers": {
            "31f12c9332e8b4b6e66619dc988533f2863b80e71dbf490c8313694637814ca1": {
                "Name": "tomcat-net-02",
                "EndpointID": "1c0e9dbffff295f2326bfd1e2847c0f1d9136ff00519101bb11d922e7da4f818",
                "MacAddress": "02:42:c0:a8:00:03",
                "IPv4Address": "192.168.0.3/16",
                "IPv6Address": ""
            },
            "675439c851dc29355c03f82bb163f9e5a326e230447d86d40d53ff08766cfd06": {
                "Name": "tomcat-net-01",
                "EndpointID": "2653da0a25d166f0d7222235e85d8231d9424e19949b6e6b7cfa1a3eddcc462b",
                "MacAddress": "02:42:c0:a8:00:02",
                "IPv4Address": "192.168.0.2/16",
                "IPv6Address": ""
            }
        },
        "Options": {},
        "Labels": {}
    }
]
[root@jiangnan tomcat1]#
# 我们来测试ping容器名和ip试试,都可以ping通
[root@jiangnan ~]# docker exec -it tomcat-net-01 ping 192.168.0.3
PING 192.168.0.3 (192.168.0.3) 56(84) bytes of data.
64 bytes from 192.168.0.3: icmp_seq=1 ttl=64 time=0.093 ms
[root@jiangnan ~]# docker exec -it tomcat-net-01 ping tomcat-net-02
PING tomcat-net-02 (192.168.0.3) 56(84) bytes of data.
64 bytes from tomcat-net-02.mynet (192.168.0.3): icmp_seq=1 ttl=64 time=0.063 ms
64 bytes from tomcat-net-02.mynet (192.168.0.3): icmp_seq=2 ttl=64 time=0.066 ms

Discovery: You --linkcan also ping through the service name directly.

5. Network connection

Docker0 is definitely not connected to a custom network. The advantage of using a custom network is network isolation.

But in actual work, for example, we deploy mysql and use a network segment. Deploying tomcat and using another network segment, the two network segments must not be connected to each other, but tomcat and mysql need to be connected to each other, we must use network connection. The schematic diagram is as follows:

ed9e576fcd30371094f95b1c38ba0b3d.png

55a761d54a368444f38a4efe0e2343a5.png

99d4179fb1859861adc9de6709891ba9.png

Network connectivity is the connection between a container and a network segment.

For example, the tomcat01 of the default docker0 I used earlier needs to be connected to the mynet network.

# docker network connect 网络 容器
[root@jiangnan tomcat1]# docker network connect mynet tomcat01
[root@jiangnan tomcat1]# docker network inspect mynet
[
    {
        "Name": "mynet",
        "Id": "3136d64109c6f285bc69d3ee4be901524292d0e5ddd9e414d49197dfa6c19ba1",
        "Created": "2022-02-27T14:15:44.676693958+08:00",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": {},
            "Config": [
                {
                    "Subnet": "192.168.0.0/16",
                    "Gateway": "192.168.0.1"
                }
]
        },
        "Internal": false,
        "Attachable": false,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
        "Containers": {
            "2e709013935463c29caf28771bb49925fee4e02842459b339d7dd1ad5dedf9b7": {
                "Name": "tomcat-net-01",
                "EndpointID": "9f3a46bad37ade7935e283715caa5699e9a7e22175b592f4a4792a37c351d969",
                "MacAddress": "02:42:c0:a8:00:02",
                "IPv4Address": "192.168.0.2/16",
                "IPv6Address": ""
            },
            "5c0c544f2507d9f5f456feceddbd853ebccc07cea8c39c8479693731e480bf55": {
                "Name": "tomcat01",
                "EndpointID": "d05abb2d31af4067c5a45f299ce7b4401b1fa81638a44b6c09f3de7f8f4221fe",
                "MacAddress": "02:42:c0:a8:00:04",
                "IPv4Address": "192.168.0.4/16",
                "IPv6Address": ""
            },
            "d6066db5fdd0b508514107a896ed20b639eaa47dbd97a025ad0c52250766c8a4": {
                "Name": "tomcat-net-02",
                "EndpointID": "3a5f6f2a07d900303382b290825c9f52640689c859608c741c7c7d81031e107e",
                "MacAddress": "02:42:c0:a8:00:03",
                "IPv4Address": "192.168.0.3/16",
                "IPv6Address": ""
            }
        },
        "Options": {},
        "Labels": {}
    }
]
[root@jiangnan tomcat1]#

32c8629b7c2b5a5177a74884df044e17.png

In this way, tomcat01 is directly added to the mynet network.

6. Summary

  • A veth pair is a virtual network device interface that appears in pairs, one end is connected to the network protocol stack, and the other end is connected to each other.

  • The docker0 network is used by default in docker.

  • docker0 is equivalent to a router, and any container starts by default is the docker0 network.

  • docker0 is a bridge for communication between containers and virtual machines.

  • It is recommended to use a custom network to better implement the connection method using the service name and avoid the embarrassment of IP changes.

  • Networks cannot be directly connected. Network connectivity is the connection between a container and a network to achieve cross-network operations.

4900e43667a35a1c1f3b5a7494b3fa61.gif

aaa466133d77bbd67da3f552f3c8e661.png

Recommended in the past

Why is everyone resisting the use of timed tasks to implement the function of "closing overtime orders"?

If you are asked about distributed locks, how should you answer?

Stop using Redis List to implement message queues, Stream is designed for queues

Basic knowledge of Java: what is a "bridge method"?

431101bb1d32d2c70a18a81dc7ed36e5.gif

point to share

6dc06d43c9371f995c7f0301a3d05721.gif

Favorites

b8a1b1dab5d6cdd4c8cbab8447e82d1c.gif

Like

322f24917bca3e7bb993b27fc933cb90.gif

click to watch

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324172027&siteId=291194637