目录
其实就是tomcat03 在本地配置了tomcat02的配置
Docker网络
理解docker0
测试
三个网络
问题: docker 是如何处理容器网络访问的?
#问题: docker 是如何处理容器网络访问的?
# 测试 运行一个tomcat
[root@gh ~]# docker run -d --name tomcat01 tomcat:9.0
6ed597deed863104e8b2a2755cb0ba7ca4065a1568c0f1447479ebfeacedacb5
[root@gh ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
6ed597deed86 tomcat:9.0 "catalina.sh run" 3 seconds ago Up 2 seconds 8080/tcp tomcat01
# 查看容器内部网络地址 发现容器 内部 没有 ip addr 命令
$ docker exec -it 容器id ip addr
[root@gh ~]# docker exec -it d6ed68dc17149da ip addr
OCI runtime exec failed: exec failed: container_linux.go:380: starting container process caused: exec: "ip": executable file not found in $PATH: unknown
发现问题容器内没有 ip 命令
解决方案:
# 1、进入容器
[root@gh ~]# docker exec -it tomcat01 /bin/bash
# 2、执行 apt-get update 先更新我们的包管理工具
root@d6ed68dc1714:/usr/local/tomcat# apt-get update
# 3、安装我们所需要的 ip 指令
root@d6ed68dc1714:/usr/local/tomcat# apt install -y iproute2
# 4、安装我们所需要的 ping 指令
root@d6ed68dc1714:/usr/local/tomcat# apt install iputils-ping
容器再次测试ip addr
# 发现容器启动的时候会得到一个 eth0@if17 ip地址 docker 分配的
root@d6ed68dc1714:/usr/local/tomcat# ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1
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
16: eth0@if17: <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 brd 172.17.255.255 scope global eth0
valid_lft forever preferred_lft forever
思考? linux能不能ping通容器内部! 可以 容器内部可以ping通外界吗? 可以!
# 思考? linux能不能ping通容器内部! 可以 容器内部可以ping通外界吗? 可以!
[root@gh ~]# 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.067 ms
64 bytes from 172.17.0.2: icmp_seq=2 ttl=64 time=0.066 ms
#linux 可以ping 通 docker 容器内部
linux 可以ping 通 docker 容器内部
服务器再次测试ip addr
[root@gh ~]# ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1
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
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 00:16:3e:2c:35:ec brd ff:ff:ff:ff:ff:ff
inet 172.29.184.223/20 brd 172.29.191.255 scope global dynamic eth0
valid_lft 315294008sec preferred_lft 315294008sec
3: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
link/ether 02:42:62:ed:5b:c5 brd ff:ff:ff:ff:ff:ff
inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
valid_lft forever preferred_lft forever
17: vethd265c9d@if16: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP group default
link/ether a2:6f:df:7e:37:ab brd ff:ff:ff:ff:ff:ff link-netnsid 0
原理
1、我们每启动一个docker容器,docker就会给docker容器分配一个ip,我们只要安装了docker,就会有一个docker0
桥接模式,使用的技术是veth-pair技术!
Linux 虚拟网络设备 veth-pair 详解,看这一篇就够了 - 猿大白 - 博客园
服务器再次测试ip addr 发现多一对网卡
[root@gh ~]# ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1
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
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 00:16:3e:2c:35:ec brd ff:ff:ff:ff:ff:ff
inet 172.29.184.223/20 brd 172.29.191.255 scope global dynamic eth0
valid_lft 315294008sec preferred_lft 315294008sec
3: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
link/ether 02:42:62:ed:5b:c5 brd ff:ff:ff:ff:ff:ff
inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
valid_lft forever preferred_lft forever
17: vethd265c9d@if16: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP group default
link/ether a2:6f:df:7e:37:ab brd ff:ff:ff:ff:ff:ff link-netnsid 0
2、在启动一个容器测试
[root@gh ~]# docker run -d -P --name tomcat02 mytomcat:1.0
36457550008f95dbb958e5b267cb1ad3d4594c8807ba868ca5e5c79a5a970533
[root@gh ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
36457550008f mytomcat:1.0 "catalina.sh run" 3 seconds ago Up 2 seconds 0.0.0.0:49155->8080/tcp tomcat02
d6ed68dc1714 10db4a99b775 "catalina.sh run" 24 minutes ago Up 24 minutes 0.0.0.0:49153->8080/tcp tomcat01
服务器再次测试ip addr 发现又多一对网卡
发现每次启动一个容器网卡就会多一对网卡
[root@gh ~]# ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1
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
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 00:16:3e:2c:35:ec brd ff:ff:ff:ff:ff:ff
inet 172.29.184.223/20 brd 172.29.191.255 scope global dynamic eth0
valid_lft 315293768sec preferred_lft 315293768sec
3: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
link/ether 02:42:62:ed:5b:c5 brd ff:ff:ff:ff:ff:ff
inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
valid_lft forever preferred_lft forever
17: vethd265c9d@if16: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP group default
link/ether a2:6f:df:7e:37:ab brd ff:ff:ff:ff:ff:ff link-netnsid 0
21: veth4657a66@if20: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP group default
link/ether 42:55:d7:6f:a5:23 brd ff:ff:ff:ff:ff:ff link-netnsid 1
3、进入tomcat02 容器查看 ip addr
[root@gh ~]# docker exec -it tomcat02 ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1
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
20: eth0@if21: <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 brd 172.17.255.255 scope global eth0
valid_lft forever preferred_lft forever
我们发现这个容器带来的网卡,都是一对一对的
evth-pair 就是一对虚拟设备接口,他们都是成对出现的,一段连着协议,一段彼此相连
正因为有这个特性 evth-pair 充当一个桥梁,链接各种虚拟网络设备
# 我们发现这个容器带来的网卡,都是一对一对的
# evth-pair 就是一对虚拟设备接口,他们都是成对出现的,一段连着协议,一段彼此相连
# 正因为有这个特性 evth-pair 充当一个桥梁,链接各种虚拟网络设备
4.尝试tomcat01 和 tomcat 02 是否可以连通 可以 ping 通
[root@gh ~]# docker exec -it tomcat02 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.167 ms
结论:容器和容器之间是可以相互ping通的
网络模型图
结论:
tomcat01和tomcat02公用一个路由器,docker0。
所有的容器不指定网络的情况下,都是docker0路由的,docker会给我们的容器分配一个默认的可用ip。
多少个可用的ip:
255.255.0.1/16 | 回环地址0.0.0.0 |
0000000.0000000.0000000.0000000 | 最终地址255.255.255.255 |
十进制 255.255.255.255 | 16代表位数,一次8位,两次16位 |
255.255.0.0 | 255.255.0.0 255*255 - 回环地址 -最终地址 ≈ 65535 |
小结:
Docker使用的是Linux的桥接,宿主机是一个Docker容器的网桥 docker0
Docker中所有网络接口都是虚拟的,虚拟的转发效率高(内网传递文件)
只要容器删除,对应的网桥一对就没了!
--link(过时)
思考一个场景:
我们编写了一个微服务,database url=ip: 项目不重启,数据ip换了,我们希望可以处理这个问题,可以通过名字来进行访问容器?
发现直接ping 容器名是ping 不通的
# 发现直接ping 容器名是ping 不通的
[root@gh ~]# docker exec -it tomcat02 ping tomcat01
ping: tomcat01: Name or service not known
解决 --link
# 运行一个容器 tomcat03 --link 链接 tomcat02
[root@gh ~]# docker run -d -P --name tomcat03 --link tomcat02 mytomcat:1.1
4c925f1bff5240adc3d52433b5e8211e6ab2ceb0d881516a63e30f3473c01220
# --link 可以解决网络连通问题
[root@gh ~]# docker exec -it tomcat03 ping tomcat02
PING tomcat02 (172.17.0.3) 56(84) bytes of data.
64 bytes from tomcat02 (172.17.0.3): icmp_seq=1 ttl=64 time=0.132 ms
64 bytes from tomcat02 (172.17.0.3): icmp_seq=2 ttl=64 time=0.086 ms
问题:反向不可以ping通
# 反向可以ping 通? 不可以
[root@gh ~]# docker exec -it tomcat2 ping tomcat03
Error: No such container: tomcat2
原理:
# 43f1237ecf7b docekr0 bridge 桥接
[root@gh ~]# docker network ls
NETWORK ID NAME DRIVER SCOPE
43f1237ecf7b bridge bridge local
73cd845ed154 host host local
b2404bf0eda1 none null local
[root@gh ~]# docker inspect 43f1237ecf7b
其实就是tomcat03 在本地配置了tomcat02的配置
# 查看hosts 配置 原理发现
[root@gh ~]# 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 36457550008f
172.17.0.4 4c925f1bff52
本质探究:
--link就是在我们 hosts 配置中 增加一个 172.17.0.3 tomcat02 36457550008f
tomcat02 没有 配置tomcat03的 地址 所以 tomcat02 ping 不通 tomcat03
[root@gh ~]# 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 36457550008f
自定义网络
查看所有的docekr网络
网络模式
bridge :桥接 docker(默认,自己创建也是用bridge模式)
none :不配置网络,一般不用
host :和所主机共享网络
container :容器网络连通(用得少!局限很大)
测试
# 我们直接启动的命令 --net bridge,而这个就是我们得docker0
# bridge就是docker0
$ docker run -d -P --name tomcat01 tomcat
等价于 => docker run -d -P --name tomcat01 --net bridge tomcat --net bridge默认参数
# docker0,特点:默认,域名不能访问。 --link可以打通连接,但是很麻烦!
# 我们可以 自定义一个网络
# --driver bridge 桥接 默认桥接
#--subnet 192.168.0.0/16 子网
#--gateway 192.168.0.1 网关
$ docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet
[root@gh ~]# docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet
dc62828a2f248a61aaddf2f7af9f9210b7196dd6fb884680ccc74d26de792965
[root@gh ~]# docker network ls
NETWORK ID NAME DRIVER SCOPE
43f1237ecf7b bridge bridge local
73cd845ed154 host host local
dc62828a2f24 mynet bridge local
b2404bf0eda1 none null local
查看我自己的网络
[root@gh ~]# docker network inspect mynet
[
{
"Name": "mynet",
"Id": "dc62828a2f248a61aaddf2f7af9f9210b7196dd6fb884680ccc74d26de792965",
"Created": "2022-03-24T17:26:17.488827348+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@gh ~]# docker run -d -P --name tomcat01-net --net mynet mytomcat:1.1
2f7c94432631b023b70bfffd3f88d8893959a20b38a0e09c394700d6cecb784a
[root@gh ~]# docker run -d -P --name tomcat02-net --net mynet mytomcat:1.1
7fa617a73210d9348e73cb91815571e633ae7759393b9d0f811f1311da7c8437
[root@gh ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
7fa617a73210 mytomcat:1.1 "catalina.sh run" 6 seconds ago Up 4 seconds 0.0.0.0:49158->8080/tcp tomcat02-net
2f7c94432631 mytomcat:1.1 "catalina.sh run" 11 seconds ago Up 9 seconds 0.0.0.0:49157->8080/tcp tomcat01-net
再次查看 我们的自己的网络
[root@gh ~]# docker network inspect mynet
测试:
发现无论是 ping ip 地址 还是容器名 都可以ping 通
# 发现无论是 ping ip 地址 还是容器名 都可以ping 通
[root@gh ~]# docker exec -it tomcat02-net 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.051 ms
^C
--- 192.168.0.3 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.051/0.051/0.051/0.000 ms
[root@gh ~]# docker exec -it tomcat02-net ping tomcat01-net
PING tomcat01-net (192.168.0.2) 56(84) bytes of data.
64 bytes from tomcat01-net.mynet (192.168.0.2): icmp_seq=1 ttl=64 time=0.089 ms
^C
--- tomcat01-net ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
我们自定义的网络docker当我们维护好了对应的关系,推荐我们平时这样使用网络!
好处:
redis -不同的集群使用不同的网络,保证集群是安全和健康的
mysql-不同的集群使用不同的网络,保证集群是安全和健康的
网络连通
测试 :不同网段下的两个容器是否可以 ping 通
# 无法ping 通
[root@gh ~]# docker exec -it tomcat02-net ping tomcat02
ping: tomcat02: Name or service not known
解决:connect
# 测试打通 tomcat02 - mynet
# 连通之后就是将 tomcat02 放到 mynet 网络下
# 一个容器两个 ip地址 !
# 举例: 阿里云服务 公网ip 私网ip
[root@gh ~]# docker network connect mynet tomcat02
[root@gh ~]# docker network inspect mynet
测试: 可以连通
# 可以连通
[root@gh ~]# docker exec -it tomcat02-net ping tomcat02
PING tomcat02 (192.168.0.4) 56(84) bytes of data.
64 bytes from tomcat02.mynet (192.168.0.4): icmp_seq=1 ttl=64 time=0.095 ms
64 bytes from tomcat02.mynet (192.168.0.4): icmp_seq=2 ttl=64 time=0.079 ms
# 依旧是不可以连通的
[root@gh ~]# docker exec -it tomcat02-net ping tomcat01
ping: tomcat01: Name or service not known
结论:
假设要夸网络操作别人,就需要使用 docker network connect 连通