Kubernetes的API Server是整个集群的咽喉要道,所有对资源的增删改查请求都要经过它。一旦集群出现安全事件——比如某个Pod被莫名删除、ServiceAccount被改绑到cluster-admin角色——第一个要问的问题往往是:这个操作是谁发起的、什么时候发生的、从哪个IP来的。这些答案全部藏在审计日志里。本文围绕Kubernetes审计日志的原理、配置和实际分析方法展开,帮你把这套机制真正用起来。

一、审计日志到底记录了什么
很多人以为审计日志就是kube-apiserver的运行日志,其实两者完全是两回事。运行日志记录的是API Server进程自身的状态信息,而审计日志记录的是每一次API请求的结构化信息,包括请求者身份、请求资源、操作动词、响应状态码、请求耗时等。数据以JSON或JSON Lines格式输出,非常适合程序化分析。
一条典型的审计日志包含以下关键字段:auditID是这条审计记录的唯一标识,stage表示记录的是请求接收阶段还是响应完成阶段,user字段里包含用户名、所属组以及认证方式,sourceIPs记录了请求来源IP链路,objectRef指出操作的目标资源,verb是create、delete、patch这类动作,responseStatus则给出了API Server的处理结果。下面是一条删除Deployment的日志示例:
{
"auditID": "8f2a1c3d-9b4e-4f7a-a1b2-3c4d5e6f7a8b",
"level": "RequestResponse",
"stage": "ResponseComplete",
"verb": "delete",
"user": {
"username": "kubernetes-admin",
"groups": ["system:masters", "system:authenticated"]
},
"sourceIPs": ["192.168.1.105"],
"objectRef": {
"resource": "deployments",
"namespace": "production",
"name": "payment-service"
},
"responseStatus": {"code": 200},
"requestReceivedTimestamp": "2024-03-12T08:30:15Z"
}
审计系统把每个请求的生命周期划分为四个阶段:Panic、RequestReceived、ResponseStarted和ResponseComplete。每个阶段可以分别设置记录级别,这给了运维人员非常细粒度的控制能力。
二、审计策略的四个级别怎么选
审计的核心是一份Policy文件,它决定了哪些请求记录、记录到什么程度。级别从低到高分为四种:None表示完全不记录;Metadata只记录请求元信息,不含请求体和响应体,这是最常用的级别,日志量小且足够回答大部分安全问题;Request在元信息基础上增加请求体;RequestResponse则把响应体也一并记录,日志量最大,一般只对敏感资源的写操作启用。
编写Policy时遵循两条原则:一是先匹配到的规则先生效,所以具体规则要放在通用规则前面;二是最后一条规则应该留一个兜底,通常是对所有请求记录Metadata。下面是一份实用的策略示例,对Secret的读取只记元信息(避免明文泄露),对角色绑定和集群角色绑定的写操作记录完整请求响应:
apiVersion: audit.k8s.io/v1
kind: Policy
rules:
# 完全忽略的健康检查和探针类请求
- level: None
users: ["system:kube-proxy"]
verbs: ["get", "watch", "list"]
resources:
- group: ""
resources: ["endpoints", "services"]
# Secret 读取只记录元信息,防止敏感数据落盘
- level: Metadata
resources:
- group: ""
resources: ["secrets"]
# 提权相关操作记录完整内容
- level: RequestResponse
resources:
- group: "rbac.authorization.k8s.io"
resources: ["roles", "rolebindings", "clusterroles", "clusterrolebindings"]
verbs: ["create", "update", "patch", "delete"]
# 兜底规则
- level: Metadata
这份策略的思路是分层控制:高频低价值的请求直接忽略,敏感资源记录元信息,涉及权限变更的操作全量记录。如果对所有请求都开RequestResponse,一个中等规模的集群每天可能产生几十GB日志,得不偿失。
三、部署审计后端并接入日志系统
策略写好后需要让API Server加载它。以kubeadm部署的集群为例,先把Policy文件放到控制平面节点上,比如/etc/kubernetes/audit-policy.yaml,然后修改/etc/kubernetes/manifests/kube-apiserver.yaml,在启动参数中加入审计相关配置:
# 挂载策略文件并指定参数 - --audit-policy-file=/etc/kubernetes/audit-policy.yaml - --audit-log-path=/var/log/k8s-audit/audit.log - --audit-log-maxage=30 - --audit-log-maxbackup=10 - --audit-log-maxsize=100 - --audit-log-format=json
同时要在manifest的volumeMounts和volumes部分补上对应的目录挂载。保存文件后kubelet会自动重建API Server Pod,用kubectl get pods -n kube-system确认新Pod正常运行,再看/var/log/k8s-audit/下是否开始产生日志文件。
单机落盘只适合小集群,生产环境更推荐接入集中式日志系统。两种常见做法:一是使用日志收集Agent(如Fluent Bit或Filebeat)tail审计日志文件,发送到Elasticsearch或Loki;二是通过--audit-webhook-config-file指定一个Webhook后端,API Server会主动把审计事件POST出去,这种方案延迟更低,也不依赖本地磁盘。日志进入集中平台后,建议按auditID作为文档ID去重,按requestReceivedTimestamp建立索引,方便后续按时间窗口检索。
四、实战:用审计日志做安全分析
日志收集齐了,接下来是怎么从海量数据里挖出异常行为。安全分析通常围绕几个高危场景展开,最典型的有以下几类。
第一类是权限提升。检索对clusterrolebindings的create操作,重点关注把用户或ServiceAccount绑定到cluster-admin的行为,正常业务很少需要这种操作,一旦出现基本可以判定为高危事件。用jq可以快速过滤:
cat audit.log | jq -r 'select(.objectRef.resource=="clusterrolebindings" and .verb=="create")
| {time: .requestReceivedTimestamp, user: .user.username, ref: .objectRef.name}'
第二类是匿名用户访问。审计日志中user.username为system:anonymous的记录值得警惕,特别是来自集群外部IP的请求,这通常意味着API Server端口暴露在公网且被扫描器盯上了,需要立即检查防火墙规则和认证配置。
第三类是exec进入生产Pod的操作。verb: create配合subresource: exec组合的日志代表有人在容器里执行命令,这是入侵后横向移动的常见手段,也经常被合法运维使用,因此要结合来源IP、操作时间(比如凌晨三点)和目标Pod的重要性综合判断。
第四类是Secret批量读取。短时间大量verb: get、resource: secrets的请求,可能是攻击者在窃取凭据,可以对这类行为配置告警阈值,例如同一用户一分钟内读取超过10个Secret就触发通知。把这些检测规则固化到日志平台的告警模块,或者写成定时跑的脚本,一套基础的审计分析体系就算搭起来了。
五、落地时的注意事项
审计日志本身也是敏感数据,它记录了谁能访问什么,攻击者拿到后等于获得了集群的情报图谱。日志存储要限制访问权限,最好加密落盘,并设置合理的保留周期。另外要定期演练:随机挑选一天,尝试用审计日志还原某次操作的全貌,如果发现关键信息缺失,说明Policy覆盖不全,需要迭代调整。
最后提醒一点,审计是事后的证据链,不是事前的防护墙。它应该和RBAC最小权限、准入控制器、NetworkPolicy等手段配合使用,形成纵深防御。日志的价值在于缩短从发现异常到定位根因的时间窗口,这部分时间的缩短,往往决定了安全事件的损失大小。
Kubernetes审计日志审计策略集群安全修改时间:2026-09-12 03:36:37