前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >kubernetes 审计日志功能

kubernetes 审计日志功能

作者头像
田飞雨
发布2019-12-19 19:10:37
2K0
发布2019-12-19 19:10:37
举报
文章被收录于专栏:田飞雨的专栏田飞雨的专栏

审计日志可以记录所有对 apiserver 接口的调用,让我们能够非常清晰的知道集群到底发生了什么事情,通过记录的日志可以查到所发生的事件、操作的用户和时间。kubernetes 在 v1.7 中支持了日志审计功能(Alpha),在 v1.8 中为 Beta 版本,v1.12 为 GA 版本。

kubernetes feature-gates 中的功能 Alpha 版本默认为 false,到 Beta 版本时默认为 true,所以 v1.8 会默认启用审计日志的功能。

一、审计日志的策略

1、日志记录阶段

kube-apiserver 是负责接收及相应用户请求的一个组件,每一个请求都会有几个阶段,每个阶段都有对应的日志,当前支持的阶段有:

  • RequestReceived - apiserver 在接收到请求后且在将该请求下发之前会生成对应的审计日志。
  • ResponseStarted - 在响应 header 发送后并在响应 body 发送前生成日志。这个阶段仅为长时间运行的请求生成(例如 watch)。
  • ResponseComplete - 当响应 body 发送完并且不再发送数据。
  • Panic - 当有 panic 发生时生成。

也就是说对 apiserver 的每一个请求理论上会有三个阶段的审计日志生成。

2、日志记录级别

当前支持的日志记录级别有:

  • None - 不记录日志。
  • Metadata - 只记录 Request 的一些 metadata (例如 user, timestamp, resource, verb 等),但不记录 Request 或 Response 的body。
  • Request - 记录 Request 的 metadata 和 body。
  • RequestResponse - 最全记录方式,会记录所有的 metadata、Request 和 Response 的 body。
3、日志记录策略

在记录日志的时候尽量只记录所需要的信息,不需要的日志尽可能不记录,避免造成系统资源的浪费。

  • 一个请求不要重复记录,每个请求有三个阶段,只记录其中需要的阶段
  • 不要记录所有的资源,不要记录一个资源的所有子资源
  • 系统的请求不需要记录,kubelet、kube-proxy、kube-scheduler、kube-controller-manager 等对 kube-apiserver 的请求不需要记录
  • 对一些认证信息(secerts、configmaps、token 等)的 body 不记录

k8s 审计日志的一个示例:

代码语言:javascript
复制
{
  "kind": "EventList",
  "apiVersion": "audit.k8s.io/v1beta1",
  "Items": [
    {
      "Level": "Request",
      "AuditID": "793e7ae2-5ca7-4ad3-a632-19708d2f8265",
      "Stage": "RequestReceived",
      "RequestURI": "/api/v1/namespaces/default/pods/test-pre-sf-de7cc-0",
      "Verb": "get",
      "User": {
        "Username": "system:unsecured",
        "UID": "",
        "Groups": [
          "system:masters",
          "system:authenticated"
        ],
        "Extra": null
      },
      "ImpersonatedUser": null,
      "SourceIPs": [
        "192.168.1.11"
      ],
      "UserAgent": "kube-scheduler/v1.12.2 (linux/amd64) kubernetes/73f3294/scheduler",
      "ObjectRef": {
        "Resource": "pods",
        "Namespace": "default",
        "Name": "test-pre-sf-de7cc-0",
        "UID": "",
        "APIGroup": "",
        "APIVersion": "v1",
        "ResourceVersion": "",
        "Subresource": ""
      },
      "ResponseStatus": null,
      "RequestObject": null,
      "ResponseObject": null,
      "RequestReceivedTimestamp": "2019-01-11T06:51:43.528703Z",
      "StageTimestamp": "2019-01-11T06:51:43.528703Z",
      "Annotations": null
    }
    ]
}

二、启用审计日志

当前的审计日志支持两种收集方式:保存为日志文件和调用自定义的 webhook,在 v1.13 中还支持动态的 webhook。

1、将审计日志以 json 格式保存到本地文件

apiserver 配置文件的 KUBE_API_ARGS 中需要添加如下参数:

代码语言:javascript
复制
--audit-policy-file=/etc/kubernetes/audit-policy.yaml --audit-log-path=/var/log/kube-audit --audit-log-format=json

日志保存到本地后再通过 fluentd 等其他组件进行收集。 还有其他几个选项可以指定保留审计日志文件的最大天数、文件的最大数量、文件的大小等。

2、将审计日志打到后端指定的 webhook
代码语言:javascript
复制
--audit-policy-file=/etc/kubernetes/audit-policy.yaml --audit-webhook-config-file=/etc/kubernetes/audit-webhook-kubeconfig

webhook 配置文件实际上是一个 kubeconfig,apiserver 会将审计日志发送 到指定的 webhook 后,webhook 接收到日志后可以再分发到 kafka 或其他组件进行收集。

audit-webhook-kubeconfig 示例:

代码语言:javascript
复制
apiVersion: v1
clusters:
- cluster:
    server: http://127.0.0.1:8081/audit/webhook
  name: metric
contexts:
- context:
    cluster: metric
    user: ""
  name: default-context
current-context: default-context
kind: Config
preferences: {}
users: []

前面提到过,apiserver 的每一个请求会记录三个阶段的审计日志,但是在实际中并不是需要所有的审计日志,官方也说明了启用审计日志会增加 apiserver 对内存的使用量。

Note: The audit logging feature increases the memory consumption of the API server because some context required for auditing is stored for each request. Additionally, memory consumption depends on the audit logging configuration.

audit-policy.yaml 配置示例:

代码语言:javascript
复制
apiVersion: audit.k8s.io/v1
kind: Policy
# ResponseStarted 阶段不记录
omitStages:
  - "ResponseStarted"
rules:
  # 记录用户对 pod 和 statefulset 的操作
  - level: RequestResponse
    resources:
    - group: ""
      resources: ["pods","pods/status"]
    - group: "apps"
      resources: ["statefulsets","statefulsets/scale"]
  # kube-controller-manager、kube-scheduler 等已经认证过身份的请求不需要记录
  - level: None
    userGroups: ["system:authenticated"]
    nonResourceURLs:
    - "/api*"
    - "/version"
  # 对 config、secret、token 等认证信息不记录请求体和返回体
  - level: Metadata
    resources:
    - group: "" # core API group
      resources: ["secrets", "configmaps"]

官方提供两个参考示例:

3、subresource 说明

kubernetes 每个资源对象都有 subresource,通过调用 master 的 api 可以获取 kubernetes 中所有的 resource 以及对应的 subresource,比如 pod 有 logs、exec 等 subresource。

代码语言:javascript
复制
获取所有 resource( 1.10 之后使用):
$ curl  127.0.0.1:8080/openapi/v2

参考:https://kubernetes.io/docs/concepts/overview/kubernetes-api/

三、webhook 的一个简单示例

代码语言:javascript
复制
package main

import (
	"encoding/json"
	"io/ioutil"
	"log"
	"net/http"

	"github.com/emicklei/go-restful"
	"github.com/gosoon/glog"
	"k8s.io/apiserver/pkg/apis/audit"
)

func main() {
	// NewContainer creates a new Container using a new ServeMux and default router (CurlyRouter)
	container := restful.NewContainer()
	ws := new(restful.WebService)
	ws.Path("/audit").
		Consumes(restful.MIME_JSON).
		Produces(restful.MIME_JSON)
	ws.Route(ws.POST("/webhook").To(AuditWebhook))

	//WebService ws2被添加到container2中
	container.Add(ws)
	server := &http.Server{
		Addr:    ":8081",
		Handler: container,
	}
	//go consumer()
	log.Fatal(server.ListenAndServe())
}

func AuditWebhook(req *restful.Request, resp *restful.Response) {
	body, err := ioutil.ReadAll(req.Request.Body)
	if err != nil {
		glog.Errorf("read body err is: %v", err)
	}
	var eventList audit.EventList
	err = json.Unmarshal(body, &eventList)
	if err != nil {
		glog.Errorf("unmarshal failed with:%v,body is :\n", err, string(body))
		return
	}
	for _, event := range eventList.Items {
		jsonBytes, err := json.Marshal(event)
		if err != nil {
			glog.Infof("marshal failed with:%v,event is \n %+v", err, event)
		}
		// 消费日志
		asyncProducer(string(jsonBytes))
	}
	resp.AddHeader("Content-Type", "application/json")
	resp.WriteEntity("success")
}

完整代码请参考:https://github.com/gosoon/k8s-audit-webhook

四、总结

本文主要介绍了 kubernetes 的日志审计功能,kubernetes 最近也被爆出多个安全漏洞,安全问题是每个团队不可忽视的,kubernetes 虽然被多数公司用作私有云,但日志审计也是不可或缺的。


参考: https://kubernetes.io/docs/concepts/extend-kubernetes/api-extension/custom-resources/ ttps://kubernetes.io/docs/tasks/debug-application-cluster/audit/ 阿里云 Kubernetes 审计日志方案

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019-01-30,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、审计日志的策略
    • 1、日志记录阶段
      • 2、日志记录级别
        • 3、日志记录策略
        • 二、启用审计日志
          • 1、将审计日志以 json 格式保存到本地文件
            • 2、将审计日志打到后端指定的 webhook
              • 3、subresource 说明
              • 三、webhook 的一个简单示例
              • 四、总结
              相关产品与服务
              容器服务
              腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
              领券
              问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档