Kube-Armor 不替代 Kubernetes 原生审计日志,它专注运行时系统调用层策略执行与事件捕获,仅在 execve、openat、connect 等系统调用发生时触发,不记录 kubectl 等 API 请求。

Kube-Armor 不能替代 Kubernetes 原生审计(audit log),它做的是运行时系统调用层的细粒度策略执行与事件捕获,不是 API 层审计。 如果你期望看到 kubectl delete pod 这类请求记录,Kube-Armor 不会生成;它只在容器进程实际执行 execve、openat、connect 等系统调用时触发策略匹配和日志上报。
为什么 Kube-Armor 日志看起来“不像审计”
Kube-Armor 依赖 eBPF + LSM(如 bpf、apparmor、selinux)拦截内核态行为,它的事件本质是「进程做了什么」,而非「谁通过 API 请求了什么」。典型输出字段包括:hostPID、containerID、syscall、operation、resource、policyName —— 这些和 kube-apiserver 的 RequestResponse 级审计日志结构完全不同。
- 原生审计日志路径通常是
/var/log/kubernetes/audit.log或转发到 webhook/rsyslog,由--audit-policy-file控制 - Kube-Armor 日志默认走
stdout(DaemonSet 容器),也可配置输出到 Kafka / Loki / Fluentd,但内容维度固定为 LSM 层行为 - 两者无数据重叠:API 请求未到达 kubelet 时,Kube-Armor 还没机会介入;Pod 被删后,其进程已不存在,Kube-Armor 也不会再产生对应事件
启用 Kube-Armor 后必须确认的 3 个 LSM 基础条件
即使 YAML 部署成功,Kube-Armor 也可能静默失效。关键检查点不在 Kubernetes manifest,而在节点内核环境:
- 确认节点内核启用了
CONFIG_BPF_SYSCALL=y和CONFIG_LSM="...,bpf"(或含apparmor)—— 运行zcat /proc/config.gz | grep -E "(BPF_SYSCALL|LSM)",若无输出需重编译内核或换发行版(如 Ubuntu 22.04+、RHEL 9+ 默认满足) - 检查
/sys/kernel/security/lsm是否包含bpf:执行cat /sys/kernel/security/lsm,输出应类似capability,landlock,bpf,apparmor - Kube-Armor DaemonSet 容器必须有
privileged: true且挂载/sys/fs/bpf和/run/containerd(或/run/docker)—— 缺任一都会导致 eBPF 程序加载失败,kubectl logs -n kube-system ds/kube-armo里会出现"failed to load probe"或"permission denied"
Kube-Armor Policy 中 audit 模式的真实含义
action: AUDIT 并非开启“审计模式”,而是让策略仅记录不阻断。它和 action: BLOCK 共享同一套 LSM hook,区别仅在于是否调用 bpf_override_return()。常见误用:
- 以为
AUDIT能捕获所有系统调用 —— 实际只捕获该 policyrule中明确列出的syscall(如exec、file、network)子类,未声明的调用不会上报 - 在
process规则里写matchPaths: ["/bin/sh"]却收不到日志 —— 因为实际执行的是/bin/bash或 shell wrapper,需用matchDirectories或通配符"/bin/*" - 对 network 规则设
destinationPort: 3306但 Pod 用域名连接 MySQL —— DNS 解析发生在用户态,connect()系统调用的目标地址已是 IP,端口匹配仍有效;但若应用使用连接池复用 socket,则首次 connect 后的读写不会再次触发该规则
把 Kube-Armor 日志接入 SIEM 的实用建议
原生输出是 JSON 行格式,但字段深度嵌套(如 data.process.executable)、部分值含二进制(data.process.args 是 base64),直接喂给 Splunk/Elasticsearch 易解析失败:
- 用 Fluent Bit 的
json插件 +modify过滤器展平关键字段:data.process.executable→executable,data.resource→target,避免深层点号造成索引问题 - 对
data.process.args字段,加一条lua过滤器自动 base64-decode 并截断超长参数(防止字段爆炸),命令行参数过长时 Kube-Armor 本身就会截断,无需额外处理 - 不要依赖
data.hostPID关联宿主机进程 —— 容器重启后 PID 变化,且多容器共享 PID namespace 时该值无意义;优先用data.containerID关联 CRI 日志或data.podName/data.namespace
真正难处理的不是日志采集,而是理解哪些 LSM 事件对应真实风险:一次 openat(AT_FDCWD, "/etc/shadow", O_RDONLY) 比一百次 connect(10.96.0.10:53) 更值得告警。这需要你持续校准策略,而不是堆砌 audit 规则。


















