事件与审计:K8s 事件流与审计日志
一句话定位:出事了怎么知道"谁在什么时候做了什么"?Event + Audit Log 双通道给你完整的时间线和责任链。
写在前面
有次生产事故让我印象极深:运维同学在半夜清理资源,不小心执行了 kubectl delete namespace production------还好集群有准入控制器拦截。事后我们想看看到底是谁执行的、从哪台机器、用的什么凭据,结果发现审计日志根本没开。
如果那次操作真的执行成功,而我们连"谁干的"都查不出来------这不叫事故,这叫灾难。
K8s 的可观测性有三根支柱:Metrics(指标) 告诉你"出事了",Logs(日志) 告诉你"为什么出事",Events + Audit Logs(事件+审计) 告诉你"什么时候、谁、做了什么"。这篇文章专门讲第三根容易被忽视的支柱。
读完你能带走:
- K8s Event 机制的原理和使用
- Audit Log 的配置策略和存储方案
- 事件导出 + 审计日志采集的完整管道
- 高危操作告警规则(删除 ns / 修改 rbac / 创建特权 pod)
- 审计日志分析查询方法
核心问题
出事了怎么知道"谁在什么时候做了什么"?
K8s 里有两套"记录簿"回答这个问题:
- Event:K8s 自身产生的状态变更通知(如 Pod 调度成功、Liveness Probe 失败)
- Audit Log:API Server 记录的所有 API 请求(谁、什么时候、调了什么 API、结果如何)
一、原理剖析
1.1 K8s Event 机制
K8s Event 生命周期
┌─────────────────────────────────────────────────────────────────┐
│ │
│ 1. 事件触发 │
│ Scheduler 将 Pod 调度到 Node-3 │
│ │ │
│ 2. 控制器/组件创建 Event 对象 │
│ scheduler 创建一个 Event: │
│ ┌─────────────────────────────────────────────┐ │
│ │ apiVersion: v1 │ │
│ │ kind: Event │ │
│ │ metadata: │ │
│ │ namespace: production │ │
│ │ name: nginx-7d4f8.17a3f5d8e │ │
│ │ involvedObject: │ │
│ │ kind: Pod │ │
│ │ name: nginx-7d4f8 │ │
│ │ namespace: production │ │
│ │ reason: Scheduled │ │
│ │ message: Successfully assigned pod to node-3 │ │
│ │ type: Normal │ │
│ │ source: │ │
│ │ component: default-scheduler │ │
│ │ firstTimestamp: 2024-07-18T10:00:00Z │ │
│ │ lastTimestamp: 2024-07-18T10:00:00Z │ │
│ │ count: 1 │ │
│ └─────────────────────────────────────────────┘ │
│ │ │
│ 3. 存储到 etcd │
│ Event 作为 API 资源存储,但不支持 CRUD(只能 Create/Get/List) │
│ │ │
│ 4. 默认保留 1 小时 │
│ etcd 中 Event 默认 TTL = 1h(由 kube-apiserver 控制) │
│ 过期后自动清理 │
│ │
└─────────────────────────────────────────────────────────────────┘
Event 的关键字段:
| 字段 | 含义 | 示例值 |
|---|---|---|
type |
事件类型 | Normal / Warning |
reason |
事件原因(机器可读) | Scheduled, Failed, Unhealthy |
message |
事件描述(人类可读) | Liveness probe failed: ... |
source.component |
产生事件的组件 | kubelet, default-scheduler |
involvedObject |
事件关联的资源 | Pod / Node / Deployment |
firstTimestamp |
首次发生时间 | 2024-07-18T10:00:00Z |
lastTimestamp |
最后发生时间 | 2024-07-18T10:05:00Z |
count |
发生次数 | 12 |
一个关键认知:Event 是瞬时的、有 TTL 的。Pod 被删除后,其 Event 也会很快过期消失。因此必须将 Event 导出到外部存储。
1.2 Audit Log 机制
K8s Audit Log 请求处理流程
kubectl delete pod nginx-7d4f8
│
▼
┌──────────────────────┐
│ API Server │
│ │
│ 1. 认证(AuthN) │ → 提取用户信息
│ ├─ 证书 │ → username: admin
│ ├─ Token │ → groups: system:masters
│ └─ OIDC │ → userAgent: kubectl/v1.28
│ │
│ 2. 鉴权(AuthZ) │ → 检查权限
│ └─ RBAC 检查 │ → "admin 有 delete pods 权限? YES"
│ │
│ 3. 准入控制 │ → Webhook 校验
│ └─ ValidatingWebhook │ → "允许删除?"
│ │
│ 4. 审计日志记录 │ ★ 在这里记录! │
│ ┌────────────────┐│
│ │ 审计事件: ││
│ │ level: Request ││
│ │ stage: Response││ ┌──────────────────────┐ │
│ │ verb: delete ││────▶│ 审计日志后端: │ │
│ │ user: admin ││ │ - 文件(/var/log/ │ │
│ │ sourceIP: ... ││ │ audit.log) │ │
│ │ objectRef: ││ │ - Webhook │ │
│ │ resource: pods││ │ - 日志文件 │ │
│ │ namespace: ││ └──────────────────────┘ │
│ │ production ││ │
│ │ responseStatus:││ │
│ │ code: 200 ││ │
│ └────────────────┘│ │
└──────────────────────┘
审计策略的四个级别(Profile Level):
审计级别对比:
┌────────────────┬──────────────────────┬──────────────────────┐
│ Level │ 记录内容 │ 适用场景 │
├────────────────┼──────────────────────┼──────────────────────┤
│ None │ 不记录 │ 关闭审计(不推荐) │
├────────────────┼──────────────────────┼──────────────────────┤
│ Metadata │ 请求元数据 │ 生产环境默认级别 │
│ │ (用户/时间/资源/状态码) │ 审计全量 API 调用 │
├────────────────┼──────────────────────┼──────────────────────┤
│ Request │ 元数据 + 请求体 │ 排查配置变更问题 │
│ │ │ 安全分析 │
├────────────────┼──────────────────────┼──────────────────────┤
│ RequestResponse│ 元数据 + 请求体 + 响应体 │ 完整取证 │
│ │ │ 注意:可能包含 Secret │
│ │ │ 数据量大 10-100x │
└────────────────┴──────────────────────┴──────────────────────┘
1.3 Event 和 Audit Log 的分工
Event Audit Log
────── ─────────
记录什么? K8s 内部状态变更通知 API Server 接收的所有请求
谁产生? 控制器/Scheduler/Kubelet API Server
记录粒度? 高(具体"发生了什么") 中("谁调了什么 API")
典型内容? "Liveness probe failed" "admin deleted pod X"
持久化? 默认 1 小时 TTL 根据配置(文件/Webhook/Log)
用途? 排查 Pod/Node 异常 安全审计 + 变更追踪
│ │
└──────────┬───────────────────┘
│
┌──────────▼──────────┐
│ 组合使用 │
│ Event = "发生了" │
│ Audit = "谁做的" │
│ 两者结合 = 完整故事 │
└─────────────────────┘
二、实战操作
2.1 部署 kubernetes-event-exporter
bash
kubectl create namespace monitoring
# 安装 event-exporter
helm repo add bitnami https://charts.bitnami.com/bitnami
helm repo update
event-exporter-values.yaml:
yaml
# ============================================
# kubernetes-event-exporter 配置
# ============================================
replicaCount: 1
image:
repository: bitnami/kubernetes-event-exporter
tag: 1.7.0
config:
logLevel: info
logFormat: json
metricsNamePrefix: ""
receivers:
# 接收器1: 文件输出
- name: "dump"
file:
path: "/data/events.json"
# 文件轮转
maxBytes: 104857600 # 100MB
maxBackups: 10
# 接收器2: Loki(日志系统)
- name: "loki"
loki:
url: "http://loki.loki.svc.cluster.local:3100/loki/api/v1/push"
tenantID: "events"
labels:
cluster: "prod-k8s-1"
batchSize: 1048576
batchWait: 5s
# 接收器3: Elasticsearch(可选)
# - name: "elasticsearch"
# elasticsearch:
# hosts:
# - "http://elasticsearch-master.logging:9200"
# index: "k8s-events"
# indexFormat: "k8s-events-{2006-01-02}"
# 接收器4: Webhook(关键事件推送)
- name: "webhook"
webhook:
endpoint: "http://alert-webhook.monitoring.svc/events"
headers:
X-Event-Source: "k8s-event-exporter"
layout:
text: |
[{{ .Type | ToUpper }}] {{ .Reason }}: {{ .Message }}
Object: {{ .InvolvedObject.Kind }}/{{ .InvolvedObject.Name }}
Namespace: {{ .InvolvedObject.Namespace }}
Time: {{ .LastTimestamp }}
# ── 路由规则(控制哪些 Event 发到哪些接收器) ──
route:
routes:
# 规则1: 所有 Warning 事件 → Loki + Webhook
- match:
- type: Warning
receiver: "dump"
drop:
- type: Normal
# 规则2: 高危 Warning → Webhook 立即告警
- match:
- type: Warning
reason: "(Failed|BackOff|Unhealthy|FailedScheduling|FailedMount|OOMKilling|NodeNotReady)"
regexp: true
receiver: "webhook"
# 规则3: 特定资源的事件 → 额外关注
- match:
- involvedObject:
kind: "(Node|PersistentVolume)"
regexp: true
receiver: "dump"
rbac:
create: true
serviceAccount:
create: true
name: event-exporter
# 持久化事件文件
persistence:
enabled: true
size: 20Gi
storageClass: ssd-sc
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
cpu: 500m
memory: 512Mi
bash
helm upgrade --install event-exporter bitnami/kubernetes-event-exporter \
--namespace monitoring \
--values event-exporter-values.yaml \
--wait
2.2 配置审计策略
审计策略通过 --audit-policy-file 参数传给 kube-apiserver。
audit-policy.yaml (生产级审计策略):
yaml
# ============================================
# K8s 审计策略 - 生产级配置
# 版本基线: K8s 1.30
# ============================================
apiVersion: audit.k8s.io/v1
kind: Policy
# 默认:不记录任何审计事件(显式规则才记录)
rules:
# ──────────────────────────────────────────
# Level: None(不记录)
# ──────────────────────────────────────────
# 排除系统组件的健康检查和状态轮询(噪音太大)
- level: None
users: ["system:kube-proxy", "system:kube-scheduler"]
verbs: ["watch"]
resources:
- group: ""
resources: ["endpoints", "services", "services/status"]
- level: None
users: ["system:apiserver", "system:kube-controller-manager"]
verbs: ["get", "list", "watch"]
resources:
- group: ""
resources: ["endpoints", "configmaps"]
- level: None
userGroups: ["system:nodes"]
verbs: ["get", "list", "watch"]
resources:
- group: ""
resources: ["nodes", "nodes/status", "pods", "pods/status"]
- level: None
nonResourceURLs:
- "/healthz*"
- "/readyz*"
- "/livez*"
- "/version"
- "/metrics"
# ──────────────────────────────────────────
# Level: Metadata(默认审计级别)
# ──────────────────────────────────────────
# 大部分请求只记录元数据(用户、时间、操作、资源、状态码)
- level: Metadata
omitStages:
- RequestReceived # 不记录收到的原始请求时间,减少噪音
# ──────────────────────────────────────────
# Level: Request(关键操作记录请求体)
# ──────────────────────────────────────────
# 高危 Namespace 操作
- level: Request
verbs: ["create", "update", "patch", "delete"]
resources:
- group: ""
resources: ["namespaces"]
omitStages:
- RequestReceived
# 安全敏感操作
- level: Request
verbs: ["create", "update", "patch", "delete"]
resources:
- group: "rbac.authorization.k8s.io"
resources: ["clusterroles", "clusterrolebindings",
"roles", "rolebindings"]
omitStages:
- RequestReceived
# Secret/ConfigMap 操作
- level: Request
verbs: ["create", "update", "patch", "delete"]
resources:
- group: ""
resources: ["secrets", "configmaps"]
omitStages:
- RequestReceived
# NetworkPolicy 变更
- level: Request
verbs: ["create", "update", "patch", "delete"]
resources:
- group: "networking.k8s.io"
resources: ["networkpolicies"]
omitStages:
- RequestReceived
# PodSecurityPolicy / ValidatingWebhook 变更
- level: Request
verbs: ["create", "update", "patch", "delete"]
resources:
- group: "admissionregistration.k8s.io"
resources: ["validatingwebhookconfigurations",
"mutatingwebhookconfigurations"]
omitStages:
- RequestReceived
# Pod Exec / Attach / PortForward(安全审计重点)
- level: RequestResponse
verbs: ["create"]
resources:
- group: ""
resources: ["pods/exec", "pods/attach", "pods/portforward"]
omitStages:
- RequestReceived
# ──────────────────────────────────────────
# Level: RequestResponse(完整记录)
# ──────────────────────────────────────────
# ServiceAccount Token 创建
- level: RequestResponse
verbs: ["create"]
resources:
- group: ""
resources: ["serviceaccounts/token"]
omitStages:
- RequestReceived
# 特权 Pod 创建(完整审计)
- level: RequestResponse
verbs: ["create", "update"]
resources:
- group: ""
resources: ["pods"]
namespaces: ["kube-system", "production"]
omitStages:
- RequestReceived
2.3 Kube-apiserver 审计配置
在 kubeadm 部署的集群中,编辑 kube-apiserver 的 manifest:
yaml
# /etc/kubernetes/manifests/kube-apiserver.yaml
spec:
containers:
- name: kube-apiserver
command:
- kube-apiserver
# 审计策略文件
- --audit-policy-file=/etc/kubernetes/audit/audit-policy.yaml
# 审计日志文件(主)
- --audit-log-path=/var/log/kubernetes/audit.log
- --audit-log-maxage=30 # 保留 30 天
- --audit-log-maxbackup=10 # 最多 10 个备份文件
- --audit-log-maxsize=100 # 每个文件最大 100MB
- --audit-log-format=json # JSON 格式
# Webhook 后端(实时推送)
- --audit-webhook-config-file=/etc/kubernetes/audit/webhook-config.yaml
- --audit-webhook-mode=batch # batch 模式减少 API 调用
- --audit-webhook-batch-max-size=400
- --audit-webhook-batch-max-wait=30s
volumeMounts:
- name: audit-policy
mountPath: /etc/kubernetes/audit
readOnly: true
- name: audit-log
mountPath: /var/log/kubernetes
volumes:
- name: audit-policy
hostPath:
path: /etc/kubernetes/audit
type: DirectoryOrCreate
- name: audit-log
hostPath:
path: /var/log/kubernetes
type: DirectoryOrCreate
Webhook 配置(推送到 Loki 或 SIEM):
yaml
# /etc/kubernetes/audit/webhook-config.yaml
apiVersion: v1
kind: Config
clusters:
- name: audit-sink
cluster:
server: http://audit-sink.monitoring.svc:8080/audit
contexts:
- context:
cluster: audit-sink
user: ""
name: default-context
current-context: default-context
2.4 部署 Audit Sink(接收 Webhook 并导入 Loki)
yaml
# audit-sink-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: audit-sink
namespace: monitoring
spec:
replicas: 2
selector:
matchLabels:
app: audit-sink
template:
metadata:
labels:
app: audit-sink
spec:
containers:
- name: audit-sink
image: nginx:alpine
ports:
- containerPort: 8080
volumeMounts:
- name: audit-log
mountPath: /var/log/audit
# 生产环境使用专门的审计接收服务,
# 如 fluentd / vector / logstash 导入 Loki
volumes:
- name: audit-log
emptyDir: {}
---
apiVersion: v1
kind: Service
metadata:
name: audit-sink
namespace: monitoring
spec:
selector:
app: audit-sink
ports:
- port: 8080
targetPort: 8080
2.5 高危操作告警规则
yaml
# audit-alerts.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: audit-alert-rules
namespace: monitoring
labels:
role: alert-rules
data:
audit-alerts.yaml: |
groups:
- name: audit-security-alerts
rules:
# ── P0 告警 ──
- alert: NamespaceDeleted
expr: |
count(
count_over_time(
{app="audit-sink"}
| json
| verb="delete"
| objectRef_resource="namespaces"
[5m]
)
) > 0
for: 1m
labels:
severity: P0
annotations:
summary: "Namespace 被删除"
description: "检查审计日志确认操作人和原因"
- alert: ClusterRoleCreated
expr: |
count(
count_over_time(
{app="audit-sink"}
| json
| verb="create"
| objectRef_resource="clusterroles"
[5m]
)
) > 0
for: 1m
labels:
severity: P0
annotations:
summary: "新的 ClusterRole 被创建"
description: "检查是否是预期操作"
# ── P1 告警 ──
- alert: PrivilegedPodCreated
expr: |
count(
count_over_time(
{app="audit-sink"}
| json
| verb="create"
| objectRef_resource="pods"
| responseStatus_code="201"
[10m]
)
) > 0
for: 1m
labels:
severity: P1
annotations:
summary: "检测到特权 Pod 创建"
description: "验证该 Pod 的 securityContext 配置"
- alert: SecretAccessedByNonSystem
expr: |
count(
count_over_time(
{app="audit-sink"}
| json
| objectRef_resource="secrets"
| user!~"system:.*"
| verb=~"get|list|watch"
[10m]
)
) > 10
for: 5m
labels:
severity: P1
annotations:
summary: "非系统用户大量读取 Secret"
- alert: RBACBindingModified
expr: |
count(
count_over_time(
{app="audit-sink"}
| json
| objectRef_resource=~"clusterrolebindings|rolebindings"
| verb=~"create|update|delete"
[5m]
)
) > 0
for: 1m
labels:
severity: P1
annotations:
summary: "RBAC 绑定被修改"
- alert: PodExecDetected
expr: |
count(
count_over_time(
{app="audit-sink"}
| json
| objectRef_subresource="exec"
| verb="create"
[5m]
)
) > 0
for: 1m
labels:
severity: P1
annotations:
summary: "检测到 kubectl exec 操作"
description: "用户 {{ $labels.user }} 在 {{ $labels.objectRef_namespace }}/{{ $labels.objectRef_name }} 上执行了 exec"
# ── P2 告警 ──
- alert: AuditLogVolumeDropped
expr: |
rate({app="audit-sink"} [10m]) < 0.1
for: 30m
labels:
severity: P2
annotations:
summary: "审计日志接收量异常下降"
description: "审计采集管道可能中断"
三、踩坑与排查
3.1 坑一:审计日志把磁盘打满
现象 :Master 节点 / 分区使用率 100%,kube-apiserver 无法写入,集群不可控。
原因 :审计策略配置了 RequestResponse 级别但没有限制大小,大 Deploy 的 YAML 全写进审计日志。一个包含 500 行 YAML 的 kubectl apply 能产生 50KB+ 的审计日志。
排查:
bash
# 1. 检查审计日志文件大小
ls -lh /var/log/kubernetes/audit.log*
du -sh /var/log/kubernetes/
# 2. 分析日志增长速率
tail -f /var/log/kubernetes/audit.log | pv -l > /dev/null
# 3. 找到日志量最大的操作
cat /var/log/kubernetes/audit.log | jq -r '.objectRef.resource' | sort | uniq -c | sort -rn | head -10
解决方案:
bash
# 1. 立即清理过期日志文件(K8s 1.30 的自动轮转需要确认)
find /var/log/kubernetes/ -name "audit.log.*" -mtime +7 -delete
# 2. 缩小日志上限
# audit-log-maxsize: 50 # 从 100MB 降到 50MB
# audit-log-maxbackup: 5 # 从 10 降到 5
# 3. 审计策略中增加排除规则
# 排除 Deployment/StatefulSet 的更新(请求体太大)
- level: Metadata
verbs: ["update", "patch"]
resources:
- group: "apps"
resources: ["deployments", "statefulsets", "daemonsets"]
3.2 坑二:Event 丢失
现象 :Pod 创建失败后,kubectl describe pod 显示的 Event 只有最近几条,看不到最早的和关键的 Warning。
原因:
- Event 默认 TTL 只有 1 小时,过期被 etcd 清理
- 同一 Event 的压缩(
count累加),旧时间戳被覆盖
解决方案:
bash
# 1. 调整 Event TTL(大集群建议 4h+)
# kube-apiserver 参数:
# --event-ttl=4h
# 2. 确认 event-exporter 正常工作
kubectl logs -n monitoring deployment/event-exporter | tail -20
# 3. 检查 Loki 中的 Event 是否完整
# 查询最近 24 小时的 Warning Event
curl -G 'http://loki.loki:3100/loki/api/v1/query_range' \
--data-urlencode 'query={app="event-exporter", type="Warning"}' \
--data-urlencode 'start='$(date -d '24 hours ago' +%s)'000000000' \
--data-urlencode 'end='$(date +%s)'000000000' \
--data-urlencode 'limit=100' | jq
3.3 坑三:审计日志噪音太大,查不到关键事件
现象 :一天审计日志 200GB,99% 是 kubelet/node 的心跳和 watches。用 grep | jq 分析慢到无法接受。
原因:审计策略默认级别设得太高,或没有排除高频低价值操作。
排查和优化:
bash
# 1. 统计各类型操作的分布
cat audit.log | jq -r '.verb + " " + .objectRef.resource' | sort | uniq -c | sort -rn | head -20
# 典型的高噪音操作:
# 3000000 watch pods ← 系统的 Watch 连接,全无价值
# 1500000 get nodes/status ← kubelet 心跳
# 500000 list endpoints ← kube-proxy 定期同步
# 2. 优化审计策略,排除这些操作
优化后的审计策略规则:
yaml
# 在 Policy 最前面加入排除规则:
rules:
# 排除高频无价值操作
- level: None
users: ["system:kube-proxy", "system:kube-scheduler",
"system:apiserver"]
verbs: ["watch", "get", "list"]
resources:
- group: ""
resources: ["endpoints", "services", "services/status"]
- level: None
userGroups: ["system:nodes"]
verbs: ["watch", "get"]
resources:
- group: ""
resources: ["nodes/status", "pods/status"]
四、最佳实践
Event 管理清单
- 必做:部署 kubernetes-event-exporter,将 Event 导出到 Loki/ES
- 必做:Warning 级别 Event 实时告警(通过 Webhook/Loki Ruler)
- 推荐 :Event TTL 调整为 4-8 小时(通过
--event-ttl) - 推荐 :根据
reason字段过滤关注的事件类型(BackOff,FailedMount等) - 可选:历史 Event 保留 30 天用于趋势分析
审计策略清单
- 默认级别用 Metadata ------ 记录所有 API 调用的元数据,成本低、覆盖全
- 关键操作升级到 Request ------ 删除 ns、修改 RBAC、访问 Secret → 记录请求体
- 高危操作用 RequestResponse ------ Pod Exec、ServiceAccount Token 创建 → 完整记录
- 系统组件操作降级到 None ------ kubelet 心跳、kube-proxy sync、scheduler watch → 不记录
- 审计日志持久化 ------ 文件 + Webhook 双写,文件定期归档到对象存储
- 敏感数据脱敏 ------
RequestResponse级别注意 Secret/Token 等敏感字段可能出现在审计日志中
审计日志分析工具链
bash
# 1. 查找某个用户的所有操作
cat audit.log | jq 'select(.user.username == "admin")'
# 2. 查找某个时间段的错误请求
cat audit.log | jq 'select(.responseStatus.code >= 400)'
# 3. 查找对特定资源的操作
cat audit.log | jq 'select(.objectRef.resource == "secrets" and .verb == "get")'
# 4. 按用户统计操作类型(Top 操作者)
cat audit.log | jq -r '.user.username' | sort | uniq -c | sort -rn | head -10
# 5. 查找失败的 kubectl exec 操作
cat audit.log | jq 'select(.objectRef.subresource == "exec" and .responseStatus.code >= 400)'
# 6. 查找非预期来源 IP 的请求
cat audit.log | jq 'select(.sourceIPs[] | startswith("10.0.") | not)'
# 7. 生产级: 用 Loki 的 LogQL 分析审计日志(需将审计日志导入 Loki)
# 查找最近 24 小时内所有 delete 操作
{app="audit-sink"} | json | verb="delete" | line_format "{{.user_username}} deleted {{.objectRef_resource}}/{{.objectRef_name}} in {{.objectRef_namespace}}"
五、小结
这三样东西的关系很好记:
Metrics: 身体检查报告(血压、心率、体温) → 出问题了
Logs: 病历(头疼、发烧、咳嗽) → 为什么出问题
Events + Audit: 监控录像(谁进来的、碰了什么) → 谁干的、什么时候干的
如果你只配了 Prometheus 和 Loki,还缺最后一块拼图。花半天时间把 Event 导出和审计日志配好,出事故时就不会手忙脚乱地问"到底是谁干的"。
一句话总结: Event 告诉你 Pod 发生了什么,Audit Log 告诉你谁对集群做了什么,两者结合就是完整的"时间线+责任链"。
思考题
- Audit Policy 的
omitStages可以排除RequestReceived阶段。排除和不排除有什么实际影响?什么时候应该保留? - 如果你的 K8s 集群是云厂商托管(如 EKS/ACK/GKE),审计日志的采集和自建集群有什么不同?云厂商通常提供什么方案?
- Event 和 Audit Log 之间有没有关联关系?比如,如何从一个 Audit 事件("张三创建了 Pod Y")找到对应的 K8s Event("Pod Y 调度成功")?