容器内 syscall 捕获必须用 sysdig -pc,它启用容器上下文感知,自动做 pid/ns 映射、路径重写和 cgroup 标注;-pc 缺失时看到的全是宿主机视角信息。

容器内 syscall 捕获必须用 sysdig -pc,不是 sysdig -p
默认 sysdig 在容器里跑,看到的是宿主机视角的 syscall,PID、文件路径、网络地址全是宿主机命名空间里的——你查不到容器内进程的真实 /proc/123/root 下的文件,也看不到它实际绑定的 0.0.0.0:8080(而可能是 10.42.1.5:8080)。关键在 -pc:它启用容器上下文感知,自动做 PID/ns 映射、路径重写、cgroup 标注。
-
-pc会把evt.arg.filename从/tmp/foo翻译成容器内真实路径(如/app/config.yaml),前提是容器挂载没用:ro或bind mount覆盖/proc - 不用
-pc时,fd.name对 socket 可能显示172.17.0.3:5432,用了之后才变成容器内进程看到的postgres:5432 - 如果容器用
--pid=host或--network=host,-pc仍生效,但部分字段(如container.id)可能为空——这不是 bug,是 cgroup v1/v2 检测逻辑限制
sysdig-probe 加载失败常见于内核模块签名和 CONFIG_MODULE_SIG
很多发行版(RHEL 8+/centos Stream 9、ubuntu 22.04+)默认开启内核模块强制签名,sysdig-probe 的 sysdig-probe.ko 若未签名或密钥不匹配,insmod 直接报 Required key not available。这不是 sysdig 版本问题,是内核策略。
- 检查是否触发签名限制:
dmesg | grep -i "signature",出现module verification failed就是它 - 临时绕过(仅调试):
sudo mokutil --disable-validation+ 重启,或启动时加nosignature内核参数(需 GRUB 配置) - 生产环境应重编译 probe:
sudo /usr/share/sysdig/scripts/build_probe.sh,它会调用当前内核头和dkms,生成已签名模块(前提是你有签名密钥)
chisel 分析容器流量时,netstat 和 echo_fds 输出字段含义不同
netstat chisel 列的是连接元数据(含容器名、端口、状态),echo_fds 则聚焦 fd 层级的 syscall 上下文(比如哪个线程 open() 了哪个 socket、后续是否 connect() 成功)。两者输出字段名一样,但来源和精度不同——别拿 netstat 的 container.name 当 echo_fds 的 container.name 用。
-
netstat -pc中container.name来自 cgroup path 解析,稳定;echo_fds -pc的container.name是 syscall 触发时实时查的,若进程刚 fork 出来还没进 cgroup,可能为空 - 分析 http 404 错误时,
echo_fds能看到writesyscall 的 buffer 内容(需-A),但netstat只能看到连接建立成功与否 - 对 gRPC 流式调用,
netstat显示一条 ESTABLISHED 连接,echo_fds却可能列出几十次sendto,因为每个 message 都是一次 syscall
docker + sysdig 容器化部署时,/dev/sysdig 设备权限容易被 SElinux 拦截
即使加了 --device /dev/sysdig,容器里运行 sysdig -pc -c topfiles_bytes 还是卡住或报 Operation not permitted,大概率是 SELinux 的 sysdig_device_t 类型没放开。AppArmor 同理,但更少见。
- 快速验证:
ausearch -m avc -ts recent | grep sysdig,如果有avc: denied { read } for dev="sysdig",就是它 - 临时放行:
sudo setsebool -P container_sysdig_device 1(RHEL/CentOS);Ubuntu 上则需sudo aa-logprof交互添加/dev/sysdig访问规则 - 注意:
docker run --privileged能绕过,但等于开了所有设备访问,不推荐——只要明确给/dev/sysdig+ 正确 SELinux 上下文即可
事情说清了就结束。syscall 捕获的“容器内”不是靠猜路径实现的,是靠 -pc 实时做 Namespace 映射;probe 加载失败八成是签名拦的,不是 sysdig 自己坏了;chisel 字段看着一样,背后数据源差得远;SELinux 不是摆设,它真会默默挡掉 /dev/sysdig。