yunwei37/Eunomia
GitHub: yunwei37/Eunomia
一个基于 eBPF 的轻量级云原生监控框架,专注于容器安全与系统可观测性,支持多维度追踪点与 Prometheus/Grafana 集成。
Stars: 69 | Forks: 12
# 欧诺弥亚
一个基于 eBPF 的轻量级云原生监控工具,用于容器安全和可观测性
[](https://github.com/yunwei37/Eunomia/actions)
[](https://codecov.io/gh/filipdutescu/modern-cpp-template)
[](https://github.com/yunwei37/Eunomia/releases)
#### 这个项目是为了 2022 年操作系统大赛而设计的,它仅适用于概念验证和教学内容,不适用于生产环境。关于更进一步的开源开发计划,请移步 [eunomia-bpf](https://github.com/eunomia-bpf/eunomia-bpf)
eunomia-bpf 将会关注两个方面:
- `eBPF 即服务`:https://github.com/eunomia-bpf/eunomia-bpf
- `一个工具链和包管理器`:https://github.com/eunomia-bpf/ebpm-bootstrap
我们在 [GitHub](https://github.com/yunwei37/Eunomia) 上有运行 CI 的源代码镜像。我们还在 [GitLab](https://gitlab.eduxiji.net/zhangdiandian/project788067-89436) 上有一个镜像,以便在中国和操作系统比赛中更快地访问。
- [什么是 Eunomia](#what-is-eunomia)
- [三个主要理念](#three-main-ideas)
- [描述](#describe)
- [跟踪点](#trace-point)
- [教程和文档](#tutorial-and-documents)
- [架构](#architecture)
- [快速开始](#quickstart)
- [前置条件](#prequest)
- [作为二进制文件运行](#run-as-binary)
- [Docker、Prometheus 和 Grafana](#docker-prometheus-and-grafana)
- [Prometheus 和 Grafana 结果](#prometheus-and-grafana-result)
- [安全规则](#security-rules)
- [在 Linux 上构建](#build-on-linux)
- [为什么选择 eBPF](#why-is-ebpf)
- [为什么选择 Eunomia](#why-eunomia)
- [文档和报告](#documents--report)
- [基准测试](#benchmark)
## 什么是 Eunomia
### 三个主要理念
1. 无需修改代码,无需繁琐的配置,仅需 BTF 和一个微小的二进制即可启动监控和获取 Eunomia 核心功能:
2. 让 ebpf 程序的分发和使用像网页和 web 服务一样自然:
3. 提供一个新手友好的 ebpf 云原生监控框架:
详细信息可参阅 **操作系统大赛决赛报告**:[doc/Readme.md](doc/Readme.md)
### 描述
`Eunomia` 是一个使用 C/C++ 开发的基于 eBPF的轻量级,高性能云原生监控工具框架,旨在帮助用户了解容器的各项行为、监控可疑的容器安全事件,力求提供覆盖容器全生命周期的轻量级开源监控解决方案。
它使用 `Linux` `eBPF` 技术在运行时跟踪您的系统和应用程序,并分析收集的事件以检测可疑的行为模式。目前,它包含性能分析、容器集群网络可视化分析*、容器安全感知告警、一键部署、持久化存储监控等功能,提供了多样化的 ebpf 追踪点,并可以轻松拓展。其核心导出器/命令行工具最小仅需要约 4MB 大小的二进制程序,即可在支持的 Linux 内核上启动。
* [X] 开箱即用:以单一二进制文件或镜像方式分发,一次编译,到处运行,一行代码即可启动,包含多种 ebpf 工具和多种监测点,支持多种输出格式(json, csv, etc) 并保存到文件;
* [X] 轻量级,高性能:编译成的二进制大小仅 `4MB`;
* [X] 通过 `ebpf` 自动收集容器和 k8s 相关元信息,并和多种指标相结合;
* [X] 可集成 `prometheus` 和 `Grafana`,作为监控可视化和预警平台;也可作为 `OpenTelemetry` 的 collector 使用;
* [X] 可自定义运行时安全预警规则, 并通过 prometheus 等实现监控告警;
* [X] 可以自动收集进程行为并通过 `seccomp`/`capability` 进行限制;
* [X] 提供远程的 http API 进行控制,实现 ebpf 跟踪器的热插拔、一键分发和热更新,也可自行定制插件进行数据分析;
* [X] 其核心框架高度可扩展,可以非常轻松地集成其他的 libbpf ebpf C 程序;
### 跟踪点
`Eunomia` 向下采集容器相关进程的系统和网络可观测数据,向上采集容器相关应用的性能数据。其支持的 ebpf 跟踪点:
- `process`: 进程执行与退出
- `files`: 文件读写
- `tcpconnect`: TCP 连接
- `syscall`: 系统调用
- `tcpconnlat`: TCP 连接延时
- `tcprtt` 跟踪 TCP RTT(round-trip time),并绘制直方图
- `profile`: 定时采集堆栈跟踪样本, 并进行 On-CPU 性能分析; 支持C/C++/Rust等,也支持对 lua 虚拟机进行采样分析;
- `funclatency` 输出显示函数延迟(调用时间)的直方图*
- `bindsnoop` 跟踪执行 socket bind 的内核函数
- `sigsnoop` 跟踪进程收到的信号;
- `opensnoop` 跟踪 open() 系统调用,并获取文件路径等信息
- `mountsnoop` 跟踪 mount() 和 umount 系统调用
- `memleak` 跟踪和匹配内存分配和释放请求*
- `oomkill`: 跟踪 Linux 内存不足 (OOM) 终止
- `syscount`: 追踪慢系统调用并进行统计
我们参考了 bcc/libbpf-tools 定制实现了我们自己的 ebpf 追踪器,所有的 ebpf 跟踪点都可以通过 pid、namespace、cgroups 等信息和 docker、Kubernetes 元信息相关联,完成端到端可观测数据的覆盖。每个追踪点都有相应的测试和文档,还有源代码解读,可供学习或进一步拓展开发使用。请参考我们的追踪器文档:[doc/tracker_docs.md](doc/tracker_docs.md)
### 教程和文档
`Eunomia` 的 `ebpf` 追踪器部分是从 `libbpf-tools` 中得到了部分灵感,但是目前关于 ebpf 的资料还相对零散且过时,这也导致了我们在前期的开发过程中走了不少的弯路。因此, 我们也提供了一系列教程,以及丰富的参考资料,旨在降低新手学习eBPF技术的门槛,试图通过大量的例程解释、丰富对 `eBPF、libbpf、bcc` 等内核技术和容器相关原理的认知,让后来者能更深入地参与到 ebpf 的技术开发中来。另外,`Eunomia` 也可以被单独编译为 C++ 二进制库进行分发,可以很方便地添加自定义 libbpf检查器,或者直接利用已有的功能来对 syscall 等指标进行监测,教程中也会提供一部分 `Eunomia` 扩展开发接口教程。
1. [eBPF介绍与 libbpf 基础教程](doc/tutorial.md)
2. [ebpf 跟踪器源码解析与使用教程](doc/tracker_docs.md)
更多详细的教程和文档,请参考我们的网站: https://yunwei37.github.io/Eunomia/
## 架构
关于详细的系统架构设计和模块划分,请参考 [系统设计报告](doc/Readme.md)
## 快速开始
### 前置条件
您的 Kconfig 应包含以下选项
- 编译选项
CONFIG_DEBUG_INFO_BTF=y
CONFIG_DEBUG_INFO=y
- 建议的内核版本为 `5.10` 或更高版本。如果您使用旧版本的内核,可能需要安装额外的 BTF 信息。
### 作为二进制文件运行
您可以使用我们预编译的二进制文件(参见此处的 [发布](https://github.com/yunwei37/Eunomia/releases))来启动 eunomia 服务器:
```
sudo ./eunomia server
```
现在服务器已准备好接受请求!关于 HTTP API,请参阅:[doc/API.md](doc/API.md)。热更新处于 alpha 状态,您可以查看 [doc/hot-update-new-start.md](doc/hot-update-new-start.md)。
这将启用我们的核心 ebpf 跟踪器,包括 `process`、`tcp` 和 `files`,它还将启动我们的安全引擎以检测潜在的安全问题。
或者,您可以简单地使用 eunomia 运行单个 ebpf 跟踪器,例如:
```
sudo ./eunomia run files
```
将以默认 3 秒的间隔跟踪系统中所有文件的读或写,并打印结果:
```
[2022-05-28 11:23:10.699] [info] start eunomia...
[2022-05-28 11:23:10.699] [info] start ebpf tracker...
[2022-05-28 11:23:10.699] [info] start prometheus server...
[2022-05-28 11:23:10.699] [info] press 'Ctrl C' key to exit...
[2022-06-02 11:18:20.173] [info] pid container_name reads writes read_bytes write_bytes type comm filename
[2022-06-02 11:18:20.173] [info] 142326 ubuntu 0 1 0 1 R postgres oom_score_adj
[2022-06-02 11:18:20.173] [info] 5824 ubuntu 1 0 16 0 R code state.vscdb
[2022-06-02 11:18:20.173] [info] 5453 ubuntu 1 0 16 0 R grafana-server grafana.db
[2022-06-02 11:18:20.173] [info] 142327 ubuntu 1 0 18 0 R git .gitignore
[2022-06-02 11:18:20.173] [info] 142327 ubuntu 1 0 18 0 R git .gitignore
[2022-06-02 11:18:20.173] [info] 142327 ubuntu 1 0 18 0 R git .gitignore
[2022-06-02 11:18:20.173] [info] 5824 ubuntu 1 1 8 12 R code state.vscdb-journal
....
```
您也可以使用 `--container-id` 来跟踪容器,或使用 `toml`/`json` 配置文件。您可以指定跟踪或采样的间隔、输出格式、日志级别等。
我们提供了四个默认的跟踪器:`process`、`tcp`、`syscall` 和 `files`。您也可以轻松地从 libbpf-tools 添加您自己的跟踪器。
更多详情,请参阅:[usage.md](doc/usage.md)
### Docker、Prometheus 和 Grafana
请参阅 [quickstart/deploy.md](doc/quickstart/deploy.md)
### Prometheus 和 Grafana 结果
- 对于详细的 Prometheus 监控指标文档,请参考:[prometheus_metrics.md](doc/prometheus_metrics.md)
- 关于如何集成 Prometheus 和 Grafane,请参考:[intergration.md](doc/intergration.md)
### 安全规则
使用 eunomia 检测安全相关事件,例如,启动 eunomia 服务器后,运行:
```
sudo bpftools/tcp/tcp
```
您将在 eunomia 输出中收到警报:
```
[2022-06-02 11:26:40.830] [info] Security Rule Detection:
[2022-06-02 11:26:40.831] [info] level: event
[2022-06-02 11:26:40.831] [info] name: Insert-BPF
[2022-06-02 11:26:40.832] [info] message: BPF program loaded: tcp
[2022-06-02 11:26:40.832] [info] pid: 143856
[2022-06-02 11:26:40.833] [info] container_id: 36fca8c5eec1
[2022-06-02 11:26:40.833] [info] container_name: Ubuntu
```
此消息意味着某些程序向内核插入了 bpf 程序,这可能导致容器逃逸([参考](https://security.tencent.com/index.php/blog/msg/206))。请注意,虽然 `eunomia` 也使用 ebpf,但它本身不会触发此警告。这也将导出到 Prometheus,在指标 `eunomia_seccurity_event_count` 中。
更多详情,请参阅 [rules_index](doc/rule_index.md)
### 在 Linux 上构建
您可能需要安装 `libcurl`、`libelf-dev`、`clang` 和 `gtest` 作为依赖项。在 `Debian/Ubuntu` 上,只需运行
```
make install-deps
```
我们使用 `C++20` 作为标准,因此您需要一个支持 C++20 的编译器,例如 `GCC` > 10.0
Makefile 构建:
```
git submodule update --init --recursive # check out deps
make install
```
关于如何构建的更多详情,您可以访问我们的 CI 配置:[.github/workflows/ubuntu.yml](.github/workflows/ubuntu.yml)
## 为什么选择 eBPF
eBPF是一项革命性的技术,可以在Linux内核中运行沙盒程序,而无需更改内核源代码或加载内核模块。通过使Linux内核可编程,基础架构软件可以利用现有的层,从而使它们更加智能和功能丰富,而无需继续为系统增加额外的复杂性层。
* 优点:低开销
eBPF 是一个非常轻量级的工具,用于监控使用 Linux 内核运行的任何东西。虽然 eBPF 程序位于内核中,但它不会更改任何源代码,这使其成为泄露监控数据和调试的绝佳伴侣。eBPF 擅长的是跨复杂系统实现无客户端监控。
* 优点:安全
解决内核观测行的一种方法是使用内核模块,它带来了大量的安全问题。而eBPF 程序不会改变内核,所以您可以保留代码级更改的访问管理规则。此外,eBPF 程序有一个验证阶段,该阶段通过大量程序约束防止资源被过度使用,保障了运行的ebpf程序不会在内核产生安全问题。
* 优点:精细监控、跟踪
eBPF 程序能提供比其他方式更精准、更细粒度的细节和内核上下文的监控和跟踪标准。并且eBPF监控、跟踪到的数据可以很容易地导出到用户空间,并由可观测平台进行可视化。
* 缺点:很新
eBPF 仅在较新版本的 Linux 内核上可用,这对于在版本更新方面稍有滞后的组织来说可能是令人望而却步的。如果您没有运行 Linux 内核,那么 eBPF 根本不适合您。
## 为什么选择 Eunomia
目前已经有许多开源的可观测性工具,相比较 Eunomia:
1. 代码无侵入收集多种指标:基于 `ebpf` 实现,不需要对代码进行埋点或改造即可获取到丰富的网络和内核性能数据,并且和容器/k8s元信息相关联;
2. 轻量级:不想安装一大堆 `BCC` 或者 `systemTap` 的环境?无法使用内核模块?因为网络不好镜像拉不下来?得益于 `Libbpf` + BPF `CO-RE`(一次编译,到处运行)的强大性能,仅需安装一个 agent 就可以收集这台主机所有相关的系统数据,约 4MB 即可在支持的内核上或容器中启动跟踪,避免繁琐的依赖项和配置项;也可以通过镜像打包 Prometheus & Grafana 等监控可视化工具, 一站式开箱即用。
3. 高性能:得益于 `ebpf` 的可编程,`Eunomia` 直接在内核中使用 eBPF 执行过滤、聚合、度量统计和直方图收集,避免向用户空间 agent 发送大量的低信号事件,大大减少了系统的开销;此外,`Eunomia` 使用了 C/C++ 高效的数据结构和多线程分析处理,以提供高效和快速的数据收集手段,在大多数情况下仅使用不到 2% 的 CPU。
4. 可用性:一般而言,可观测性工具需要比被观测系统至少可靠一个数量级。我们使用了大量的静态分析和动态分析工具,如 clang tidy、cppcheck、Addresssanitizer、Clang Static Analyzer 等,同时进行了大量的测试以保证系统的可用性以及稳定性。
5. 热插拔:Eunomia 完全开源,可通过配置文件或开放的 http API 进行插件拓展,可以在运行时随时启动和停止特定的跟踪器;
6. 热更新:可直接通过 HTTP API 分发和更新编译好的 libbpf ebpf 程序,在不停机的同时以极小的代价进行更新;
7. 可扩展:Eunomia 的核心框架高度模块化,可扩展,可以轻松接入其他的 libbpf ebpf C 程序,实现自定义跟踪器;也提供了大量关于使用 libbpf 进行 ebpf 开发的文档和教程,以供 ebpf 的初学者学习参考。
除了收集容器中的一般系统运行时内核指标,例如系统调用、网络连接、文件访问、进程执行等,我们在探索实现过程中还发现目前对于 `lua` 和 `nginx` 相关用户态 `profile` 工具和指标可观测性开源工具存在一定的空白,但又有相当大的潜在需求;因此我们还计划添加一系列基于 uprobe 的用户态 `nginx/lua` 追踪器,作为可选的扩展方案;请参考 https://github.com/yunwei37/nginx-lua-ebpf-toolkit 仓库。
如果您想要使用 Eunomia,请注意:
- Eunomia 并不是一个完整的可观测性系统,它主要关注于系统的 Metrics ,即数据的数值表现方向,也收集一部分操作系统和网络层面的日志信息。Metrics 提供的信息用于衡量关于系统整体行为和健康状态。Metrics 通常在 “发生了什么” 中扮演重要角色,有时候是 “为什么”。您可能需要将其与应用程序本身的 logs 和 Traces 信息相结合,以便于更好的了解应用程序的行为或故障原因。
- 受 ebpf 技术所限,运行 Eunomia 需要确保操作系统内核支持 ebpf,因此它可能并不能在较旧的内核上正常工作。
## 文档和报告
Eunomia的完整文档在 doc 目录中:
- [操作系统大赛决赛报告目录](doc/Readme.md)
- [开发文档](doc/develop_doc/Readme.md):doc/develop_doc 目录下的所有文档
- [跟踪器文档](doc/tracker_docs.md)
- [教程](doc/tutorial.md)
## 基准测试
使用 top 查看 eunomia 的内存和cpu占用情况

使用 openresty 和 APISIX 在本机上启动一个包含6个容器和负载均衡的网络服务,以及 Prometheus 和 Grafana ,使用 wrk 进行压力测试:
```
Linux ubuntu 5.13.0-44-generic #49~20.04.1-Ubuntu SMP x86_64 GNU/Linux
4 核,12 GB 内存:
```
这是未开启 eunomia server 的情况:

这是启动 eunomia server 后的情况,使用默认配置并启用 process/container、tcp、files、ipc 等探针,在同样环境下进行测试:

可以观测到启动 eunomia 之后对于服务仅有大约 3-4% 的性能损耗。
系统架构
在 Promtheus 上展示和容器信息关联的 tcp 连接延时
对于容器中进程的跟踪结果,记录开始和结束时间
grafana dashboard: tcp accept\bind\connect 容器相关数据 Grafana 统计面板
grafana dashboard: tcp files syscall 每分钟计数统计图
grafana dashboard: signal、capability、文件请求读写比较
标签:API集成, DNS解析, Docker, Docker镜像, eBPF即服务, Grafana, Hpfeeds, LangChain, Linux内核, Python脚本, Web截图, 可观测性, 子域名突变, 安全防御评估, 客户端加密, 客户端加密, 容器安全, 开源项目, 性能分析, 操作系统竞赛, 文件系统监控, 无代理, 监控工具, 系统调用, 自定义请求头, 请求拦截, 轻量级, 追踪