基础操作
一个正常运行的 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: 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: 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 服务中。