集群异常行为检测近年来成为安全与运维交叉领域的重点方向。随着容器编排系统规模扩大,单纯依赖 CPU、内存阈值或者简单规则匹配已经无法识别内部横向移动、凭证滥用、配置篡改等隐蔽风险。UEBA(User and Entity Behavior Analytics,用户实体行为分析)把用户、服务账号、节点、容器都视为实体,基于其历史活动建立行为轮廓,再对实时行为做偏离评估,从而发现传统手段漏掉的异常。

多源数据接入与行为基线构建
UEBA 的第一道关卡是数据。集群环境里行为数据分散在多个平面:Kubernetes 审计日志记录了谁对哪些资源做了何种操作;节点系统日志反映进程与网络连接;容器运行时日志体现应用层请求;网络策略组件能给出服务间流量。如果只取其中一类,就会丢失上下文。例如一个普通用户在白天通过 API 创建 Pod 并不异常,但如果该账号过去三个月从未操作过集群,且创建后立即挂载宿主目录,这就是典型偏离。
接入时要做字段归一化。不同组件的时间格式、实体标识不一样,需要统一成“实体 ID、动作类型、目标对象、源 IP、时间戳”的结构。实体 ID 要尽量稳定,比如用服务账号的命名空间加名称,而不是每次调度变化的 Pod UID。下面是一段用 Python 做简单归一化的示例,把审计日志和节点日志合并成统一事件:
import json
def normalize_audit(raw):
# raw 是 Kubernetes 审计日志的一行 JSON
obj = json.loads(raw)
return {
'entity': obj['user']['username'],
'action': obj['verb'],
'target': obj['objectRef']['resource'],
'src_ip': obj['sourceIPs'][0],
'ts': obj['requestReceivedTimestamp']
}
def normalize_node(raw):
# raw 是节点安全日志解析后的字典
return {
'entity': raw['proc_user'],
'action': 'exec',
'target': raw['proc_name'],
'src_ip': raw['host'],
'ts': raw['time']
}
events = []
events.append(normalize_audit(audit_line))
events.append(normalize_node(node_line))
基线构建常用滑动窗口统计。对每个实体,计算其在过去 30 天里各动作的发生频次、活跃时间段、常用源 IP 集合。这些统计量不是写死的规则,而是随业务演化的参考系。当新行为进来,系统计算当前窗口与基线的差异度。这里要注意,容器集群有发版和扩容导致的自然波动,基线必须支持周期重置,否则正常业务变更也会被误判为异常。
行为建模与偏离检测算法选择
建模方式大致分两类:独立实体模型和关系模型。独立模型把每个用户或节点当作孤立对象,用时间序列异常检测(如 EWMA、孤立森林)找突变。关系模型则把集群看作图,实体是点,调用、访问是边,用图嵌入或社区发现识别结构异常。实践中两者要结合:独立模型抓个体突增,关系模型抓非法横向路径。
下面示例用孤立森林对某个服务账号的每日 API 调用量做检测。特征包括调用总数、写操作比例、不同资源类型数。模型在训练期只喂入历史正常数据,推理时分数越高越异常:
from sklearn.ensemble import IsolationForest
import numpy as np
# 历史特征:每行是 [调用总数, 写比例, 资源类型数]
normal_data = np.array([
[120, 0.1, 5],
[130, 0.12, 6],
[110, 0.09, 4]
])
model = IsolationForest(contamination=0.05)
model.fit(normal_data)
# 实时特征
live = np.array([[800, 0.8, 20]])
score = model.decision_function(live)
print('异常分数(越负越异常):', score)
图模型方面,可以把服务账号 A 访问命名空间 B 的 Pod 作为边。正常情况下边是稀疏且稳定的,如果某天 A 突然连到十个新命名空间,且这些命名空间属于不同业务线,图算法会给出高中心度异常。UEBA 的难点在于特征权重的业务解释,安全人员需要知道为什么标红,而不能只看到一个分数。因此模型输出要带主要贡献特征,比如“写操作比例从 10% 升至 80%”。
检测运营与误报治理
再好的算法直接上线也会淹没在误报里。集群里每天有数以万计的事件,如果偏离就告警,值班人员会迅速疲劳。运营层要做分级:把实体分为高敏(如集群管理员账号、控制面节点)和低敏(普通只读账号),高敏实体用小阈值,低敏实体用组合条件。同时引入反馈闭环,人工标记误报后,系统自动调低对应特征权重或加入白名单。
另一个关键是时间关联。单一动作可能正常,但序列异常。例如账号先被添加至新组,隔一小时创建高权限 Pod,再过十分钟导出配置。这种多步行为要用会话切分,把同一实体在短时间内的动作聚成序列,再用序列模式匹配或 LSTM 识别。下面用伪代码展示会话聚合思路:
def sessionize(events, gap=3600):
# events 已按 ts 排序
sessions = []
cur = []
last_ts = None
for e in events:
if last_ts is None or e['ts'] - last_ts <= gap:
cur.append(e)
else:
sessions.append(cur)
cur = [e]
last_ts = e['ts']
if cur:
sessions.append(cur)
return sessions
UEBA 平台还应提供调查视图,把异常实体相关的审计、日志、网络流集中展示,帮助分析师几分钟内定性。只有检测、排序、调查、反馈形成闭环,集群异常行为检测才能从演示走向日常可用。团队在初期可先覆盖控制面账号与核心业务服务,逐步扩展实体范围,避免一次性铺开导致运营失控。