本篇文章大部分由ChatGPT4生成
最近有业务的容器需要在Kubernetes上运行ROS2,由于ROS2的DDS(Data Distribution Service,数据分发服务)的通讯框架采用了组播的方式将消息分发给订阅者节点以提高效率。所以如果在一个 kubernetes 集群中部署多套ROS2,就会导致在ROS2之间的数据出现串流的情况。解决这个问题,我们需要将组播数据路由到本地的loop回环网卡上。研究了下在Kubernetes CNI中默认插件中的loopback是没有这个支持的。要解决这个需求,需要简单小改下cni 的 loopback 插件,让其在为pod创建loop网卡时,将组播地址224.0.0.0转到的loop网卡。在开始前,我们还是有必要回顾学习下相关的知识。
Loopback网卡是一种特殊的网络接口,用于在本地主机之间建立虚拟的网络连接。它的主要特点是,数据包从一个网络接口发送出去,然后立即返回到同一个接口,而不需要经过任何物理网络设备。在Linux系统中,loopback网卡通常使用“lo”作为设备名,并分配了一个固定的IP地址,即127.0.0.1。
loopback网卡的作用
网络组播是一种特殊的网络通信方式,允许一个数据包同时发送给一组目标地址。组播地址是一个特殊的IP地址范围(IPv4的224.0.0.0至239.255.255.255,IPv6的FF00::/8),用于标识组播组。组播技术在许多场景中都有广泛应用,如在线视频会议、网络电视直播等。
克隆CNI源码到本地 https://github.com/containernetworking/plugins,修改plugins/main/loopback/loopback.go
,在为pod添加loopback网卡的同时将组播 224.0.0.0/4 路由到本地
func cmdAdd(args *skel.CmdArgs) error {
...
err = netlink.LinkSetMulticastOn(link)
if err != nil {
return err // not tested
}
err = netlink.RouteAdd(&netlink.Route{
LinkIndex: link.Attrs().Index,
Scope: netlink.SCOPE_HOST,
Dst: &net.IPNet{
IP: net.IPv4(224, 0, 0, 0),
Mask: net.IPv4Mask(240, 0, 0, 0),
},
})
if err != nil {
return err // not tested
}
...
}
然后使用命令build_linux.sh
编译新的loopback文件,然后将kubernetes节点自带/opt/cni/bin/loopback
文件替换即可。最终当新的Pod运行成功后,我们就可以看到如下效果