Docker网络
今天主要是学习Docker的第四步,了解Docker网络;接下来依旧会持续更新Docker的高级部分,感兴趣的可以关注;
一、准备工作
首先,我们清空全部环境信息,将docker 的所有镜像、容器先删除!
二、理解Docker0
1、查看本地网络信息
可以看到有三个网卡信息:
lo:本地(回环)地址;
ens:虚拟机或阿里云服务器(内网)地址;
docker0:docker网络地址(安装docker后,主机默认分配的)。
2、了解Docker 是如何处理容器网络访问的?
2.1、启动一个容器,查看容器内部网络
#启动容器名为tomcat01
[root@zw-study dockerfile_test]# docker run -d --name tomcat01 -P fb5657adc892
4ad232c130069e0e3cb5b9f15db8b636bab664234acee75959d3c847c0ba3f60
#查看运行的容器
[root@zw-study dockerfile_test]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
4ad232c13006 fb5657adc892 "catalina.sh run" 4 seconds ago Up 3 seconds 0.0.0.0:32768->8080/tcp tomcat01
#进入容器tomcat01
[root@zw-study ~]# docker exec -it 4ad232c13006 /bin/bash
#查看内部网络
root@4ad232c13006:/usr/local/tomcat# ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
10: eth0@if11: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet 172.17.0.2/16 scope global eth0
valid_lft forever preferred_lft forever
inet6 fe80::42:acff:fe11:2/64 scope link
valid_lft forever preferred_lft forever
注意:
此处进入容器后,查看网络,输入ip addr 后,可能报错,报错信息:
bash: ip: command not found
解决方案:
输入命令:
apt-get update & apt-get install -y iproute2
2.2、退出容器,查看主机网络
[root@zw-study ~]# ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 00:16:3e:12:db:dd brd ff:ff:ff:ff:ff:ff
inet 172.23.204.70/20 brd 172.23.207.255 scope global dynamic eth0
valid_lft 315268029sec preferred_lft 315268029sec
inet6 fe80::216:3eff:fe12:dbdd/64 scope link
valid_lft forever preferred_lft forever
3: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
link/ether 02:42:96:09:a5:51 brd ff:ff:ff:ff:ff:ff
inet 172.17.0.1/16 scope global docker0
valid_lft forever preferred_lft forever
inet6 fe80::42:96ff:fe09:a551/64 scope link
valid_lft forever preferred_lft forever
11: vethe79d2eb@if10: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP group default
link/ether ee:64:0a:8f:b4:0d brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet6 fe80::ec64:aff:fe8f:b40d/64 scope link
valid_lft forever preferred_lft forever
2.3、结论1:docker每启动一个容器,就会分配一个ip,只要安装了docker,就会有一个网卡docker0,桥接模式,使用的时veth-pair技术
从上面宿主机和容器内网络可以看到容器内ip与宿主机ip成对出现,这就是veth-pair技术。
1、我们发现这个容器带来网卡,都是一对对的。
2、evth—pair 就是一对的虚拟设备接口,他们都是成对出现的,一段连着协议,一段彼此相连。正因为有这个特性,evth—pair 充当一个桥梁,连接各种虚拟网络设备的。
3、openstac,Docker容器之间的连接,OVS的连接,都是使用 evth-pair 技术 。
2.4、网络连接测试(问题思考与验证,由此得到结论)
首先我们思考一下两个问题:
1、测试宿主机能否连接容器?
2、多启动一个容器,测试容器之间能否连接?
接下来我们开始验证:
验证1:
验证2:
#开启第二个容器名为tomcat02
[root@zw-study ~]# docker run -d --name tomcat02 -P fb5657adc892
0abb405d17122f7947f4bebd4b3c3109c55ef53871e8da7f35ad83022293c91d
#查看所有运行的容器
[root@zw-study ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
0abb405d1712 fb5657adc892 "catalina.sh run" 7 seconds ago Up 6 seconds 0.0.0.0:32769->8080/tcp tomcat02
4ad232c13006 fb5657adc892 "catalina.sh run" 2 hours ago Up 2 hours 0.0.0.0:32768->8080/tcp tomcat01
#进入tomcat02容器
[root@zw-study ~]# docker exec -it 0abb405d1712 /bin/bash
#查看容器内部网络
root@0abb405d1712:/usr/local/tomcat# ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
12: eth0@if13: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
link/ether 02:42:ac:11:00:03 brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet 172.17.0.3/16 scope global eth0
valid_lft forever preferred_lft forever
inet6 fe80::42:acff:fe11:3/64 scope link
valid_lft forever preferred_lft forever
#容器与容器连接 (tomcat02 ping tomcat01)
root@0abb405d1712:/usr/local/tomcat# ping 172.17.0.2
PING 172.17.0.2 (172.17.0.2) 56(84) bytes of data.
64 bytes from 172.17.0.2: icmp_seq=1 ttl=64 time=0.107 ms
64 bytes from 172.17.0.2: icmp_seq=2 ttl=64 time=0.068 ms
64 bytes from 172.17.0.2: icmp_seq=3 ttl=64 time=0.070 ms
64 bytes from 172.17.0.2: icmp_seq=4 ttl=64 time=0.071 ms
64 bytes from 172.17.0.2: icmp_seq=5 ttl=64 time=0.072 ms
64 bytes from 172.17.0.2: icmp_seq=6 ttl=64 time=0.067 ms
#容器与容器连接 (tomcat01 ping tomcat02)
root@4ad232c13006:/usr/local/tomcat# ping 172.17.0.3
PING 172.17.0.3 (172.17.0.3) 56(84) bytes of data.
64 bytes from 172.17.0.3: icmp_seq=1 ttl=64 time=0.081 ms
64 bytes from 172.17.0.3: icmp_seq=2 ttl=64 time=0.072 ms
64 bytes from 172.17.0.3: icmp_seq=3 ttl=64 time=0.072 ms
64 bytes from 172.17.0.3: icmp_seq=4 ttl=64 time=0.072 ms
64 bytes from 172.17.0.3: icmp_seq=5 ttl=64 time=0.074 ms
注意:ping可能报错,报错信息:
bash: ping: command not found
解决方案:
安装iputils-ping
输入命令:
apt -y install iputils-ping
2.5、结论2:Docker0相当于一个路由器,每个容器都与docker0相连,容器之间的通信通过路由器来转发
所有的容器在不指定网络的情况下,都是docker0路由的,docker会给我们的容器分配一个默认的可用IP,也就是说:容器tomcat01和容器tomcat02是公用的一个路由器,docker0
2.6、展开分析Docker0
Docker中的所有网络接口都是虚拟的从而使得转发效率最高化,相当于内网传递,你如果删除了容器,也就对应删除了网络;
三、容器互联技术
问题引入
问题思考:
假设,我们的引用程序中配置了mysql数据库,通过ip的形式,例如:jdbc:mysql://39.105.150.128:3306/str_data?useUnicode=true&characterEncoding=UTF-8
每次重启容器或Linux宿主机,ip就会变化,固定的ip互联网络就会失效,难道我们每次都需要去程序修改这个配置吗?能否直接通过容器名称去访问??
测试:
#进入tomcat02 尝试ping tomcat01
[root@zw-study ~]# docker exec -it 0abb405d1712 /bin/bash
root@0abb405d1712:/usr/local/tomcat# ping tomacat01
ping: tomacat01: Name or service not known
root@0abb405d1712:/usr/local/tomcat#
答案:直接连接肯定是无法连接的
那么,有什么技术可以实现呢?答案肯定是有的,接下来我们就采用两种方式解决;
1、–link
1.1、–link实现
#开启tomcat03 并且通过--link 连接tomcat01
[root@zw-study ~]# docker run -d --name tomcat03 -P --link tomcat01 fb5657adc892
1fd1b46af332027ca4875972e13efc5ee95dd40c61b70f73b68990c2ab0fb27b
#查看正在运行的容器
[root@zw-study ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
1fd1b46af332 fb5657adc892 "catalina.sh run" 5 seconds ago Up 4 seconds 0.0.0.0:32770->8080/tcp tomcat03
0abb405d1712 fb5657adc892 "catalina.sh run" 58 minutes ago Up 58 minutes 0.0.0.0:32769->8080/tcp tomcat02
4ad232c13006 fb5657adc892 "catalina.sh run" 3 hours ago Up 3 hours 0.0.0.0:32768->8080/tcp tomcat01
#进入tomcat03
[root@zw-study ~]# docker exec -it tomcat03 /bin/bash
#通过容器名称连接tomcat01 ,可以看到连接成功
root@1fd1b46af332:/usr/local/tomcat# ping tomcat01
PING tomcat01 (172.17.0.2) 56(84) bytes of data.
64 bytes from tomcat01 (172.17.0.2): icmp_seq=1 ttl=64 time=0.098 ms
64 bytes from tomcat01 (172.17.0.2): icmp_seq=2 ttl=64 time=0.074 ms
64 bytes from tomcat01 (172.17.0.2): icmp_seq=3 ttl=64 time=0.096 ms
64 bytes from tomcat01 (172.17.0.2): icmp_seq=4 ttl=64 time=0.076 ms
但是,需要注意,这种方式,反向是不能连接的(因为创建tomcat01 的时候,并没有–link tomcat03)
1.2、–link原理探究(–link本质是通过在hosts中做host映射实现的)
进入tomcat03,查看它的主机文件hosts:
本质上,–link实现方式,是通过在hosts文件中,做host映射实现的!!!
因此–link已经摒弃;建议实现使用自定义网络方式实现
2、自定义网络(重点实现方式)
2.1、Docker网络命令
- 查看网络
docker network ls
- 创建网络
docker network create 网络名
docker network create myNetWork
- 查看网络详细信息
docker network inspect 网络名
docker network inspect myNetWork
- 删除网络
docker network rm 网络名
docker nerwork rm myNetWork
2.2、查看分析所有Docker网络
[root@zw-study ~]# docker network ls
NETWORK ID NAME DRIVER SCOPE
4d65d4f31816 bridge bridge local
44c5a1dab171 host host local
558b2cb3625f none null local
解释:
1. bridge : 桥接(默认,自己创建也使用bridge 模式,Docker0就是这种)
2. host : 和宿主即共享网络
3. none : 不配置网络
2.3、自定义网络
#创建网络
命令解释:创建了一个名为myNetWork的网络
网络模式为bridge,
子网是192.168.0.0/16,
网关或者路由是192.168.0.1
[root@zw-study ~]# docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 myNetWork
e983274c3cc44fb08fe9034a46e1594d4d8a53359b97e071a88b6e14b602ae1f
#查看所有网络
[root@zw-study ~]# docker network ls
NETWORK ID NAME DRIVER SCOPE
4d65d4f31816 bridge bridge local
44c5a1dab171 host host local
e983274c3cc4 myNetWork bridge local
558b2cb3625f none null local
查看自定义网络详细信息
2.4、自定义网络测试是否解决容器名连接问题
注意:我们之前在启动容器时,默认走的是Docker0网络
#原先我们开启一个容器的命令是:
docker run -d --name tomcat02 -P fb5657adc892
实际上默认使用Docker0 [--net bridge],桥接模式:
docker run -d --name tomcat02 -P --net bridge fb5657adc892
接下来我们使用自己的网络启动容器,进行测试:
#查看镜像
[root@zw-study ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
docker.io/tomcat latest fb5657adc892 3 years ago 680 MB
#使用自定义网络启动myNetworkTomcat01 容器
[root@zw-study ~]# docker run -d --name myNetworkTomcat01 -P --net myNetWork fb5657adc892
4c45ff95a52736114eb9efd0ed44933ab7d03fa9681ea41df79caf5f0c3c9326
#使用自定义网络启动myNetworkTomcat02 容器
[root@zw-study ~]# docker run -d --name myNetworkTomcat02 -P --net myNetWork fb5657adc892
dadfa1bbc69bb05498d1fe52d399ec5b3238c2902714d152d38f5139519cbf0a
#查看所有启动容器
[root@zw-study ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
dadfa1bbc69b fb5657adc892 "catalina.sh run" 3 seconds ago Up 2 seconds 0.0.0.0:32772->8080/tcp myNetworkTomcat02
4c45ff95a527 fb5657adc892 "catalina.sh run" 11 seconds ago Up 10 seconds 0.0.0.0:32771->8080/tcp myNetworkTomcat01
1fd1b46af332 fb5657adc892 "catalina.sh run" 55 minutes ago Up 55 minutes 0.0.0.0:32770->8080/tcp tomcat03
0abb405d1712 fb5657adc892 "catalina.sh run" About an hour ago Up About an hour 0.0.0.0:32769->8080/tcp tomcat02
4ad232c13006 fb5657adc892 "catalina.sh run" 4 hours ago Up 4 hours 0.0.0.0:32768->8080/tcp tomcat01
#测试1正向测试:myNetworkTomcat01容器连接myNetworkTomcat02
[root@zw-study ~]# docker exec -it 4c45ff95a527 ping myNetworkTomcat02
PING myNetworkTomcat02 (192.168.0.3) 56(84) bytes of data.
64 bytes from myNetworkTomcat02.myNetWork (192.168.0.3): icmp_seq=1 ttl=64 time=0.083 ms
64 bytes from myNetworkTomcat02.myNetWork (192.168.0.3): icmp_seq=2 ttl=64 time=0.106 ms
64 bytes from myNetworkTomcat02.myNetWork (192.168.0.3): icmp_seq=3 ttl=64 time=0.082 ms
64 bytes from myNetworkTomcat02.myNetWork (192.168.0.3): icmp_seq=4 ttl=64 time=0.081 ms
64 bytes from myNetworkTomcat02.myNetWork (192.168.0.3): icmp_seq=5 ttl=64 time=0.081 ms
#测试2反向测试:myNetworkTomcat02容器连接myNetworkTomcat01
root@dadfa1bbc69b:/# ping myNetworkTomcat01
PING myNetworkTomcat01 (192.168.0.2) 56(84) bytes of data.
64 bytes from myNetworkTomcat01.myNetWork (192.168.0.2): icmp_seq=1 ttl=64 time=0.061 ms
64 bytes from myNetworkTomcat01.myNetWork (192.168.0.2): icmp_seq=2 ttl=64 time=0.106 ms
64 bytes from myNetworkTomcat01.myNetWork (192.168.0.2): icmp_seq=3 ttl=64 time=0.107 ms
64 bytes from myNetworkTomcat01.myNetWork (192.168.0.2): icmp_seq=4 ttl=64 time=0.093 ms
64 bytes from myNetworkTomcat01.myNetWork (192.168.0.2): icmp_seq=5 ttl=64 time=0.103 ms
2.5、自定义网络测试结论
通过自定义网络,我们实现了无论正向、反向均可以通过容器名称实现容器互联,这样下来大家就知道比起–link,它的优势是显而易见的
2.6、自定义网络的意义
自定义网络docker都已经帮我们维护好了对应的关系。可以轻松的实现不同集群去使用不同的网络,保证集群网络的安全和健康;
四、网络间联通
问题引入:
如果我们现在用tomcat01、tomcat02、tomcat03去连接myNetworkTomcat02、myNetworkTomcat02可以连接吗?
测试:
[root@zw-study ~]# docker exec -it tomcat01 ping myNetworkTomcat01
ping: myNetworkTomcat01: Name or service not known
结果:
显然是无法连接的,思考下为什么呢?
4.1、问题分析:
首先我们查看tomcat01与myNetworkTomcat01各自网络的情况:
由此,我们分析得知,tomcat01系列和myNetWorkTomcat01系列分别在两个不同的网络中,所以无法直接连通;
4.2、解决方式
网卡与网卡无法打通,但是容器和网卡之间可以打通
如下图所示:
4.2.1、具体实现 docker network connect
#查看正在运行的容器
[root@zw-study ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
dadfa1bbc69b fb5657adc892 "catalina.sh run" About an hour ago Up About an hour 0.0.0.0:32772->8080/tcp myNetworkTomcat02
4c45ff95a527 fb5657adc892 "catalina.sh run" About an hour ago Up About an hour 0.0.0.0:32771->8080/tcp myNetworkTomcat01
1fd1b46af332 fb5657adc892 "catalina.sh run" 2 hours ago Up 2 hours 0.0.0.0:32770->8080/tcp tomcat03
0abb405d1712 fb5657adc892 "catalina.sh run" 3 hours ago Up 3 hours 0.0.0.0:32769->8080/tcp tomcat02
4ad232c13006 fb5657adc892 "catalina.sh run" 5 hours ago Up 5 hours 0.0.0.0:32768->8080/tcp tomcat01
#通过docker network connect 将tomcat01加入到myNetWork网络中
[root@zw-study ~]# docker network connect myNetWork tomcat01
#查看myNetWork网络详情,发现,tomcat01已经存在于myNetWork网络中
[root@zw-study ~]# docker network inspect myNetWork
[
{
"Name": "myNetWork",
"Id": "e983274c3cc44fb08fe9034a46e1594d4d8a53359b97e071a88b6e14b602ae1f",
"Created": "2025-01-01T15:40:53.501242461+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,
"Containers": {
"4ad232c130069e0e3cb5b9f15db8b636bab664234acee75959d3c847c0ba3f60": {
"Name": "tomcat01",
"EndpointID": "49f5717423f4e9958ec74a72d2d5b1565a7a3133e17a072893dc357a091423af",
"MacAddress": "02:42:c0:a8:00:04",
"IPv4Address": "192.168.0.4/16",
"IPv6Address": ""
},
"4c45ff95a52736114eb9efd0ed44933ab7d03fa9681ea41df79caf5f0c3c9326": {
"Name": "myNetworkTomcat01",
"EndpointID": "1dc601546233440b2f07bfa145851702e6a16b9b872c447ac676bb681f283b24",
"MacAddress": "02:42:c0:a8:00:02",
"IPv4Address": "192.168.0.2/16",
"IPv6Address": ""
},
"dadfa1bbc69bb05498d1fe52d399ec5b3238c2902714d152d38f5139519cbf0a": {
"Name": "myNetworkTomcat02",
"EndpointID": "93d7da8af9e6b5420cd43a0051a07dea7fb93efb77464776b034b7a46b7ea20b",
"MacAddress": "02:42:c0:a8:00:03",
"IPv4Address": "192.168.0.3/16",
"IPv6Address": ""
}
},
"Options": {},
"Labels": {}
}
]
如图所示:
4.2.2、测试
#查看所有正在运行的容器
[root@zw-study ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
dadfa1bbc69b fb5657adc892 "catalina.sh run" About an hour ago Up About an hour 0.0.0.0:32772->8080/tcp myNetworkTomcat02
4c45ff95a527 fb5657adc892 "catalina.sh run" About an hour ago Up About an hour 0.0.0.0:32771->8080/tcp myNetworkTomcat01
1fd1b46af332 fb5657adc892 "catalina.sh run" 2 hours ago Up 2 hours 0.0.0.0:32770->8080/tcp tomcat03
0abb405d1712 fb5657adc892 "catalina.sh run" 3 hours ago Up 3 hours 0.0.0.0:32769->8080/tcp tomcat02
4ad232c13006 fb5657adc892 "catalina.sh run" 5 hours ago Up 5 hours 0.0.0.0:32768->8080/tcp tomcat01
#测试tomcat01 链接 myNetworkTomcat01
[root@zw-study ~]# docker exec -it tomcat01 ping myNetworkTomcat01
PING myNetworkTomcat01 (192.168.0.2) 56(84) bytes of data.
64 bytes from myNetworkTomcat01.myNetWork (192.168.0.2): icmp_seq=1 ttl=64 time=0.080 ms
64 bytes from myNetworkTomcat01.myNetWork (192.168.0.2): icmp_seq=2 ttl=64 time=0.074 ms
64 bytes from myNetworkTomcat01.myNetWork (192.168.0.2): icmp_seq=3 ttl=64 time=0.072 ms
64 bytes from myNetworkTomcat01.myNetWork (192.168.0.2): icmp_seq=4 ttl=64 time=0.071 ms
#测试tomcat01 链接 myNetworkTomcat02
[root@zw-study ~]# docker exec -it tomcat01 ping myNetworkTomcat02
PING myNetworkTomcat02 (192.168.0.3) 56(84) bytes of data.
64 bytes from myNetworkTomcat02.myNetWork (192.168.0.3): icmp_seq=1 ttl=64 time=0.086 ms
64 bytes from myNetworkTomcat02.myNetWork (192.168.0.3): icmp_seq=2 ttl=64 time=0.070 ms
64 bytes from myNetworkTomcat02.myNetWork (192.168.0.3): icmp_seq=3 ttl=64 time=0.072 ms
#测试myNetworkTomcat01 链接 tomcat01
[root@zw-study ~]# docker exec -it myNetworkTomcat01 ping tomcat01
PING tomcat01 (192.168.0.4) 56(84) bytes of data.
64 bytes from tomcat01.myNetWork (192.168.0.4): icmp_seq=1 ttl=64 time=0.057 ms
64 bytes from tomcat01.myNetWork (192.168.0.4): icmp_seq=2 ttl=64 time=0.074 ms
64 bytes from tomcat01.myNetWork (192.168.0.4): icmp_seq=3 ttl=64 time=0.069 ms
本篇完结(下一篇,Docker compose服务编排)