推广 热搜: 公司  快速  上海  中国    未来  企业  政策  教师  系统 

Linux Bridge 和 Veth Pair 设备简介

   日期:2024-11-19     作者:xinet    caijiyuan   评论:0    移动:http://keair.bhha.com.cn/mobile/news/1115.html
核心提示:Linux Bridge 和 Veth Pair 设备,理解清楚这两种设备对后续理解容器化网络会比较有帮助。我们先看一下 veth pair,这是成对出现

Linux Bridge 和 Veth Pair 设备,理解清楚这两种设备对后续理解容器化网络会比较有帮助。

Linux Bridge 和 Veth Pair 设备简介

我们先看一下 veth pair,这是成对出现的虚拟网络设备,可以简单想象这是两块网卡,中间有一条网线相连。 Linux Bridge 和 Veth Pair 设备简介

通过 ip 命令,可以创建 veth pair,我们创建和,分别绑定 IP 并置为 UP 状态:


查看一下网络设备状态,和已经正常创建并绑定 IP:


我们尝试一下将 vair pair 的一段置为 DOWN,再查看一下网络设备状态,可以看到我只是将置为 DOWN,但是随之也进入 M-DOWN 的状态。因为 veth pair 的两块网络设备彼此对向,当置为 DOWN 时,意味着它无法接受数据,随之另一端也就不能正常工作,所以内核会将其自动置为 M-DOWN,以保持两端的一致性。


我们说和逻辑上有一根网线相连,所以理论上通过 ping 是能通的,我们试一下:


可以看到并不能 ping 通,我们在抓包看下:


原因是和虽然处在同一网段,但由于是第一次通信,所以 ARP 表中并不存在的 MAC 信息,需要先发送 ARP Request,但是并没有收到响应。这是因为 Ubuntu 内核中一些默认配置限制导致的,我们先放开限制:


现在就能 ping 通了:


我们在和抓包看一下过程:


从和的微小的时间戳上的差异,我们可以看到当执行 ping 命令时,先接收到 ICMP Request,随即立刻发送给对端的,但是在两个设备上都没有看到 ICMP Reply,可 ping 命令确实显示 。 其实原因很简单,ICMP Reply 是走的 loopback 的口。


我们来看一下数据包的流转过程: Linux Bridge 和 Veth Pair 设备简介

流程大致如下:

  1. 首先 ping 程序构造 ICMP Request,通过 Socket API 发送给内核的网络协议栈;
  2. 在 ping 中我们通过指定走网卡,所以协议栈会将数据包交给;
  3. 由于和间有逻辑上存在的网线,数据包会直接交到;
  4. 接收到数据包后也不做处理,转手交给内核协议栈;
  5. 内核协议栈在接收到数据包后,发现是本地的 IP,所以会构造 ICMP Reply的包,查看路由表之后发现应该走 loopback 的口();
  6. loopback 接收到 ICMP Reply 后,转发给内核协议栈;
  7. 最终协议栈将数据包交给 ping 进程,ping 成功收到 ICMP Reply包;

当给和配置 IP 时,内核会自动在表中添加路由:


我们知道在容器里大量用到 namespace 来实现容器间的隔离性,对容器网络也是一样的,我们先看一下在宿主机默认的 namespace 下的网络设备:


然后我们创建一个 netns ,再查看下中的网络设备:


可以看到在中,只有一个默认创建设备,除此之外,所有的路由规则、防火墙规则等也与默认 namespace 是完全隔离的。

这时候我们想将的网络与宿主机打通,就可以考虑使用 veth pair:


这时候查看默认 namespace 和的网络设备,可以看到和设备配置正常:


然后尝试下通过的接口来 ping 默认 namespace 下的,并在上抓包:


因为 veth pair 的特性,所以即便和处在不同的 namespace,它们之间也可以正常通信,并且在网卡上我们可以看到完整的 ICMP Request 和 ICMP Reply 数据包。

还记得在上面的例子中,ICMP Reply 是走的 loopback 的口吗?在当前的场景里,因为和已经在不同的 namespace 下了,所以当在回包时,去路由表查询,并不会认为 是本地接口,所以会正常从回包,我们可以看下这两个 namespace 的路由表来验证判断:



我们刚才看到了在宿主机默认 namespace 和容器 namespace 之间,通过 veth pair 可以打通网络,逻辑上就相当于宿主机和容器是两台独立的主机,通过一条网线连接在了一起。

正常一台宿主机里不会只有一个容器,宿主机和容器是一对多的关系,如果要打通容器之间的网络,单纯的依赖 veth pair 也可以做到,但配置就比较复杂,所以在这里我们引入 bridge 来实现。

Linux 的 bridge 是内核提供的虚拟以太网桥,原理上类似于物理交换机,工作在第二层。我们在 Linux 上创建一个 bridge,然后将容器通过 veth pair 插入到这个 bridge 上,以实现容器间的网络互通。

首先创建并启用 bridge :


然后通过 namespace 来模拟容器网络:


可以看到容器网络可以正常打通:



在刚才的例子中,处在不同 namespace 的容器网络可以通过 veth pair 与 bridge 相连的方式来相互打通,但是如果容器内想要访问外部的网络,就还需要做一些额外的配置。

这里说明一下我的网络环境,我用来测试的 Ubuntu 的机器是插在一个路由器上的,这个路由器的 IP 是 ,DHCP 的网段是 ,为了使容器网络能跟外部网络通信,这里我们采用简单一点的方式,就是将容器的网卡 IP 设置成物理网卡的 IP 处在同一网段。

首先创建 bridge :


然后创建 namespace 作为容器网络,创建 veth pair 和,其一端放入,另一端插入网桥(这里注意一下我给配置的 IP 是物理网络的网段)。


这里还有一个重要的配置,是在中将默认路由的网关配置为这个物理网络的网关。


此时上已经插入了网卡,但我们知道如果仅仅是这样是无法与外部网络通信的,我们还需要将物理网卡也插入网桥,这样逻辑上物理路由器、物理网卡、和会处在一个二层内。


Linux Bridge 和 Veth Pair 设备简介

通过这样的配置,容器就能正常访问外部网络了。

本文地址:http://keair.bhha.com.cn/news/1115.html    康宝晨 http://keair.bhha.com.cn/ , 查看更多

特别提示:本信息由相关用户自行提供,真实性未证实,仅供参考。请谨慎采用,风险自负。

 
 
更多>同类最新资讯
0相关评论

文章列表
相关文章
最新动态
推荐图文
最新资讯
点击排行
网站首页  |  关于我们  |  联系方式  |  使用协议  |  版权隐私  |  网站地图  |  排名推广  |  广告服务  |  积分换礼  |  网站留言  |  RSS订阅  |  违规举报  |  粤ICP备2023022329号