使用 Docker Desktop进行 BPF 开发

本文涉及的产品
容器服务 Serverless 版 ACK Serverless,952元额度 多规格
容器服务 Serverless 版 ACK Serverless,317元额度 多规格
简介: Docker Desktop 是 Windows 和 Mac 上最为流行 Docker 开发环境。是否有办法在Docker Desktop中,利用容器来使用eBPF呢?

Docker Desktop 是 Windows 和 Mac 上最为流行 Docker 开发环境。我平时很多日常开发和测试也是以 Docker Desktop 为主。之前开发测试eBPF应用大多是直接在Linux上面完成的,是否有办法在Docker Desktop中,利用容器来使用eBPF呢?本文参考了部分 https://github.com/singe/ebpf-docker-for-mac 相关实现,来帮助大家尝试一下。

bcc & bpftrace

Docker Desktop for Mac 通过一个虚拟机,来运行基于Linuxkit构建的操作系统支持Docker环境。我们无法直接访问Virtual Machine,我们需要在 Docker容器中运行 eBPF 工具, 这需要有如下的前提条件:

  • /usr/src/ 需要包含内核源代码
  • debugfs 被正确挂载。 mount -t debugfs debugfs /sys/kernel/debug
  • /lib/modules/ 需要挂载 host 宿主机上相关目录
  • 需要在特权方式运行,比如 docker run --privileged ...
  • 需要使用宿主机 PID 名空间,比如 docker run --pid=host ...

我们首先获取当前宿主机内核版本信息

$ docker run -it --rm --privileged --pid=host justincormack/nsenter1
# uname -r
5.10.47-linuxkit

在Docker Hub上,Docker 在 docker/for-desktop-kernel 仓库中发布了 Docker Desktop 所包含的 linuxkit 内核代码的容器镜像。大家根据上面的内核版本信息就能定位相应的镜像 tag。

然后,我们来构建属于自己的 Docker 镜像,比如我希望构建一个Docker镜像包含,bccbpftrace 等eBPF开发工具。我们创建如下 Dockerfile.tools 来构建相应镜像

FROM docker/for-desktop-kernel:5.10.47-0b705d955f5e283f62583c4e227d64a7924c138f AS ksrc

FROM ubuntu:20.04 AS bpftrace
COPY --from=ksrc /kernel-dev.tar /
RUN tar xf kernel-dev.tar && rm kernel-dev.tar
# Use Alibaba Cloud mirror for ubuntu
RUN sed -i 's/archive.ubuntu.com/mirrors.aliyun.com/' /etc/apt/sources.list
# Install LLVM 10.0.1
RUN apt-get update && apt install -y wget lsb-release software-properties-common && wget https://apt.llvm.org/llvm.sh && chmod +x llvm.sh && ./llvm.sh 10
ENV PATH "$PATH:/usr/lib/llvm-10/bin"

# Build/Install bpftrace
RUN apt-get install -y bpftrace

# Build/Install bcc
WORKDIR /root
RUN DEBIAN_FRONTEND="noninteractive" apt install -y kmod vim bison build-essential cmake flex git libedit-dev \
  libcap-dev zlib1g-dev libelf-dev libfl-dev python3.8 python3-pip python3.8-dev clang libclang-dev && \
  ln -s $(which python3) /usr/bin/python
RUN git clone https://github.com/iovisor/bcc.git && \
    mkdir bcc/build && \
    cd bcc/build && \
    cmake .. && \
    make && \
    make install && \
    cmake -DPYTHON_CMD=python3 .. && \
    cd src/python/ && \
    make && \
    make install && \
    sed -i "s/self._syscall_prefixes\[0\]/self._syscall_prefixes\[1\]/g" /usr/lib/python3/dist-packages/bcc/__init__.py

CMD mount -t debugfs debugfs /sys/kernel/debug && /bin/bash

运行如下命令,构建镜像 (执行时间较长,可以出去喝喝咖啡,吃吃饭)

$ docker build -t ebpf-for-mac -f ./Dockerfile.tools .
[+] Building 6097.8s (16/16) FINISHED
...

或者可以直接拉取以构建好的镜像,

$ docker pull registry.cn-hangzhou.aliyuncs.com/denverdino/ebpf-for-mac
$ docker tag registry.cn-hangzhou.aliyuncs.com/denverdino/ebpf-for-mac ebpf-for-mac

运行如下命令,来通过Docker镜像运行 bcc 测试应用。

$ docker run -it --rm \
  --name ebpf-for-mac \
  --privileged \
  -v /lib/modules:/lib/modules:ro \
  -v /etc/localtime:/etc/localtime:ro \
  --pid=host \
  ebpf-for-mac
  
# wget https://raw.githubusercontent.com/singe/ebpf-docker-for-mac/main/hello_world.py

# python3 hello_world.py
b'      kube-proxy-5454    [003] d... 10679.347316: bpf_trace_printk: Hello world'
b''
b'      kube-proxy-5469    [002] d... 10679.355387: bpf_trace_printk: Hello world'
b''
b'         dockerd-1807    [001] d... 10680.178545: bpf_trace_printk: Hello world'
b''
b'            runc-95361   [003] d... 10680.191472: bpf_trace_printk: Hello world'
b''
...

bpftrace 是IO Visor开发的eBPF的追踪工具。它允许开发者用简洁的DSL(Domain Specific Language)编写eBPF程序,而不必在内核中手动编译和加载它们。具体验证可以参考 Brendan Gregg 的[A thorough introduction to bpftrace
](https://www.brendangregg.com/blog/2019-08-19/bpftrace.html)

在Kubernetes上调度 bpftrace 应用

Docker Desktop也内置了Kubernetes集群开发环境。为了帮助国内开发者解决由于无法访问 gcr.io 镜像仓库,导致无法开启 Kubernetes 的问题,阿里云团队维护了一个简单的 helper 工具可以解决相应问题,请参考: https://github.com/AliyunContainerService/k8s-for-docker-desktop

kubectl-trace 是可以让用户在Kubernetes集群中安排执行bpftrace程序的kubectl插件。它的架构图如下,当通过 kubectl trace 命令创建一个trace应用时,kubectl-trace插件会在Kubernetes集群上,通过API创建一个被称作“trace-runner”的临时任务来执行bpftrace应用,可以调度到指定的节点或者Pod对其进行追踪。

kubectl-trace的安装过程比较简单,请参考 Installing 进行操作。然而其默认带的 trace-runner 镜像是不支持 Docker Desktop,执行会自动退出。我们来根据上文原理,hack 一个扩展的版本。其中的代码实现在 https://github.com/denverdino/trace-runner-for-docker-desktop 项目中。

其实现与上文类似,在 /usr/src/ 中添加内核源代码,并挂载 debugfs , 然后就可以愉快的玩耍了。具体实现可以参见项目中 Dockerfile 与 main.go ,此处不在赘述。其运行效果如下:

$ kubectl trace run docker-desktop --imagename=registry.cn-hangzhou.aliyuncs.com/denverdino/kubectl-trace-runner -e "tracepoint:syscalls:sys_enter_* { @[probe] = count(); }"
trace 7b64f4b4-226e-4aaf-83b1-94858c72f91f created

$ kubectl trace attach 7b64f4b4-226e-4aaf-83b1-94858c72f91f
Attaching 327 probes...

^C
first SIGINT received, now if your program had maps and did not free them it should print them out

@[tracepoint:syscalls:sys_enter_getrlimit]: 1
@[tracepoint:syscalls:sys_enter_newstat]: 1
@[tracepoint:syscalls:sys_enter_fsync]: 1
@[tracepoint:syscalls:sys_enter_rt_sigsuspend]: 2
...

或者利用别名来简化命令使用

$ alias kubectl-trace-run="kubectl trace run --imagename=registry.cn-hangzhou.aliyuncs.com/denverdino/kubectl-trace-runner"
$ kubectl-trace-run docker-desktop -e 'tracepoint:syscalls:sys_enter_open { printf("%s %s\n", comm, str(args->filename)); }'
trace 96209723-f439-4fb8-8bdc-d32e41e53e35 created

$ kubectl trace attach 96209723-f439-4fb8-8bdc-d32e41e53e35
Attaching 1 probe...
sntpc /etc/services
sntpc /dev/urandom
sntpc /dev/urandom
...

Have fun and Happy Halloween!

相关实践学习
容器服务Serverless版ACK Serverless 快速入门:在线魔方应用部署和监控
通过本实验,您将了解到容器服务Serverless版ACK Serverless 的基本产品能力,即可以实现快速部署一个在线魔方应用,并借助阿里云容器服务成熟的产品生态,实现在线应用的企业级监控,提升应用稳定性。
容器应用与集群管理
欢迎来到《容器应用与集群管理》课程,本课程是“云原生容器Clouder认证“系列中的第二阶段。课程将向您介绍与容器集群相关的概念和技术,这些概念和技术可以帮助您了解阿里云容器服务ACK/ACK Serverless的使用。同时,本课程也会向您介绍可以采取的工具、方法和可操作步骤,以帮助您了解如何基于容器服务ACK Serverless构建和管理企业级应用。 学习完本课程后,您将能够: 掌握容器集群、容器编排的基本概念 掌握Kubernetes的基础概念及核心思想 掌握阿里云容器服务ACK/ACK Serverless概念及使用方法 基于容器服务ACK Serverless搭建和管理企业级网站应用
目录
相关文章
|
1月前
|
安全 持续交付 Docker
精通 Docker:简化开发、部署与安全保障
精通 Docker:简化开发、部署与安全保障
|
1月前
|
虚拟化 iOS开发 Docker
Windows10安装Docker Desktop(大妈看了都会)
Windows10安装Docker Desktop(大妈看了都会)
354 0
|
2月前
|
Java 数据安全/隐私保护 Docker
Docker Desktop 启动报错 Unexpected WSL error 问题解决
Docker Desktop 启动报错 Unexpected WSL error 问题解决
|
19天前
|
缓存 Linux 开发工具
win10下docker desktop:使用dockerfile基于CentOS:8创建可以使用vim的镜像
win10下docker desktop:使用dockerfile基于CentOS:8创建可以使用vim的镜像
62 0
|
1月前
|
存储 运维 持续交付
介绍 Docker 的基本概念和优势,以及在应用程序开发中的实际应用。
介绍 Docker 的基本概念和优势,以及在应用程序开发中的实际应用。
23 0
|
2月前
|
Kubernetes Cloud Native Go
Golang深入浅出之-Go语言中的云原生开发:Kubernetes与Docker
【5月更文挑战第5天】本文探讨了Go语言在云原生开发中的应用,特别是在Kubernetes和Docker中的使用。Docker利用Go语言的性能和跨平台能力编写Dockerfile和构建镜像。Kubernetes,主要由Go语言编写,提供了方便的客户端库与集群交互。文章列举了Dockerfile编写、Kubernetes资源定义和服务发现的常见问题及解决方案,并给出了Go语言构建Docker镜像和与Kubernetes交互的代码示例。通过掌握这些技巧,开发者能更高效地进行云原生应用开发。
89 1
|
2月前
|
存储 运维 数据中心
Docker 的基本概念和优势,以及在应用程序开发中的实际应用。
Docker是容器化技术,基于镜像(只读模板)创建可移植的容器,确保应用及其服务在隔离环境中运行。其优势包括快速部署(整个应用打包一次部署)、跨平台兼容、统一运行环境、资源隔离和简化依赖管理。Docker在开发和运维中都发挥作用,助力高效测试、部署和提升生产稳定性。
79 3
|
2月前
|
JavaScript 前端开发 Docker
全栈开发实战:结合Python、Vue和Docker进行部署
【4月更文挑战第10天】本文介绍了如何使用Python、Vue.js和Docker进行全栈开发和部署。Python搭配Flask创建后端API,Vue.js构建前端界面,Docker负责应用的容器化部署。通过编写Dockerfile,将Python应用构建成Docker镜像并运行,前端部分使用Vue CLI创建项目并与后端交互。最后,通过Nginx和另一个Dockerfile部署前端应用。这种组合提升了开发效率,保证了应用的可维护性和扩展性,适合不同规模的企业使用。
|
2月前
|
Java 持续交付 开发者
使用 Docker 容器化 Java Web 应用:提高开发和部署效率
【4月更文挑战第4天】Docker 作为轻量级容器技术,提升了 Java Web 应用的开发和部署效率。它提供类似生产环境的本地开发体验,减少环境配置时间,保证应用隔离性与稳定性。Docker 改善了部署流程,实现跨环境的无缝迁移,支持自动化构建、部署和扩展,并促进持续集成和持续部署,助力企业实现更高效、可靠的软件生命周期管理。
|
2月前
|
Docker 容器
Docker Desktop镜像迁移到其他磁盘
Docker Desktop镜像迁移到其他磁盘