eBPF Talk: 混部环境下无损升级 XDP 程序的思路

文摘   2024-05-20 08:11   新加坡  

混部环境指的是当前服务器不是 XDP 程序独占的,部署有其它的网络服务。

如果服务器使用的是 Intel 网卡、而且 XDP 程序采用 Native 模式挂载到网卡上,那么在挂载和卸载 XDP 程序时,会导致网络中断,这会影响到其它网络服务。

本文介绍了一种无损升级 XDP 程序的思路,能够解决这个问题。

XDP 部署方式

XDP 程序采用 Native 模式挂载到网卡上,并且 pin 到指定 bpffs 路径上。

将 XDP 程序 pin 到 bpffs 是为了预防用户态程序异常退出导致 XDP 程序被卸载;意即,即使用户态程序异常退出,XDP 程序仍然能够继续运行。

而在项目实战中,会将所有 bpf 对象都 pin 到 bpffs 路径上,这样能够方便管理所有 bpf 对象。

不过,这种部署方式有一个缺点:在升级 XDP 程序时,如果 bpf map 的 key/value size 发生变化,那么就需要将 XDP 程序卸载,将所有 bpf 对象 unpin 掉。

所以,当遇到混部环境时,这种部署方式就会导致网络中断,影响到其它网络服务。

无损升级 XDP 程序的思路

能够无损升级 Native 模式的 XDP 程序的前提,是网卡驱动支持原子更新 XDP 程序。

支持原子更新 XDP 程序的网卡驱动有:mlx5、ixgbe、i40e。ice 驱动还没支持。

所以,只要网卡驱动支持原子更新 XDP 程序,就能够无损升级 XDP 程序。

思路:

  1. 将 bpf 对象所在的目录 mv 到新的目录;
  2. 将 XDP link 对象克隆到原有的路径下;
  3. 在原有路径下,重新生成所有 bpf 对象。
  4. 使用克隆的 XDP link 去更新 XDP 程序。
  5. 删除新的目录。

不过,其中第 2 步是如何克隆 XDP link 对象呢?

如果直接使用 cp 命令,会得到错误:cp: cannot open 'xdp' for reading: Input/output error

这是因为 bpffs 文件系统不支持 cp 命令。

不过,却支持 mv 命令,因为 mv 命令只是修改了文件的路径,而没有修改文件的 inode。

如何绕过这个错误呢?

克隆 XDP link 对象的思路是:LoadPinnedLink() 然后 NewFromID()

  • bpfbak `cloneObj():link`[1]

因此,弄了个小工具:bpfbak[2]bpfbak 能够克隆 pinned bpf 对象,然后 pin 到另一个路径上。

$ ./bpfbak -h
bpfbak is a tool to backup eBPF objects

Usage:
  bpfbak [flags]

Flags:
      --auto-mount           automatically mount bpffs at the destination directory or --mount-bpffs
  -d, --dst string           destination filepath to backup the bpf object
  -h, --help                 help for bpfbak
      --mount-bpffs string   path to the directory where bpffs is mounted
  -s, --src string           source bpf object to be backed up
      --unpin-src            unpin the source bpf object after backing up

效果展示:

$ ./bpfbak -s ./test-bpffs-dir/traceroute/xdp -d ./test-bpffs-dir/bak/xdp
$ bpftool l s p ./test-bpffs-dir/bak/xdp
6: xdp  prog 67
    ifindex ens33(2)
$ bpftool l s p ./test-bpffs-dir/traceroute/xdp
6: xdp  prog 67
    ifindex ens33(2)

总结

本文介绍了一种无损升级 XDP 程序的思路,能够解决在混部环境下升级 XDP 程序导致网络中断的问题。

由此需求,衍生了一个小工具:bpfbak[3]。“阅读全文” 即可查看 bpfbak 的源码。

参考资料
[1]

bpfbak cloneObj():link: https://github.com/Asphaltt/bpfbak/blob/c96bde64671f842681c5ec7eca663a1d21357a28/bpfbak.go#L94

[2]

bpfbak: https://github.com/Asphaltt/bpfbak

[3]

bpfbak: https://github.com/Asphaltt/bpfbak

eBPF Talk
专注于 eBPF 技术,以及 Linux 网络上的 eBPF 技术应用