Article directory
Docker network principle
In the previous article, I told you that the container is a relatively independent environment, which is equivalent to a small Linux system and 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:
The veth pair connects the two networks veth0 and veth1.
2. Understand Docker0
Let's check the local ip first
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
Discovery: When we checked earlier, 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
It can also be pinged on the host computer.
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.
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.
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. Technology isveth pair
used.
3. Container Interconnection – Link
As can be seen in the network model diagram, containers cannot be directly connected to each other.
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 it --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.
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 --link
the method used 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.
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 it 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
--link
can 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:
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]#
In this way, tomcat01 is directly added to the mynet network.
# tomcat01 可以ping通tomcat-net-01了
[root@jiangnan ~]# docker exec -it tomcat01 ping tomcat-net-01
PING tomcat-net-01 (192.168.0.2) 56(84) bytes of data.
64 bytes from tomcat-net-01.mynet (192.168.0.2): icmp_seq=1 ttl=64 time=0.071 ms
64 bytes from tomcat-net-01.mynet (192.168.0.2): icmp_seq=2 ttl=64 time=0.067 ms
Conclusion: If you want to operate others across the network, you need to use docker network connect [OPTIONS] NETWORK connection.
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.
The WeChat public account has already been opened. You can find me by searching for "Jiang Xiaonan and his friends". Friends, you can pay attention, and the articles will be synchronized later for easy viewing.