一、前言------sysdig 工具简介
1.1 什么是 sysdig
sysdig 是开源的 Linux 系统可见性与取证工具 ,通过内核探针捕获 系统调用(syscall)及 OS 事件 ,支持 实时观察 、强大过滤 、离线分析 ,并可用 Chisel(Lua 脚本) 做聚合统计。
一句话定位:
sysdig 是系统活动的 「抓包器 + 分析器」 ------ 像 Wireshark 抓网络包一样,把 syscall 流抓进
.scap,随时回放、过滤、统计。
1.2 与 strace / perf / Falco 的对比
| 工具 | 定位 | 输出 | 典型场景 |
|---|---|---|---|
| strace | 跟踪单个进程 syscall | 终端文本 | 开发调试、快速看某程序行为 |
| sysdig | 捕获整机/容器事件流 | 实时流 / .scap 文件 |
取证、容器排查、离线分析 |
| perf | CPU/性能采样 | 热点、计数器 | 性能瓶颈 |
| ltrace | 库函数调用 | libc API | API 层行为 |
| Falco | 安全规则引擎(基于同类事件) | 告警 | 运行时威胁检测 |
关系:
内核 syscall 事件
├─ strace → attach 单进程,即时打印
├─ sysdig → 全机捕获 + 过滤 + 存盘 + Chisel 分析
└─ Falco → 对同类事件跑安全规则("谁读了 /etc/shadow")
1.3 核心能力
| 能力 | 说明 |
|---|---|
| 实时流 | sysdig proc.name=nginx 像 tail -f 看事件 |
| 捕获文件 | sysdig -w trace.scap 离线回放 |
| 过滤语言 | proc.name、evt.type、fd.name、container.id 等 |
| Chisel | 内置 Lua 脚本:topprocs_cpu、netstat、spy_users |
| 容器原生 | 无需改容器即可按 container.name 过滤 |
| eBPF 模式 | --modern-bpf 免传统内核模块(视版本) |
二、使用场景------何时使用 sysdig
1、问题已过去,需要「事后复盘」
典型现象: 凌晨告警,早上进程已重启,日志不全。
# 若之前有捕获
sysdig -r incident.scap "proc.name=myapp and evt.type=open"
sysdig 价值: .scap 保留 完整事件流 + 上下文,比 strace 临时跟踪更适合取证。
2、容器 / K8s 环境排查
典型现象: 某 Pod 偷偷访问敏感文件、异常出站连接。
sysdig container.name=payment-svc and evt.type=connect
sysdig -c netstat container.name=payment-svc
3、整机谁在读某个文件 / 谁占 CPU
sysdig -c topfiles_bytes
sysdig -c topprocs_cpu
sysdig "fd.name contains /etc/shadow"
4、对比 strace:单进程 vs 全系统
| 需求 | 工具 |
|---|---|
只关心 ./myapp 启动过程 |
strace ./myapp 更简单 |
谁(任意进程)在动 /etc/passwd |
sysdig |
| 抓一段窗口留证据 | sysdig -w |
| 统计 top 进程/文件/连接 | sysdig -c chisel |
5、C/C++ 开发调试
# 跟踪自己的程序
sudo sysdig proc.name=my_server and evt.type=open
# 只看文件与网络
sudo sysdig proc.name=my_server and (evt.type=open or evt.type=connect)
# 捕获后慢慢分析
sudo sysdig -w my_server.scap -z proc.name=my_server
./my_server # 另一终端跑业务
# Ctrl+C 停止捕获
sudo sysdig -r my_server.scap
6、不适合 sysdig 的场景
| 场景 | 更合适的工具 |
|---|---|
| 单进程快速跟踪 | strace |
| 库函数层(printf/malloc) | ltrace |
| 源码级断点 | gdb |
| CPU 火焰图 | perf |
| 内存越界 | ASan |
| 长期 7×24 安全运营 | Falco / SIEM |
三、核心原理------工作原理深度解析
3.1 架构:内核捕获 → 用户态丰富 → 过滤/Chisel
┌─────────────┐ ┌──────────────┐ ┌─────────────┐
│ Linux 内核 │────►│ sysdig 探针 │────►│ 用户态引擎 │
│ syscall/事件 │ │ (kmod/eBPF) │ │ 解析+上下文 │
└─────────────┘ └──────────────┘ └──────┬──────┘
│
┌────────────────────────────┼────────────────┐
▼ ▼ ▼
实时打印 写入 .scap Chisel 聚合
sysdig filter sysdig -r sysdig -c
与 strace 差异:
| strace | sysdig | |
|---|---|---|
| 附着方式 | ptrace 单进程 | 内核级捕获(可见多进程) |
| 开销模型 | 被跟踪进程变慢 | 全机事件流,需过滤 |
| 持久化 | 需自己重定向 | 原生 .scap |
| 容器 | 需进容器 exec | container.* 字段直接过滤 |
3.2 探针:内核模块 vs eBPF
| 模式 | 说明 |
|---|---|
| 传统 | 加载 sysdig 内核模块(需匹配内核头) |
| --modern-bpf | 使用 eBPF,免编译 kmod(新发行版推荐) |
sudo sysdig --modern-bpf -V
3.3 事件默认输出格式
%evt.num %evt.time %evt.cpu %proc.name (%thread.tid) %evt.dir %evt.type %evt.info
示例:
12345 12:34:56.789101234 2 sysdig_demo (12340) > open /tmp/sysdig_demo_test.txt
| 字段 | 含义 |
|---|---|
evt.num |
事件序号 |
evt.time |
时间戳 |
evt.cpu |
CPU 编号 |
proc.name |
进程名 |
evt.dir |
> 进入 syscall,< 返回 |
evt.type |
事件类型(open、read、connect...) |
evt.info |
参数/返回值等详情 |
3.4 过滤表达式
过滤器写在命令末尾,支持 and / or / not:
sysdig proc.name=nginx and evt.type=write
sysdig fd.type=ipv4 and evt.type=connect
sysdig proc.pid=1234
sysdig container.id=abc123
常用字段:
| 字段 | 含义 |
|---|---|
proc.name |
进程名 |
proc.pid |
PID |
proc.cmdline |
完整命令行 |
evt.type |
事件类型 |
evt.dir |
方向 > / < |
fd.name |
文件路径 / socket |
fd.type |
file、ipv4、pipe... |
container.name |
容器名 |
k8s.pod.name |
K8s Pod(需元数据) |
3.5 Chisel(Lua 脚本)
Chisel 对事件流做 聚合、排序、格式化,类似「可编程报表」:
sysdig -cl # 列出所有 chisel
sysdig -i topprocs_cpu # 查看说明
sysdig -c topprocs_cpu # 运行
3.6 与 Falco 的关系
-
sysdig:捕获 + 分析(开发/运维/取证)
-
Falco :基于同类内核事件的 安全规则引擎(「若某进程打开 /etc/shadow 则告警」)
二者同源技术栈(CNCF),可理解为 sysdig 负责看清楚,Falco 负责判定可疑。
四、命令参数------常用选项详解
4.1 基本用法
sysdig [选项] [过滤器]
csysdig # 交互式 TUI(更易用)
4.2 常用选项
| 选项 | 说明 |
|---|---|
| -r file | 从 .scap 回放 |
| -w file | 写入捕获文件 |
| -z | 与 -w 联用,压缩 scap |
| -s len | 打印字符串最大长度(默认 256) |
| -n num | 只处理前 num 个事件 |
| -A | 打印事件数据缓冲(如 read/write 内容) |
| -p fmt | 自定义输出格式 |
| -c chisel | 运行 Chisel |
| -cl | 列出 Chisel |
| -i chisel | Chisel 详情 |
| -l | 列出可用 -p 字段 |
| -d filter | 将过滤器设为 display filter(仅显示) |
| -t | 不带日期,仅时间 |
| -a | 绝对时间戳 |
| -S | 简单输出(时间+内容) |
| --modern-bpf | 使用 eBPF 探针 |
| -V | 版本与驱动信息 |
4.3 捕获与回放
# 捕获 60 秒全机事件
sudo timeout 60 sysdig -w full.scap -z
# 只捕获某进程
sudo sysdig -w app.scap -z proc.name=myapp
# 回放并过滤
sudo sysdig -r app.scap evt.type=open
sudo sysdig -r app.scap -c topfiles_bytes
4.4 自定义输出格式
sysdig -p "%proc.name %evt.type %fd.name" proc.name=nginx
sysdig -p "%evt.time %proc.name %evt.dir %evt.type %evt.args" evt.type=open
4.5 帮助选项中文对照
-r, --readfile=FILE 从捕获文件读取事件
-w, --writefile=FILE 将事件写入捕获文件
-z, --compress 压缩捕获文件
-s, --snaplen=LEN 事件打印缓冲上限
-n, --numevents=NUM 处理事件数量上限
-A, --printevtdata 打印 read/write 等数据缓冲
-p, --print=FORMAT 自定义输出格式
-c, --chisel=CHISEL 运行指定 chisel
-cl, --list-chisels 列出 chisel
-i, --chisel-info=CHISEL 显示 chisel 帮助
-l, --list 列出可用字段
-d, --displayflt=FILTER 设置 display filter
-t, --timetype=TYPE 时间格式
-S, --simpleoutputs 简化输出
--modern-bpf 使用 eBPF 驱动
-V, --version 版本信息
-h, --help 帮助
五、使用实战------实际案例分析
示例程序 sysdig_demo
/*
* sysdig_demo.c - 演示 sysdig 可捕获的系统调用与事件
*
* 编译:
* gcc -g -O0 sysdig_demo.c -o sysdig_demo
*
* 跟踪(需 root):
* sudo sysdig proc.name=sysdig_demo
* sudo sysdig -w demo.scap proc.name=sysdig_demo &
* ./sysdig_demo
* sudo killall sysdig
* sudo sysdig -r demo.scap
*/
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <errno.h>
#define DEMO_FILE "/tmp/sysdig_demo_test.txt"
static void demo_file_io(void)
{
int fd;
char buf[128];
ssize_t n;
printf("[1] open / read / write / close\n");
fd = open(DEMO_FILE, O_RDWR | O_CREAT | O_TRUNC, 0644);
if (fd < 0) {
perror("open");
return;
}
if (write(fd, "hello sysdig demo\n", 18) < 0)
perror("write");
if (lseek(fd, 0, SEEK_SET) < 0)
perror("lseek");
n = read(fd, buf, sizeof(buf) - 1);
if (n < 0) {
perror("read");
} else {
buf[n] = '\0';
printf(" read back: %s", buf);
}
if (close(fd) < 0)
perror("close");
}
static void demo_malloc_mmap(void)
{
char *p1, *p2;
printf("[2] malloc / free (可能触发 brk 或 mmap)\n");
p1 = malloc(64);
p2 = malloc(1024 * 1024);
if (!p1 || !p2) {
perror("malloc");
free(p1);
free(p2);
return;
}
strcpy(p1, "sysdig malloc demo");
memset(p2, 0x5a, 1024 * 1024);
printf(" p1 = %s\n", p1);
free(p1);
free(p2);
}
static void demo_fork(void)
{
pid_t pid;
int status;
printf("[3] fork / wait\n");
pid = fork();
if (pid < 0) {
perror("fork");
return;
}
if (pid == 0) {
int fd = open("/tmp/sysdig_demo_child.txt",
O_WRONLY | O_CREAT | O_TRUNC, 0644);
if (fd >= 0) {
write(fd, "from child\n", 11);
close(fd);
}
_exit(9);
}
if (waitpid(pid, &status, 0) < 0) {
perror("waitpid");
return;
}
if (WIFEXITED(status))
printf(" child exit = %d\n", WEXITSTATUS(status));
}
static void demo_stat(void)
{
printf("[4] access / stat\n");
if (access(DEMO_FILE, F_OK) == 0)
printf(" %s exists\n", DEMO_FILE);
else
printf(" %s missing: %s\n", DEMO_FILE, strerror(errno));
}
int main(void)
{
printf("=== sysdig demo start (pid=%d) ===\n", getpid());
demo_file_io();
demo_malloc_mmap();
demo_stat();
demo_fork();
printf("=== sysdig demo end ===\n");
return 0;
}
cd examples/sysdig_demo
make && make check
案例 1:实时过滤单进程
# 终端 1
sudo sysdig proc.name=sysdig_demo
# 终端 2
./sysdig_demo
典型输出:
1 10:00:01.123 0 sysdig_demo (4567) > open /tmp/sysdig_demo_test.txt
2 10:00:01.124 0 sysdig_demo (4567) < open fd=3
3 10:00:01.125 0 sysdig_demo (4567) > write fd=3 size=18
...
案例 2:捕获 + 离线回放(核心用法)
make sysdig-capture
# 或手动:
sudo sysdig -w demo.scap -z proc.name=sysdig_demo &
./sysdig_demo
sudo killall sysdig
sudo sysdig -r demo.scap
sudo sysdig -r demo.scap evt.type=open
价值: 可多次回放、换不同过滤器,无需复现问题。
案例 3:Chisel 统计文件访问
make sysdig-chisel
# 等价:
sudo sysdig -r demo.scap -c topfiles_bytes proc.name=sysdig_demo
典型输出:
Bytes Name
18 /tmp/sysdig_demo_test.txt
11 /tmp/sysdig_demo_child.txt
案例 4:查谁在读敏感文件(安全排查)
sudo sysdig "fd.name contains /etc/shadow"
sudo sysdig -c spy_users fd.name contains /etc/passwd
案例 5:网络连接监控
sudo sysdig fd.type=ipv4 and evt.type=connect
sudo sysdig -c netstat proc.name=my_server
sudo sysdig -c topconns
案例 6:容器内进程
# 列出容器相关字段
sysdig -l | grep container
sudo sysdig container.name=web and evt.type=open
sudo sysdig -c topprocs_cpu container.name=web
案例 7:与 strace 对照
| 操作 | strace | sysdig |
|---|---|---|
跟踪 ./app |
strace ./app |
sysdig proc.name=app(需另开终端启动 app) |
| 存盘 | strace -o log |
sysdig -w app.scap |
| 统计 | strace -c |
sysdig -c topprocs_time |
| 看 write 内容 | strace -s 200 -e write |
sysdig -A evt.type=write and proc.name=app |
案例 8:自定义输出 + 组合过滤
sudo sysdig -p "%evt.time %proc.name %evt.type %fd.name %evt.args" \
"proc.name=sysdig_demo and (evt.type=open or evt.type=read or evt.type=write)"
六、常见问题------疑难解答
| 问题 | 原因 | 解决 |
|---|---|---|
sysdig: command not found |
未安装 | 见下方安装 |
| 需要 root | 捕获 syscall 需特权 | sudo sysdig 或 CAP_SYS_ADMIN |
| 内核模块编译失败 | 无 kernel headers | apt install linux-headers-$(uname -r) |
| 事件太多看不清 | 未加过滤器 | proc.name=...、evt.type=... |
.scap 很大 |
捕获全机太久 | 缩短时间、加过滤、用 -z |
| 容器字段为空 | 无 container 运行时元数据 | 确认 Docker/k8s 环境、驱动版本 |
| 与 strace 选哪个 | 场景不同 | 单进程即时 → strace;取证/全机 → sysdig |
--modern-bpf 失败 |
内核/权限不支持 | 回退传统 kmod 或升级 sysdig |
6.1 安装
# Debian / Ubuntu(官方仓库或 sysdig 文档)
curl -s https://download.sysdig.com/stable/install-sysdig | sudo bash
sudo apt install sysdig
# 或
sudo apt install sysdig
# 验证
sudo sysdig -V
6.2 权限说明
# 通常需要 root
sudo sysdig -V
# 非 root 可尝试(视系统配置)
sysdig --modern-bpf ...
6.3 常用 Chisel 速查
| Chisel | 用途 |
|---|---|
topprocs_cpu |
CPU 占用最高进程 |
topprocs_mem |
内存占用最高进程 |
topfiles_bytes |
读写最多的文件 |
topconns |
网络连接最多 |
netstat |
类 netstat 视图 |
spy_users |
某用户的活动 |
spy_ip |
与某 IP 的通信 |
stderr |
标准错误输出 |
fdcount_by_proc |
各进程 fd 数量 |
七、总结------要点回顾
7.1 三句话
-
sysdig 在内核层捕获 syscall/OS 事件,比 strace 视野更广,支持容器与全机分析。
-
-w存.scap、-r回放 是取证核心;过滤器 + Chisel 让海量事件可分析。 -
C/C++ 调试:单进程快速看行为用 strace;要留证、查全机、容器里谁干了什么用 sysdig。
7.2 推荐工作流
怀疑某服务异常
→ sudo sysdig -w incident.scap -z container.name=svc &
→ 复现问题
→ sudo sysdig -r incident.scap "evt.type=open"
→ sudo sysdig -r incident.scap -c topfiles_bytes
7.3 最小命令清单
sudo sysdig -V # 检查安装
sudo sysdig proc.name=app # 实时过滤
sudo sysdig -w trace.scap -z proc.name=app # 捕获
sudo sysdig -r trace.scap # 回放
sudo sysdig -r trace.scap evt.type=connect # 回放+过滤
sudo sysdig -c topprocs_cpu # Chisel 统计
sudo sysdig -cl # 列出 chisel
csysdig # 交互 TUI
7.4 调试工具链位置
| 工具 | 回答的问题 |
|---|---|
| strace | 这个进程 正在 调哪些 syscall? |
| ltrace | 这个进程调了哪些 库函数? |
| sysdig | 整机/容器 发生了什么?能否 存盘回放? |
| perf | CPU 时间花在哪? |
| ASan | 内存合法吗? |
| Falco | 行为是否 违反安全规则? |
| gdb | 运行时断点与变量 |