基础操作

一个正常运行的 Kubernetes 集群,除了利用访问控制对集群操作的许可进行限制之外,对于操作过程的跟踪审计也是比不可少的,围绕不同的实体,例如用户、节点以及各种工作负载进行观测是很有必要的。Kubernetes 的 API Server 提供了审计日志支持,利用审计日志的方式对系统内的操作进行记录,这里我们可以沿用推荐的 Elastic Search + Fluentd 对审计日志进行采集存储,最终使用 Kibana 或者其他支持 ES 查询的工具对关键资源或用户进行访问跟踪。

首先要启用 API Server 的审计功能。Kubernetes 提供了四个基础参数来定义审计功能:

audit-log-path 启用审计日志,并将日志内容写入指定文件,“-” 代表 stdout。

audit-log-maxage 日志文件的最大保存天数,根据文件名中的日期进行确定。

audit-log-maxbackup 最多保存日志文件的数量。

audit-log-maxsize 最大文件尺寸,超过尺寸会被翻转。单位是 MB,缺省为 100MB。

例如:

--audit-log-path=/var/log/kubernetes/kubernetes.audit \
--audit-log-maxage=7 \
--audit-log-maxbackup=4 \
--audit-log-maxsize=10

在 Kubernetes API Server 的启动参数中加入这些开关之后,重新启动服务。

这时我们就可以看到文件/var/log/kubernetes/kubernetes.audit已经生成。利用 tail 命令看看他的结构和内容,例如请求内容是这样的:

2017-08-30T16:28:35.485818099+08:00 AUDIT: id="ebc47b7b-c4fe-4a9a-861c-d9686903cec4" ip="127.0.0.1" method="GET" user="system:apiserver" groups="\"system:masters\"" as="" asgroups="" namespace="" uri="/apis/admissionregistration.k8s.io/v1alpha1/initializerconfigurations"

而响应内容格式如下:

2017-08-30T16:28:35.486131325+08:00 AUDIT: id="ebc47b7b-c4fe-4a9a-861c-d9686903cec4" response="404"

我们本文中暂时只对请求内容进行进一步解析,响应内容可以通过加入第二格式的方式进行采集。内容中的id字段,可以看作是会话 id,用于连接请求和响应。

根据上述文本内容,可以开始 Fluentd 文件的编写。请求和响应的内容都很规则,简单的正则表达式即可完成解析,例如我写的是这样的:

type tail
format /^(?\d.*?)\s+(?\w+).\s+id=\"(?.*?)\"\s+ip=\"(?.*?)\"\s+method=\"(?.*?)\"\s+user=\"(?.*?)\"\s+groups=(?.*?)\s+as=\"(?.*?)\"\s+asgroups=\"(?.*?)\"\s+namespace=\"(?.*?)\"\s+uri=\"(?.*?)\"$/
path /var/log/kubernetes/kubernetes.audit
pos_file /var/log/audit.pos
time_format %Y-%m-%dT%H:%M:%S.%N%z
tag audit.response

将这一部分内容加入到 Fluentd 配置之中去,启动抓取。日志入库之后,我们就可以对指定用户或者资源进行查询,获知他的黑历史了,例如我们要查找用户admin的操作历史:

{
"query": {
"match": {
"user": {
"query": "admin",
"type": "phrase"
}
}
}
}

在 Kibana 中执行查询,会看到类似内容(如果所在集群没有该用户,可以替换为 system:apiserver等内置用户进行测试):

利用解析出的各个字段,可以比较清楚的看到什么人,在什么时间,对什么对象进行了什么操作。


高级审计

在 Kubernetes 1.7 中新增了 Advanced audit 特性(Alpha),可以对审计内容、以及后续处理进行定义。

首先加入了审计策略的支持,可以使用行为,动作等条件进行限制,过滤掉无需考虑的审计内容。

存储后端在日志之外,还增加了 Web Hook 的支持,可以直接将审计内容发布到指定的 Web 服务中。