前言
Calico 从 v3.13 开始,集成了 eBPF 数据平面。
关于什么是 eBPF, 以及 Calico 为什么引入了 eBPF , 并不是本篇文章的重点,感兴趣的朋友可以自行阅读相关文档。
相比于 Calico 的默认基于 iptables 数据平面,eBPF 具有更高的吞吐量以外, 还具有 source IP preservation 这个功能。
在 K8s 中通常都是直接或者间接以 NodePort 方式对外暴露接口的。而对于 K8s 这个分布式集群来讲,通常情况下,客户端连接 Node Port 端口的节点和负责响应请求的后端业务 Pod 所在的节点不是同一个节点,为了打通整个数据链路,就不可避免的引入了 SNAT。但是这样显然也会带来一个副作用,即业务 Pod 在收到 Packet 以后,其 SRC IP 已经不再是客户端的实际 IP(被伪装成节点的内网 IP )。另一方面,对于一些业务应用来讲,获取客户端 IP 是一个实实在在的刚需。比如:业务应用需要通过客户端 IP 来获取客户登陆的 geo 信息。
目前 K8s 主要是通过设置 externaltrafficpolicy 来规避这个问题的,但是这个方案本身并不能完全令人满意。Calico 从 v3.13 开始通过集成 eBPF 优雅地解决了这个问题。
Calico eBPF要求
- Calico >= 3.13
- Linux Kernel >= 4.18
- 节点/sys/fs/bpf需要挂载BPF文件系统
内核升级
系统: CentOS 7
内核版本不满足要求,因此需要升级内核。内核小版本更新很快,可以去 http://ftp.sjtu.edu.cn/sites/elrepo.org/linux/kernel/el7/x86_64/RPMS/ 自行查找。
wget https://mirrors.nju.edu.cn/elrepo/kernel/el7/x86_64/RPMS/kernel-lt-5.4.146-1.el7.elrepo.x86_64.rpm
rpm -ivh kernel-lt-5.4.146-1.el7.elrepo.x86_64.rpm
cat /boot/grub2/grub.cfg | grep menuentry
grub2-set-default 'CentOS Linux (5.4.146-1.el7.elrepo.x86_64) 7 (Core)'
grub2-editenv list
grub2-mkconfig -o /boot/grub2/grub.cfg
reboot
检查BPF文件系统
(1)挂载文件系统
mount | grep "/sys/fs/bpf"
none on /sys/fs/bpf type bpf (rw,relatime)
如果上面返回空,则需要挂载BPF文件系统。命令如下:
mount bpffs -t bpf /sys/fs/bpf
检查Calico版本
Calico版本不得低于3.13,如果版本太低,需要升级Calico版本,Calico版本升级很简单,到DockerHub上找到符合要求的版本即可。
切换Calico数据平面到eBPF
关闭kube-proxy
kubectl patch ds -n kube-system kube-proxy -p '{"spec":{"template":{"spec":{"nodeSelector":{"non-calico": "true"}}}}}'
开启eBPF模式
这里可以使用calicoctl客户端工具进行patch。
calicoctl patch felixconfiguration default --patch='{"spec": {"bpfKubeProxyIptablesCleanupEnabled": false}}'
calicoctl patch felixconfiguration default --patch='{"spec": {"bpfEnabled": true}}'
calicoctl patch felixconfiguration default --patch='{"spec": {"bpfExternalServiceMode": "DSR"}}'
评论区