【前言】
2015年,David是Docker公司(一家让容器技术变得流行的公司)的一名核心开发工程师。他的日常工作包括两部分:维护Docker社区和促进Docker项目发展。他既需要审查贡献者提交的PR,也需要确保Docker可以在各种场景下稳定高效地工作,特别是在成千上万容器运行的高负载场景下。
当时,我们采用火焰图来分析Docker相关的性能问题。火焰图提供的高级可视化功能,可以让我们非常方便地浏览分析的数据。Go语言通过内嵌的HTTP服务可以非常容易地提取到应用的性能数据,并能够基于性能数据产生数据图表。David曾写过一篇文章,讲述Go语言的性能分析器,并描述如何基于数据生成火焰图。但是,使用Go语言性能分析器来收集Docker的性能数据也存在着一些问题,因为性能分析器的功能默认是关闭的。所以,如果要开启性能调试,我们必须要重启Docker服务,这可能导致失去运行时的性能数据,迫使我们花费时间等待问题再次重现。David的文章中提到了重启Docker是诊断Docker性能问题的必要步骤。但是,最好的方式应该是不重启服务就能达到分析性能问题的目的。这驱使David开始研究收集和分析程序性能指标的各种技术,不久他就发现了BPF。
与此同时,与David相距甚远的Lorenzo,也在寻求一种更好地研究Linux内核内部机制的方式,他发现学习BPF可以更容易地了解更多的内核子系统。几年后,他已经在InfluxData的工作中应用了BPF技术,以更快地在InfluxCloud中提取数据。如今Lorenzo不仅活跃于BPF社区,他还就职于Sysdig公司,从事Falco项目中IOVisor工具的开发—IOVisor使用BPF来保证容器和Linux系统的运行时安全。
在过去的几年时间内,我们已经尝试在更多的场景中使用BPF,包括收集Kubernetes集群数据、管理网络流量策略。通过阅读BPF领导者Brendan Gregg、Alexei Starovoitov,以及Clilium和Facebook公司的诸多技术博客,我们学习了BPF技术的底层原理。他们的博客和文章给予了我们极大的帮助,同时也是本书诸多引用的来源。
每次学习BPF技术时,我们都需要翻阅博客文章、手册以及Internet上的各种资料。本书的目的就是将分散在各处的知识汇总在一起,以便于BPF爱好者能更好地学习这一神奇技术。
本书分为9章演示如何使用BPF完成相关任务。你可以单独阅读一些章节作为参考指南,但是如果你是BPF的新手,我们建议你按顺序阅读。这样你可以了解BPF的核心概念,并逐步了解BPF在未来可能发挥的作用。
无论你是可观测性和性能分析方面的专家,还是正尝试开始研究新技术来解决生产系统问题的新手,我们都希望你能从本书中受益。
【提供示例代码下载】
可以从https://oreil.ly/lbpf-repo下载补充材料(示例代码、练习等)。
【译者序】
学习的心与勇气的赞歌
2019年10月,当我听到这本书的英文版即将面世时,第一时间就意识到这将是BPF方面的第一本书。我从事容器和Kubernetes领域的工作与研究多年,看到这本书中介绍的BPF理论知识和技术时非常兴奋,我意识到终于有机会可以全面地了解和学习BPF专业知识了。我立刻开始着手翻译这本书,并找到狄卫华老师,邀请他一起翻译,以此跟大家分享BPF专业知识和技术。
天才计算机大师Alan Kay曾说过:“在计算机世界中,每一次突飞猛进都是因为软件产品允许用户进行各种编程。”有的人说:“软件正在占据世界。”作为Linux内核可观测性技术,BPF有一种神奇的能力,可以帮助我们在不了解软件内部逻辑的情况下快速定位程序的问题。BPF正在占据软件世界。
提到BPF,你可能比较生疏,但是说起tcpdump、wireshark这些流行的网络抓包和分析工具,你一定听说过并且很可能使用过,这些技术的底层的数据包过滤用的就是BPF。最初BPF程序等同于数据包过滤。之后,BPF以疯狂的速度发展。近年来已经成长为一个高度灵活且功能丰富的框架,它能够在不牺牲系统性能和安全性的前提下,允许用户编写BPF程序对内核事件进行观测。BPF比重新编译内核模块更容易、更安全。从网络方面而言,基于eBPF技术实现的XDP技术,在网络包还未进入网络协议栈之前就对其进行处理,提供了高性能、可编程的网络数据路径,给Linux网络带来了巨大的性能提升。BPF强大的灵活性、稳定性和丰富的功能,使得谷歌、Facebook和Netflix等前瞻性大企业纷纷对它伸出橄榄枝,它们纷纷利用BPF来实现网络安全、负载均衡、性能监控、故障排查等大量应用。同时,基于BPF的Cilium在容器领域也锋芒初现,提供了强大而高效的网络、稳定的安全性,以及3~7层的负载均衡。
本书涵盖BPF技术的各个方面,包括BPF架构、BPF映射,使用BCC编写BPF程序实现Linux可观测性,以及XDP、网络、安全等方面的体系化与结构化的介绍。作为BPF技术的爱好者, 我们希望通过翻译本书,能将这种体系和理念分享给更多的人,期待与大家更深入地探讨与交流。
很荣幸这次能跟狄卫华老师合作完成本书的翻译,感谢在翻译过程中他对我的各种帮助。同时,感谢倪朋飞老师耐心地帮我们进行技术审查和指导,感谢KS2微信群和Kubernetes社区的朋友对我们的各种帮助。最后,感谢我的家人,是他们的支持和耐心陪伴让我踏踏实实地利用业余时间完成了这件事。对我而言,这是我人生中做得最有意义的事情之一。
(范彬)
【序言】
作为一名程序员,我喜欢紧跟内核和计算研究方面的各种最新技术。当第一次接触到BPF和XDP(eXpress Data Path)技术时,我就被深深地吸引了。我非常高兴本书聚焦于BPF和XDP技术,让更多的人在项目中使用如此优秀的技术。
首先聊聊我的背景以及我为什么如此喜欢研究内核。我曾与David一起担任Docker核心维护人员,主要负责使用iptables为容器提供过滤和路由逻辑。我提交的第一个PR就是修复CentOS上不同版本iptables命令行参数不兼容而执行失败的问题。如果你和我一样,经常开发和使用命令行工具,那么你也一定会遇到过很多诸如此类的问题。除此之外,在主机上构建成千上万的规则也会让iptables不堪重负,我需要解决由此导致的系统性能问题。
当我接触BPF和XDP工具后,简直如获珍宝。我不再苦恼于使用iptables遇到的类似问题。另外,我非常高兴地获悉内核社区甚至计划使用BPF(https://oreil.ly/cuqTy)替代iptables,同时,容器网络工具Cilium(https://cilium.io)也正在采用BPF和XDP进行构建。
除了可以实现更加优秀的iptables的功能外,BPF还可以实现更多的功能,比如,帮助我们跟踪系统调用、内核函数和用户态的程序。Linux系统上的bpftrace(https://github.com/iovisor/bpftrace)命令行工具实现了类似于DTrace的强大的功能。bpftrace可以跟踪所有正在打开的文件句柄、打开文件的进程,统计程序的系统调用,跟踪OOM killer,等等,一切尽在掌握之中。BPF和XDP也被用在Cloudflare(https://oreil.ly/OZdmj)和Facebook的负载均衡器(https://oreil.ly/wrM5-)上,用于防御DDoS攻击。XDP在网络过滤数据包方面表现得相当出色,在本书的XDP和网络部分可以了解到更多的信息。
我有幸在Kubernetes社区认识了Lorenzo,他开发的kubectl-trace(https://oreil.ly/Ot7kq)工具可以让用户在Kubernetes集群上轻松地运行定制化的跟踪程序。
就个人而言,我也非常喜欢使用BPF编写定制化的跟踪器,向同事证明他们编写的软件需要进行性能优化,或要求他们减少昂贵的系统调用次数以提升程序性能。不要低估通过数据协助别人进行系统调优的威力。不要担心,本书将会指导你编写第一个跟踪程序,并帮助你进行系统性能优化。BPF之前的工具都是通过使用有损队列,将样本集发送到用户空间进行聚合,而BPF则可以在内核空间直接基于事件源构建直方图和过滤,这种机制非常适用于生产环境。
我职业生涯的一半时间都在从事工具开发。最好的工具是提供自治,开发者可以使用工具提供的接口进行自治,工具的使用场景甚至可能超出工具开发者的设计想法。引用Richard Feynman的话:“我很早就意识到知道事情名字和知道事情本身的区别。”到现在为止,我们应该已经知道了BPF的名字,并了解了BPF能给我们带来帮助。
我喜欢这本书是因为它介绍了使用BPF创建新工具所需掌握的知识。阅读本书并完成练习后,你将拥有使用BPF的超级能力。你可以将BPF放置在工具箱中,在最需要时让其发挥作用。通过本书,你不仅能了解到BPF技术,而且也能学习到BPF的工作原理。本书可以帮你打开思路来探索使用BPF进行各种实践的途径。
这个欣欣向荣的生态系统非常令人兴奋!我希望越来越多的人开始使用BPF,并将BPF的力量变得更加强大。我很乐意了解本书的读者最终会采用BPF构建什么,无论是用来跟踪软件错误、自定义防火墙还是编写红外解码(https://lwn.net/Articles/759188)的脚本。请让我们知道你如何使用BPF进行构建!
—Jessie Frazelle
【作者简介】
★大卫·卡拉维拉(David Calavera)
是Netlify的CTO,曾是Docker的维护者以及Runc、Go和BCC工具及其他开源项目的贡献者。他构建和促进了Docker插件生态系统,因Docker项目的工作而闻名。David非常喜欢使用火焰图和进行性能优化。
★洛伦佐·丰塔纳(Lorenzo Fontana)
是Sysdig开源团队的成员,主要负责CNCF(云本地计算基础)的Falco项目,该项目通过内核模块和eBPF实现了容器运行时安全和异常检测功能。他对分布式系统、软件定义网络、Linux内核和性能分析充满热情。
【译者简介】
★范彬
在容器技术领域工作多年,潜心研究,对Docker、Kubernetes技术有丰富的实践经验,一直保持热情和努力去研究新的内核和网络等方面的技术。现任中国电信天翼云容器组组长,带领团队研发了具有100%自主知识产权的天翼云容器引擎平台,并在金融等多个行业得到成功应用。
★狄卫华
趣头条资深架构师,拥有近 15 年的软件研发和架构经验,专注于高并发、微服务架构和云原生技术,具有丰富的大型软件架构设计和实施落地经验;熟悉Linux内核技术和网络、擅长性能调优和问题排查定位;熟悉 Kubernetes 和 Docker 技术,有丰富的容器化实践经验。