在本节中,我们将重点介绍如何扩展内核。在某种意义上,这里的内容是高级的和可选的。一般来说,你在日常工作中不需要它。
配置和编译你自己的Linux内核超出了本书的范围。关于如何做到这一点的信息,我推荐Greg Kroah-Hartman的 Linux Kernel in a Nutshell (O'Reilly),他是主要的Linux维护者和项目负责人之一。他涵盖了所有的任务,从下载源代码到配置和安装步骤,再到运行时的内核选项。
让我们从一些简单的东西开始:如何知道你正在使用的内核版本?你可以使用以下命令来确定这一点:
❶从这里的uname输出可以看出,在撰写本书时,我正在x86_64机器上使用5.11内核( https://oreil.ly/FJdA1 )(参见2.2.1节)。
现在我们知道了内核版本,我们可以解决如何将内核扩展到树外的问题——也就是说,不需要向内核源代码添加特性,然后再构建它。对于这个扩展,我们可以使用模块,所以让我们来看看它。
简单地说,模块就是可以按需加载到内核中的程序。也就是说,你不必重新编译内核或重新启动计算机。现在,Linux自动检测大部分硬件,并自动加载它的模块。但也有需要手动加载模块的情况。考虑以下情况:内核检测到一个视频卡并加载一个通用模块。但是,显卡制造商提供了一个更好的第三方模块(在Linux内核中不可用),你可以选择使用。
要列出可用的模块,运行以下命令(输出经过编辑,因为我的系统上有超过1000行):
太好了!但是内核实际上加载了哪些模块呢?让我们来看看(输出被缩短):
注意,上述信息可以通过 /proc/modules 。获得这要归功于内核通过伪文件系统接口公开这些信息。关于这个主题的更多内容将在第6章中介绍。
如果想要了解更多关于模块信息或操作内核模块的好方法,那么modprobe就是你的朋友。例如,列出依赖项:
接下来我们介绍一种扩展内核的现代方法。
扩展内核功能的一种越来越流行的方法是eBPF。最初被称为伯克利包过滤器(BPF),现在的内核项目和技术通常被称为eBPF(一个没有任何含义的术语)。
从技术上讲,eBPF是Linux内核的一个特性,你需要Linux内核3.15或更高版本才能使用它。它使你能够使用bpf( https://oreil.ly/cltxg )系统调用安全有效地扩展Linux内核函数。eBPF是使用自定义的64位RISC指令集作为内核虚拟机实现的。
如果你想了解更多关于eBPF在哪个内核版本中启用了什么,那么你可以使用GitHub( https://oreil.ly/HtKO8 )上的iovisor/bcc文档。
在图2-5中,你可以看到来自Brendan Gregg的书 BPF Performance Tools: Linux System and Application Observability ( https://oreil.ly/sfYKK ,Addison Wesley)的高级概述。
eBPF已经在许多地方和用例中使用,例如:
作为CNI插件,在Kubernetes中实现pod网络
例如,在Cilium( https://oreil.ly/BS0iz )和Project Calico中。同样,对于服务可扩展性也是如此。
对可观测性
对于Linux内核跟踪,例如使用iovisor/bpftrace( https://oreil.ly/0M0oV ),以及在集群设置中使用Hubble( https://oreil.ly/7yzhq ),请参阅第8章。
作为一种安全控制
例如,执行容器运行时扫描,你可以在CNCF Falco( https://falco.org )等项目中使用。
用于网络负载均衡
比如Facebook(Meta)的L4 katran( https://oreil.ly/HqMZg )库。
图2-5:Linux内核中的eBPF概述
在2021年年中,Linux基金会宣布,Facebook、谷歌、Isovalent、微软和Netflix联合起来创建了eBPF基金会( https://oreil . ly/g2buM ),并通过它为eBPF项目提供了一个供应商中立的家。请继续关注!
如果你想了解最新情况,请查看 eppf .io 。