使用BPF监视你的Kubernetes集群


如果你已经使用Kubernetes已经有一段时间了,你就会知道你能做的最好的事情就是邀请成千上万的你最好的熟人在没有成人监督的情况下在你的集群上运行任意命令。在将来的某个时刻,您可能想知道您曾经知道的那些人仍然在您的群集上做什么。是不是在挖矿呢?

BPF(Berkeley Packet Filter)是Linux内核中的一个虚拟机,它在收到其中一个事件时对事件进行分类并触发操作。它允许您在运行时将代码注入内核以处理这些事件; 不需要内核编译。BPF有两种风格。本文引用的是扩展版本eBPF,但我只称它为BPF。

另一个更有趣的选择是使用Kubectl Trace来检查容器中正在运行的内容。Kubectl的这个扩展计划一次性作业在容器内运行BPF程序。因此,您可以使用一行命令列出在任何容器中运行的所有进程:

kubectl trace run container -e \ "tracepoint:syscalls:sys_enter_execve { @[comm] = count() }"

此命令将等待容器执行新进程,并将按其命令名称(comm)对正在运行的许多进程进行分组。问题是当你想知道那里发生了什么时,你需要执行这个命令; 它不允许您监视群集使用情况,而无需一直查看它。

我最喜欢的选择是将BPF的Execsnoop部署到每个pod中的sidecar容器,并让它实时登录pod中运行的所有进程。Kubernetes 1.13有一个名为的配置标志shareProcessNamespace,允许您将在pod中生成的所有进程放入同一名称空间,这样您就可以从边车监视pod中的所有容器。这是您的pod定义的开始:

apiVersion: v1
kind: Pod
metadata:
  name: happy-borg
spec:
  shareProcessNamespace: true
  containers:
  - name: execsnoop
    image: calavera/execsnoop
    securityContext:
    - privileged: true
    volumeMounts:
    - name: sys # mount the debug filesystem
      mountPath: /sys
      readOnly: true
    - name: headers # mount the kernel headers required by bcc
      mountPath: /usr/src
      readOnly: true
    - name: modules # mount the kernel modules required by bcc
      mountPath: /lib/modules
      readOnly: true
  - name: container doing random work
  ...

BPF为Kubernetes打开了更好的可观察性的大门。