Docker网络理论

一、Docker网络理论

1.1理解docker0网桥

当我们安装完好后启动Docker,Docker会为我们自动创建一个 docker0网桥 可以使用ifconfig 命令查看到 如下图:

可以看到 docker0和服务器上其他网卡级别相同,那 docker0是不是可以理解成网卡呢?
答案:当然不能
docker0是网桥,可以通过brctl show命令查看到

[root@instance-xsv07pjt ~]# brctl show
bridge name	bridge id		STP enabled	interfaces
docker0		8000.02423dff5dcf	no		

可以把docker0抽象理解成交换机,就好比在公司内网咱们的服务器连接这交换机,服务器与服务器之间就可以相互通信了,把交换机理解成docker0 把服务器理解成 container,见下图 瞬间豁然开朗:

1.2 veth pair(虚拟网线)

上面说到,公司内网交换机连接服务器,是不是得需要一条物理网线,交换机与服务器两端连接,这样设备才能相互通信。
docker0,与container类似但不是通过 物理网线 连接 而是通过 虚拟网线(veth pair)

veth pair的全称是:virtual ethernet,就是虚拟的网卡设备接口 如下图所示:

1、创建 centos-1 容器 并且安装 ethool
veth pair都是成对出现的这个结论 可以通过 ethtool 命令验证 如下小实验:

docker run -itd --name centos-1 centos:7
docker exec -it centos-1 /bin/bash
yum -y install ethtool

2、查看容器内

[root@instance-xsv07pjt ~]# docker exec centos-1 ethtool -S eth0
NIC statistics:
     peer_ifindex: 21

3、宿主机查看

[root@instance-xsv07pjt ~]# ip addr
.....
21: veth706c644@if20: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP group default 
    link/ether c6:4a:26:fa:77:f1 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet6 fe80::c44a:26ff:fefa:77f1/64 scope link 
       valid_lft forever preferred_lft forever

上面小实验验证结果就是 容器内 21 和宿主机 21组成一对 veth pair设备,彼此流量互通!

总结:

  • 1、veth pair 全称是virtual ethernet
  • 2、veth pair 是成对出现的一种虚拟网络设备接口

二、容器网络互通理论

2.1小实验:容器之间是否可以通信?

1、首先创建两个Nginx容器

docker run -itd --name nginx-1 nginx:1.18.0
docker run -itd --name nginx-2 nginx:1.18.0

nginx-1:172.17.0.3
nginx-2:172.17.0.4
它们的网关都是172.17.0.1也就是docker0,如下图所示:

2、验证两个container能否通信

docker exec nginx-1 curl 172.17.0.4
......
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>

很显然 实验结果是网络可以相互通信!

2.2为什么?容器之间可以相互通信?

1、当我们使用 172.17.0.3 curl 172.17.0.4172.17.0.3必须按照 以太网协议 将数据封装好 如:

src ip = 172.17.0.3
src mac = 172.17.0.3的mac地址
dst ip = 172.17.0.4
dst mac = 172.17.0.4的mac地址

2、172.17.0.3首先会在本地缓存查找 172.17.0.4的mac地址,如果没有则发送arp请求,可以使用arp -n名称查看到是否有缓存

arp -n

3、arp请求大致如下:

- 这是一个arp请求包
- 我的ip地址是:172.17.0.3
- 我的mac地址是:172.17.0.3的mac地址
- 请问:ip地址为:172.17.0.4的机器,你的mac地址是多少?

4、172.17.0.3 会查询自己的路由表,将这个arp请求从自己的gateway发送出去

# 172.17.0.3容器里面查看 `route -n`
[root@7494780ab73b /]# route -n                
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         172.17.0.1      0.0.0.0         UG    0      0        0 eth0
172.17.0.0      0.0.0.0         255.255.0.0     U     0      0        0 eth0

我们会发现 172.17.0.3的网关地址其实就是docker0
所以这个arp请求包会被发送到docker0上,由docker0拿到这个arp包发现,目标ip是172.17.0.4并不是自己,所以docker0会进一步将这个arp请求报文广播出去,所有在172.17.0.0网段的容器都能收到这个报文!其中就包含了咱们要找的172.17.0.4

172.17.0.4收到这个arp报文后,会判断,哦!目标ip就是自己的ip,于是它将自己的mac地址填充到arp报文中返回给docker0!
172.17.0.3拿到``172.17.0.4`的mac地址 以太网协议需要信息齐全了 然后就可以通信了!

2.3总结:


1、172.17.0.3 会查询自己的arp缓存是否有 172.17.0.4 的mac地址,如果有就可以直接通信,没有则需要发送arp请求。
2、172.17.0.3 会查询自己的路由表,将这个arp请求从自己的gateway(docker0)发送出去
3、docker0 广播这个arp请求 172.17.0.0网段的容器都能收到这个报文
4、172.17.0.4收到这个请求 填写自己的mac地址返给 docker0
5、以太网协议需要信息齐全了 然后就可以通信了!

三、Docker网络模式

Docker 有 bridge、none、host、container 四种网络模式,提供网络隔离、端口映射、容器间互通网络等各种支持
1、bridge模式:
默认网络模式,通过网桥进行网络通信,也就是咱们上面介绍的 就不画图解释了

2、none模式:
这种网络模式下容器只有 lo 回环网络,没有其他网卡,这种类型的网络没有办法联网,外界也无法访问它,封闭的网络能很好地保证容器的安全性。极少使用到这种网络

3、host网络
host 模式会让容器与主机共享网络,此时映射的端口可能会生产冲突,但是容器的其余部分(文件系统、进程等)依然是隔离的,此时容器与宿主机共享网络。

posted @ 2022-11-15 16:28  乱七八糟博客备份  阅读(134)  评论(0编辑  收藏  举报