当前位置:   article > 正文

Kubernetes 审计日志采集与分析最佳实践

Kubernetes 审计日志采集与分析最佳实践

Kubernetes 审计日志概述

Kubernetes 在 1.7 版本中发布了审计(Audit)日志功能,审计(Audit)提供了安全相关的时序操作记录(包括时间、来源、操作结果、发起操作的用户、操作的资源以及请求/响应的详细信息等),通过审计日志,我们能够非常清晰的知道 K8S 集群到底发生了什么事情,包括但不限于:

  1. 当前/历史上集群发生了哪些变更事件。
  2. 这些变更操作者是谁,是系统组件还是用户,是哪个系统组件/用户。
  3. 重要变更事件的详细内容是什么,比如修改了 POD 中的哪个参数。
  4. 事件的结果是什么,成功还是失败。
  5. 操作用户来自哪里,集群内还是集群外。

审计日志格式

Kubernetes 审计日志是以 json 格式的方式进行输出的,如下所示:

  1. {
  2. "kind": "Event",
  3. "apiVersion": "audit.k8s.io/v1",
  4. "level": "Metadata",
  5. "auditID": "432064d5-bda6-4957-a9e8-369f364e5748",
  6. "stage": "ResponseComplete",
  7. "requestURI": "/api/v1/namespaces/tigera-operator/configmaps/operator-lock",
  8. "verb": "update",
  9. "user": {
  10. "username": "system:serviceaccount:tigera-operator:tigera-operator",
  11. "uid": "8ab017b1-c57d-4aa4-a52f-5acec0c1e72e",
  12. "groups": ["system:serviceaccounts", "system:serviceaccounts:tigera-operator", "system:authenticated"],
  13. "extra": {
  14. "authentication.kubernetes.io/pod-name": ["tigera-operator-d7957f5cc-hv5p8"],
  15. "authentication.kubernetes.io/pod-uid": ["2e859424-41ca-4f64-a1c6-b0ae3395e480"]
  16. }
  17. },
  18. "sourceIPs": ["10.0.16.202"],
  19. "userAgent": "operator/v0.0.0 (linux/amd64) kubernetes/$Format/leader-election",
  20. "objectRef": {
  21. "resource": "configmaps",
  22. "namespace": "tigera-operator",
  23. "name": "operator-lock",
  24. "uid": "5f5b044f-9d7e-4c89-b703-f85affe91a25",
  25. "apiVersion": "v1",
  26. "resourceVersion": "13338825"
  27. },
  28. "responseStatus": {
  29. "metadata": {},
  30. "code": 200
  31. },
  32. "requestReceivedTimestamp": "2024-05-09T01:51:24.165036Z",
  33. "stageTimestamp": "2024-05-09T01:51:24.167660Z",
  34. "annotations": {
  35. "authorization.k8s.io/decision": "allow",
  36. "authorization.k8s.io/reason": "RBAC: allowed by ClusterRoleBinding \"tigera-operator\" of ClusterRole \"tigera-operator\" to ServiceAccount \"tigera-operator/tigera-operator\""
  37. }
  38. }

审计日志阶段

审计日志根据日志策略可以选择在事件执行的某个阶段记录,目前支持的事件阶段有:

  • RequestReceived 接收到事件且在分配给对应 handler 前记录。
  • ResponseStarted 开始响应数据的 Header 但在响应数据 Body 发送前记录,这种一般应用在持续很长的操作事件,例如 watch 操作。
  • ResponseComplete 事件响应完毕后记录。
  • Panic 内部出现 panic 时记录。

审计日志等级

审计日志根据日志策略可以选择事件保存的等级,根据等级不同,APIServer 记录日志的详细程度也不同。目前支持的事件等级有:

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

审计日志策略

APIServer 支持对每类不同的资源设置不同的审计日志策略,包括日志记录阶段以及日志记录等级,目前官方以及很多云厂商都会提供日志策略,一般都遵循以下原则:

  • 在收到请求后不立即记录日志,当返回体 header 发送后才开始记录。
  • 对于大量冗余的 kube-proxy watch 请求,kubelet 和 system:nodes 对于 node 的 get 请求,kube 组件在 kube-system 下对于 endpoint 的操作,以及 apiserver 对于 namespaces 的 get 请求等不作审计。
  • 对于 /healthz,/version,/swagger* 等只读 url 不作审计。
  • 对于可能包含敏感信息或二进制文件的 secrets,configmaps,tokenreviews 接口的日志等级设为 metadata,该 level 只记录请求事件的用户、时间戳、请求资源和动作,而不包含请求体和返回体。
  • 对于一些如 authenticatioin、rbac、certificates、autoscaling、storage 等敏感接口,根据读写记录相应的请求体和返回体。

开启审计日志策略

以 K8S 1.24 为例,开启审计日志策略。

1、登陆主节点服务器

cd /etc/kubernetes

2、新增 audit-policy.yml

  1. # Copyright © 2022 sealos.
  2. #
  3. # Licensed under the Apache License, Version 2.0 (the "License");
  4. # you may not use this file except in compliance with the License.
  5. # You may obtain a copy of the License at
  6. #
  7. # http://www.apache.org/licenses/LICENSE-2.0
  8. #
  9. # Unless required by applicable law or agreed to in writing, software
  10. # distributed under the License is distributed on an "AS IS" BASIS,
  11. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. # See the License for the specific language governing permissions and
  13. # limitations under the License.
  14. apiVersion: audit.k8s.io/v1 # This is required.
  15. kind: Policy
  16. # Don't generate audit events for all requests in RequestReceived stage.
  17. omitStages:
  18. - "RequestReceived"
  19. rules:
  20. # The following requests were manually identified as high-volume and low-risk,
  21. # so drop them.
  22. - level: None
  23. users: [ "system:kube-proxy" ]
  24. verbs: [ "watch" ]
  25. resources:
  26. - group: "" # core
  27. resources: [ "endpoints", "services" ]
  28. - level: None
  29. users: [ "system:unsecured" ]
  30. namespaces: [ "kube-system" ]
  31. verbs: [ "get" ]
  32. resources:
  33. - group: "" # core
  34. resources: [ "configmaps" ]
  35. - level: None
  36. users: [ "kubelet" ] # legacy kubelet identity
  37. verbs: [ "get" ]
  38. resources:
  39. - group: "" # core
  40. resources: [ "nodes" ]
  41. - level: None
  42. userGroups: [ "system:nodes" ]
  43. verbs: [ "get" ]
  44. resources:
  45. - group: "" # core
  46. resources: [ "nodes" ]
  47. - level: None
  48. users:
  49. - system:kube-controller-manager
  50. - system:kube-scheduler
  51. - system:serviceaccount:kube-system:endpoint-controller
  52. verbs: [ "get", "update" ]
  53. namespaces: [ "kube-system" ]
  54. resources:
  55. - group: "" # core
  56. resources: [ "endpoints" ]
  57. - level: None
  58. users: [ "system:apiserver" ]
  59. verbs: [ "get" ]
  60. resources:
  61. - group: "" # core
  62. resources: [ "namespaces" ]
  63. # Don't log these read-only URLs.
  64. - level: None
  65. nonResourceURLs:
  66. - /healthz*
  67. - /version
  68. - /swagger*
  69. # Don't log events requests.
  70. - level: None
  71. resources:
  72. - group: "" # core
  73. resources: [ "events" ]
  74. # Secrets, ConfigMaps, and TokenReviews can contain sensitive & binary data,
  75. # so only log at the Metadata level.
  76. - level: Metadata
  77. resources:
  78. - group: "" # core
  79. resources: [ "secrets", "configmaps" ]
  80. - group: authentication.k8s.io
  81. resources: [ "tokenreviews" ]
  82. # Get repsonses can be large; skip them.
  83. - level: Request
  84. verbs: [ "get", "list", "watch" ]
  85. resources:
  86. - group: "" # core
  87. - group: "admissionregistration.k8s.io"
  88. - group: "apps"
  89. - group: "authentication.k8s.io"
  90. - group: "authorization.k8s.io"
  91. - group: "autoscaling"
  92. - group: "batch"
  93. - group: "certificates.k8s.io"
  94. - group: "extensions"
  95. - group: "networking.k8s.io"
  96. - group: "policy"
  97. - group: "rbac.authorization.k8s.io"
  98. - group: "settings.k8s.io"
  99. - group: "storage.k8s.io"
  100. # Default level for known APIs
  101. - level: RequestResponse
  102. resources:
  103. - group: "" # core
  104. - group: "admissionregistration.k8s.io"
  105. - group: "apps"
  106. - group: "authentication.k8s.io"
  107. - group: "authorization.k8s.io"
  108. - group: "autoscaling"
  109. - group: "batch"
  110. - group: "certificates.k8s.io"
  111. - group: "extensions"
  112. - group: "networking.k8s.io"
  113. - group: "policy"
  114. - group: "rbac.authorization.k8s.io"
  115. - group: "settings.k8s.io"
  116. - group: "storage.k8s.io"
  117. - group: "autoscaling.alibabacloud.com"
  118. # Default level for all other requests.
  119. - level: Metadata

对应的策略信息可以按照实际需求进行调整。

API Server 开启审计日志

进入目录 /etc/kubernetes/manifests,先备份 kube-apiserver.yaml 文件,并且备份的文件不能放在 /etc/kubernetes/manifests/ 下,调整文件内容:

1、在 spec.containers.command 下添加命令:

  1. - command:
  2. - kube-apiserver
  3. - --advertise-address=10.0.16.204
  4. - --allow-privileged=true
  5. - --audit-log-format=json
  6. - --audit-log-maxage=7
  7. - --audit-log-maxbackup=10
  8. - --audit-log-maxsize=100
  9. - --audit-log-path=/var/log/kubernetes/audit.log
  10. - --audit-policy-file=/etc/kubernetes/audit-policy.yml

2、在 spec.containers.volumeMounts 下添加:

  1. - mountPath: /etc/kubernetes
  2. name: audit
  3. - mountPath: /var/log/kubernetes
  4. name: audit-log

3、在 spec.volumes 下添加:

  1. - hostPath:
  2. path: /etc/kubernetes
  3. type: DirectoryOrCreate
  4. name: audit
  5. - hostPath:
  6. path: /var/log/kubernetes
  7. type: DirectoryOrCreate
  8. name: audit-log

4、生效

API Server 被改动后,会自动重启,耐心等待几分钟即可。

5、验证

执行以下命令,看看是否有 audit.log 文件产生,如果有则证明已经生效。

ls /var/log/kubernetes

观测云采集 K8S 审计日志

接入步骤:

  • 部署 DataKit 采集器
  • 采集 K8S 审计日志
  • 查看 K8S 审计日志报表

部署 DataKit 采集器

K8s 安装 - 观测云文档

采集 K8S 审计日志

K8S 审计日志存储在对应 master 节点的 /var/log/kubernetes 目录下,这里采用 annotation 的方式进行采集。

  • 创建 pod

k8s-audit-log.yaml

  1. apiVersion: v1
  2. kind: Pod
  3. metadata:
  4. name: kube-audit-log
  5. annotations:
  6. datakit/logs: |
  7. [
  8. {
  9. "disable": false,
  10. "type": "file",
  11. "path":"/var/log/kubernetes/audit.log",
  12. "source": "k8s-audit",
  13. "tags" : {
  14. "atype": "kube-audit-log"
  15. }
  16. }
  17. ]
  18. spec:
  19. containers:
  20. - name: kube-audit-log
  21. image: busybox
  22. # command: ["sleep", "1"]
  23. args:
  24. - /bin/sh
  25. - -c
  26. - >
  27. i=0;
  28. while true;
  29. do
  30. i=$((i+1));
  31. sleep 10;
  32. done
  33. volumeMounts:
  34. - mountPath: /var/log/kubernetes
  35. name: datakit-vol-opt
  36. volumes:
  37. - name: datakit-vol-opt
  38. hostPath:
  39. path: /var/log/kubernetes
  40. nodeSelector:
  41. kubernetes.io/hostname: k8s-master
  42. tolerations:
  43. - key: "node-role.kubernetes.io/master"
  44. operator: "Exists"
  45. effect: "NoSchedule"
  46. - key: "node-role.kubernetes.io/control-plane"
  47. operator: "Exists"
  48. effect: "NoSchedule"

需要注意当前 pod 只能运行在 master 节点上。

  • 执行
kubectl apply -f k8s-audit-log.yaml 
  • 查看

等几分钟后就可以在观测云上查看到对应的日志了。

由于是 json 格式,观测云支持通过 @+json字段名 的方式进行搜索,如 @verb:update⁠

查看 K8S 审计日志报表

审计日志采集上来后,通过观测云 pipeline 的能力,可以对审计日志关键字段进行提取,从而对审计日志进行进一步数据分析。

  • 新建 pipeline

1、选择对应的日志来源 k8s-audit

2、Pipeline 名称:kubelet-audit

3、定义解析规则

  1. abc = load_json(_)
  2. add_key(kind, abc["kind"])
  3. add_key(level, abc["level"])
  4. add_key(stage, abc["stage"])
  5. add_key(verb, abc["verb"])
  6. add_key(auditID, abc["auditID"])
  7. add_key(username, abc["user"]["username"])
  8. add_key(responseCode, abc["responseStatus"]["code"])
  9. if abc["responseStatus"]["code"]==200 {
  10. add_key(status, "OK")
  11. }else{
  12. add_key(status, "FAIL")
  13. }
  14. add_key(sourceIP_0,abc["sourceIPs"][0])
  15. add_key(namespace,abc["objectRef"]["namespace"])
  16. add_key(node,abc["objectRef"]["name"])

4、点击获取脚本测试

5、保存

  • 查看审计日志视图

选择仪表板模板 Kubernetes Audit 即可查看到对应的视图信息。

本文内容由网友自发贡献,转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号