docker bridge网络类型研究

bridge模式是docker的默认网络模式,使用docker run -p时,docker实际是在iptables做了DNAT规则,实现端口转发功能。可以使用iptables -t nat -vnL查看。bridge模式如下图所示:

当Docker进程启动时,会在主机上创建一个名为docker0的虚拟网桥,此主机上启动的Docker容器都会连接到这个虚拟网桥上。虚拟网桥的工作方式和物理交换机类似,这样主机上的所有容器就通过交换机连在了一个二层网络中。

从docker0子网中分配一个IP给容器使用,并设置docker0的IP地址为容器的默认网关。在主机上创建一对虚拟网卡veth pair设备,Docker将veth pair设备的一端放在新创建的容器中,并命名为eth0(容器的网卡),另一端放在主机中,以vethxxx这样类似的名字命名,并将这个网络设备加入到docker0网桥中。可以通过brctl show命令查看。

## 使用busybox启动一个调试容器,开启http服务
[root@localhost ~]# docker run -d --name web01 -v /opt:/test/ -p 81:80 busybox:latest sh -c "httpd -h /test/ -p 80 -f"
9301a015f684565c9cf159eeb5150f629cd73e7e0debeb4fbe943b9212b61a01
[root@localhost ~]# 
[root@localhost ~]# docker ps
CONTAINER ID   IMAGE            COMMAND                  CREATED          STATUS         PORTS                               NAMES
9301a015f684   busybox:latest   "sh -c 'httpd -h /te…"   10 seconds ago   Up 9 seconds   0.0.0.0:81->80/tcp, :::81->80/tcp   web01

 从上图中我们可以看到,可以看到容器内部和Linux主机都会创建一个新的网卡,而这两个网卡都是成对的。使用的技术就是evth-pair。evth-pair 就是一对的虚拟设备接口,他们是成对出现的,一段连着协议,一段彼此相连。evth-pair充当一个桥梁,连接各种虚拟网络设备。

Docker容器完成bridge网络配置的过程如下:
  1. 在主机上创建一对虚拟网卡veth pair设备。veth设备总是成对出现的,它们组成了一个数据的通道,数据从一个设备进入,就会从另一个设备出来。因此,veth设备常用来连接两个网络设备。
   2. Docker将veth pair设备的一端放在新创建的容器中,并命名为eth0。另一端放在主机中,以veth9a3cee8这样类似的名字命名,并将这个网络设备加入到docker0网桥中。
   3. 从docker0子网中分配一个IP给容器使用,并设置docker0的IP地址为容器的默认网关。
从宿主机直接访问容器中的httpd服务,抓取发请求的数据包查看网络链路。

新开一个终端窗口执行tcpdum命令进行抓包

[root@localhost ~]# tcpdump tcp -i veth9a3cee8 -s 0 -c 20  -w 3.cap
tcpdump: listening on veth9a3cee8, link-type EN10MB (Ethernet), capture size 262144 bytes

在另外的终端,对httpd发送请求

[root@localhost ~]# curl 127.0.0.1:81
<HTML><HEAD><TITLE>404 Not Found</TITLE></HEAD>
<BODY><H1>404 Not Found</H1>
The requested URL was not found
</BODY></HTML>
[root@localhost ~]# curl 127.0.0.1:81
<HTML><HEAD><TITLE>404 Not Found</TITLE></HEAD>
<BODY><H1>404 Not Found</H1>
The requested URL was not found
</BODY></HTML>
[root@localhost ~]# 

 这里虽然返回404但是不要紧,请求和响应已经完成了,我们把抓到的包用wireshark工具打开分析

 

 

 可以看到在宿主机上向容器服务发送请求,其实就是docker0网桥在与容器内的eth0通信,对127.0.0.1:81 的请求 端口转发到了172.17.0.2:80;

红框部分是三次握手的过程,紧接着就正式发送http get请求了。

。。。

后面再研究容器与容器的通信、不同主机内容器的通信

 


原文链接:https://blog.csdn.net/CSDN1csdn1/article/details/123961079

posted @ 2023-02-15 15:26  高佳丰  阅读(93)  评论(0编辑  收藏  举报