理解Docker0

  • 清空当前环境,保持环境干净
  • 三个网络
  • docker是如何处理网络访问呢

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 测试 查看容器的ip地址 发现出现了 32: eth0@if33  ip地址  是docker 分配的
[root@mylinux ~]# docker exec -it tomcat01 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
32: eth0@if33: <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通容器中的ip
# 可以ping 通容器内部
[root@mylinux ~]# 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.094 ms
64 bytes from 172.17.0.2: icmp_seq=2 ttl=64 time=0.060 ms
64 bytes from 172.17.0.2: icmp_seq=3 ttl=64 time=0.060 ms
64 bytes from 172.17.0.2: icmp_seq=4 ttl=64 time=0.056 ms

原理:
我们每启动一个docker容器,docker就会给docker容器分配一个ip,我们只要安装了docker,就会有个网卡docekr0,它是桥接模式,使用的技术是evth-pair技术

当我们启动过容器后再次查看主机的ip addr会发现多了一对网卡 与容器中一致

当我们再次启动一个容器的时候,发现又多了一对网卡 ,与刚刚启动的容器中的一致

我们发现这个容器带来的网卡都是一对一对的
evth-pair 就是一对的虚拟设备接口,他们都是成对出现的,一段连着协议,一段彼此相连

那两个容器之间是否也可以ping通呢?

1
2
3
4
5
6
7
# 答案是也可以ping通的
root@d381d1c0f2ae:/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.083 ms
64 bytes from 172.17.0.2: icmp_seq=2 ttl=64 time=0.072 ms
64 bytes from 172.17.0.2: icmp_seq=3 ttl=64 time=0.068 ms
64 bytes from 172.17.0.2: icmp_seq=4 ttl=64 time=0.067 ms

这就是容器之间访问桥接的过程

结论: tomcat01 和 tomcat02 是公用的路由器 docker0

所有容器不指定网络的情况下,都是由docker0路由的,docker会给我们的容器分配一个默认的可用ip

Docker 中的所有网络接口都是虚拟的。虚拟的转发效率高。(内网传递文件)

只要容器删除,对应的桥接就没了

–link

思考一个场景,我们编写了一个微服务,database url=ip 项目不重启,数据库ip换掉了,我们希望处理这个问题,是否可以用名称来进行访问容器?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# 当我们使用一个容器去ping另一个容器服务名的时候发现是直接ping不通的

[root@mylinux ~]# docker exec -it tomcat01 ping tomcat02

ping: tomcat02: Name or service not known

# 我们可以使用 --link 来进行配置 当我们在启动容器的时候 我们可以使用 --link 来指定另一个服务的服务命,这样我们就可以ping通了
# 来启动一个tomcat进行测试

[root@mylinux ~]# docker run -d -P --name tomcat03 --link tomcat02 tomcat
c0c6032ecdcf8ab78567f85983748362c232e28b5bbde27de77f236f9b816ebc
[root@mylinux ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
c0c6032ecdcf tomcat "catalina.sh run" 9 seconds ago Up 7 seconds 0.0.0.0:32771->8080/tcp tomcat03
d381d1c0f2ae tomcat "catalina.sh run" 31 minutes ago Up 31 minutes 0.0.0.0:32770->8080/tcp tomcat02
b68146ac8a6a tomcat "catalina.sh run" 45 minutes ago Up 45 minutes 0.0.0.0:32768->8080/tcp tomcat01
[root@mylinux ~]# docker exec -it c0c6032ecdcf 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.091 ms
64 bytes from tomcat02 (172.17.0.3): icmp_seq=2 ttl=64 time=0.068 ms
64 bytes from tomcat02 (172.17.0.3): icmp_seq=3 ttl=64 time=0.107 ms
64 bytes from tomcat02 (172.17.0.3): icmp_seq=4 ttl=64 time=0.110 ms

反之,我们使用tomcat02去pingtomcat03可以ping通吗?

1
2
3
# 结果是不可以的
[root@mylinux ~]# docker exec -it d381d1c0f2ae ping tomcat03
ping: tomcat03: Name or service not known

探究Inspect

为什么tomcat03配置过能直接ping通呢?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# 我们可以去tomcat03的host文件查看是否绑定了tomcat02的ip地址

[root@mylinux ~]# 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
# 发现这里配置了tomcat02的映射,所以在我们访问tomcat02的时候其实就是访问的 172.17.0.3

**172.17.0.3 tomcat02 d381d1c0f2ae**
172.17.0.4 c0c6032ecdcf

# 当我们去查看tomcat02的时候 发现tomcat02的host里面没有与tomcat03做映射 所以它才ping不通

[root@mylinux ~]# 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 d381d1c0f2ae

我们现在使用Docker现在已经不建议使用 – link来进行配置了

可以自定义网络 不使用Docker0

Docker0的问题:它不支持容器名连接访问