# Kubernetes 的审计日志和采集

## 基础操作

一个正常运行的 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。

例如：

~~~bash
--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 命令看看他的结构和内容，例如请求内容是这样的：

~~~bash
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="<self>" asgroups="<lookup>" namespace="<none>" uri="/apis/admissionregistration.k8s.io/v1alpha1/initializerconfigurations"
~~~

而响应内容格式如下：

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

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

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

~~~bash
<source>
  type tail
  format /^(?<time>\d.*?)\s+(?<action>\w+).\s+id=\"(?<id>.*?)\"\s+ip=\"(?<ip>.*?)\"\s+method=\"(?<method>.*?)\"\s+user=\"(?<user>.*?)\"\s+groups=(?<groups>.*?)\s+as=\"(?<as>.*?)\"\s+asgroups=\"(?<asgroups>.*?)\"\s+namespace=\"(?<namespace>.*?)\"\s+uri=\"(?<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
</source>
~~~

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

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

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

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

![screenshot](images/audit-screenshot.jpg)

## 高级审计

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

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

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