33.B站薪享宏福笔记——第十二章(3)审计功能

12 B站薪享宏福笔记——第十二章

                                    —— Kubernetes 中必备的工具组件

12.3 审计功能

           —— 安全保障手段之一

12.3.1 起因

  平台的企业级需求中,多多少少都会包含审计相关的功能存在,能够在事后确认操作人和错误的原因,以此在后续的工作中避免此类的事件存在。如果想要做到此类功能,可以进行如下操作:

  审计日志(Audit Logs):Kubernetes 提供了审计功能,可以记录对集群资源的操作历史。可以配置 Kubernetes 的审计日志功能,使其记录对 Deployment、Pod、Service 等资源的创建、更新、删除等操作。审计日志通常可以配置为输出到文件、发送到远程日志服务器或集成到安全信息和事件管理(SIEM)系统中

  Kubernetes 事件(Events):Kubernetes 中的事件系统记录了对集群中各种资源的操作,包括 Deployment、Pod、Service等。可以使用 kubectl get events 命令来查看事件历史记录,或通过 Kubernetes API 获取事件数据。还可以设置自定义的事件记录器,将事件数据输出到日志文件或其他存储介质中

  自定义脚本:可以编写自定义脚本或控制器来监控 Deployment 资源的变化,并将变化记录到日志文件或数据库中。例如,可以编写一个 Python、Go、Java 等脚本,使用 Kubernetes 客户端监听 Deployment 资源的变化并记录到文件中

  第三方审计解决方案:一些第三方审计解决方案,如 Aqua Security、Sysdig Secure 等,提供了针对 Kubernetes 集群的全面审计和安全监控功能,包括记录资源的修改历史

12.3.2 审计概念

  Kubernetes 审计日志提供了与安全相关的、按时间顺序排列的记录集,记录每个用户使用 Kubernetes API 的应用以及控制层面自身引发的活动

  审计日志记录最初产生于 Kube-APIServer 内部,每个请求在不同执行阶段都会生成审计事件,这些审计事件会根据特定策略被预处理并写入后端,在策略中确定要记录的内容和用来存储记录的后端,目前后端支持 日志文件 和 webhook 写入

12.3.3 审计阶段

阶段  描述
RequestReceived(请求确认) 此阶段对应审计处理器接收到请求后,并且在委托给其余处理器之前生成的事件(收到后,未发送前)
ResponseStarted(响应启动) 在响应信息的头部发送后,相应消息体发送前生成的事件,只有长时间运行的请求(例如 watch 监听)才会生成这个阶段(长时间请求,发送头部,未发报文体前)
ResponseComplete(响应完成) 当响应消息体完成并且没有更多数据需要传输的时候(完全解决)
Panic(异常) 当 panic 发生时生成(panic 是 go 语言内部捕获异常的函数,会捕获异常动作的日志)

 

 

 

 

 

 

12.3.4 审计日志级别

审计日志 描述
None 符合这条规则的日志将不会记录
Metadata(元数据) 记录请求的元数据(例如:请求的用户、时间戳、资源、动词(list、get)等),但是不记录或者响应的消息体本身
Request(请求) 记录事件的元数据和请求的消息体,但是不记录响应的消息体,这不适用于非资源类型的请求
RequestResponse(通信) 记录事件的元数据,请求和响应的消息体,这不适用于非资源类型的请求

 

 

 

 

 

 

12.3.5 实验

Kubernetes 在 v1.7 中支持了日志审计功能(Alpha),在 v1.8 中为 Beta 版本,v1.12 为 GA(稳定) 版本

(1)审计策略资源清单

[root@k8s-master01 12.3]# cat 1.policy.yaml 
apiVersion: audit.k8s.io/v1
kind: Policy
rules:
# 设置机密资源的审计日志级别为Metadata
- level: Metadata
  resources:
  - group: ""
    resources: ["secrets"]
# 设置节点的审计日志级别为RequestResponse
- level: RequestResponse
  userGroups: ["system:nodes"]
# 对于其他内容,不要记录任何内容
- level: None
1.接口组版本:audit.k8s.io 组 v1 版
2.类别:Policy
3.规则:级别:元数据、组、资源:组(不写组,即核心组 v1 版)、类别:secrets(意为 对 核心组 v1 版本的 secrets 做元数据级别的记录)
       级别:通信、 用户组:system:nodes(意为 对 system:nodes 组的用户 做 通信级别的记录)
       级别:不记录(除上面两个资源外,其他都不记录信息)

(2)添加审计策略文件

# 上面目录(1)中是为了介绍资源,下面为了实验演示,将系统节点的通信日志去掉,只查看元数据级别的日志
[root@k8s-master01 12.3]# mkdir /etc/kubernetes/audit-policy/
[root@k8s-master01 12.3]# cat /etc/kubernetes/audit-policy/policy.yaml
apiVersion: audit.k8s.io/v1
kind: Policy
rules:
# 设置机密资源的审计日志级别为Metadata
- level: Metadata
  resources:
  - group: ""
    resources: ["secrets"]
# 对于其他内容,不要记录任何内容
- level: None

(3)添加配置信息

# 通过对 kube-apiserver.yaml 中文件配置的修改,开启后端审计日志
[root@k8s-master01 12.3]# cd /etc/kubernetes/manifests/
[root@k8s-master01 manifests]# ls -ltr
total 16
-rw------- 1 root root 2436 May 28 02:24 etcd.yaml
-rw------- 1 root root 2901 May 28 02:24 kube-controller-manager.yaml
-rw------- 1 root root 1487 May 28 02:24 kube-scheduler.yaml
-rw------- 1 root root 3984 Aug  8 11:33 kube-apiserver.yaml
# 修改文件前先备份是一个运维必备的优良品德
[root@k8s-master01 manifests]# cp kube-apiserver.yaml kube-apiserver.yaml_bak
# 修改文件,下面文件棕色字体处更改,要确认更改的字段位置要求
# spec.containers.command 下添加 审计规则 yaml 策略文件、审计日志输出路径、审计单个文件大小 MB、保留的审计日志备份文件数量2
# spec.containers.volumeMounts 挂载 策略文件和日志文件
# spec.volumes 定义主机的策略文件、日志文件
[root@k8s
-master01 manifests]# cat kube-apiserver.yaml apiVersion: v1 kind: Pod metadata: annotations: kubeadm.kubernetes.io/kube-apiserver.advertise-address.endpoint: 192.168.66.11:6443 creationTimestamp: null labels: component: kube-apiserver tier: control-plane name: kube-apiserver namespace: kube-system spec: containers: - command: - kube-apiserver - --audit-policy-file=/etc/kubernetes/audit-policy/policy.yaml - --audit-log-path=/etc/kubernetes/audit-logs/audit.log - --audit-log-maxsize=7 - --audit-log-maxbackup=2 - --advertise-address=192.168.66.11 - --allow-privileged=true - --authorization-mode=Node,RBAC - --client-ca-file=/etc/kubernetes/pki/ca.crt - --enable-admission-plugins=NodeRestriction - --enable-bootstrap-token-auth=true - --etcd-cafile=/etc/kubernetes/pki/etcd/ca.crt - --etcd-certfile=/etc/kubernetes/pki/apiserver-etcd-client.crt - --etcd-keyfile=/etc/kubernetes/pki/apiserver-etcd-client.key - --etcd-servers=https://127.0.0.1:2379 - --kubelet-client-certificate=/etc/kubernetes/pki/apiserver-kubelet-client.crt - --kubelet-client-key=/etc/kubernetes/pki/apiserver-kubelet-client.key - --kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname - --proxy-client-cert-file=/etc/kubernetes/pki/front-proxy-client.crt - --proxy-client-key-file=/etc/kubernetes/pki/front-proxy-client.key - --requestheader-allowed-names=front-proxy-client - --requestheader-client-ca-file=/etc/kubernetes/pki/front-proxy-ca.crt - --requestheader-extra-headers-prefix=X-Remote-Extra- - --requestheader-group-headers=X-Remote-Group - --requestheader-username-headers=X-Remote-User - --secure-port=6443 - --service-account-issuer=https://kubernetes.default.svc.cluster.local - --service-account-key-file=/etc/kubernetes/pki/sa.pub - --service-account-signing-key-file=/etc/kubernetes/pki/sa.key - --service-cluster-ip-range=10.10.0.0/12 - --tls-cert-file=/etc/kubernetes/pki/apiserver.crt - --tls-private-key-file=/etc/kubernetes/pki/apiserver.key image: registry.aliyuncs.com/google_containers/kube-apiserver:v1.29.2 imagePullPolicy: IfNotPresent livenessProbe: failureThreshold: 8 httpGet: host: 192.168.66.11 path: /livez port: 6443 scheme: HTTPS initialDelaySeconds: 10 periodSeconds: 10 timeoutSeconds: 15 name: kube-apiserver readinessProbe: failureThreshold: 3 httpGet: host: 192.168.66.11 path: /readyz port: 6443 scheme: HTTPS periodSeconds: 1 timeoutSeconds: 15 resources: requests: cpu: 250m startupProbe: failureThreshold: 24 httpGet: host: 192.168.66.11 path: /livez port: 6443 scheme: HTTPS initialDelaySeconds: 10 periodSeconds: 10 timeoutSeconds: 15 volumeMounts: - mountPath: /etc/kubernetes/audit-policy/policy.yaml name: audit-policy readOnly: true - mountPath: /etc/kubernetes/audit-logs name: audit-logs readOnly: false - mountPath: /etc/ssl/certs name: ca-certs readOnly: true - mountPath: /etc/pki name: etc-pki readOnly: true - mountPath: /etc/kubernetes/pki name: k8s-certs readOnly: true hostNetwork: true priority: 2000001000 priorityClassName: system-node-critical securityContext: seccompProfile: type: RuntimeDefault volumes: - name: audit-policy hostPath: path: /etc/kubernetes/audit-policy/policy.yaml type: File - name: audit-logs hostPath: path: /etc/kubernetes/audit-logs type: DirectoryOrCreate - hostPath: path: /etc/ssl/certs type: DirectoryOrCreate name: ca-certs - hostPath: path: /etc/pki type: DirectoryOrCreate name: etc-pki - hostPath: path: /etc/kubernetes/pki type: DirectoryOrCreate name: k8s-certs status: {}

(4)查看日志信息

# 确认 kube-apiserver 已经重新启动生效( 由于 kube-apiserver 是静态 pod,所以稍微等待就可以了 )
#(为了保险起见也可以重启 kubelet 重载后重启 systemctl daemon-reload && systemctl restart kubelet )
[root@k8s
-master01 manifests]# kubectl get pod -A|grep kube-apiserver kube-system kube-apiserver-k8s-master01 1/1 Running 0 9m42s # 查看自定义路径下的日志文件 [root@k8s-master01 manifests]# cd /etc/kubernetes/audit-logs/ [root@k8s-master01 audit-logs]# ls -ltr total 192 -rw------- 1 root root 113201 Aug 8 11:47 audit.log [root@k8s-master01 audit-logs]# tail -1 audit.log {"kind":"Event","apiVersion":"audit.k8s.io/v1","level":"Metadata","auditID":"0d6278c3-d858-41a1-b59d-b6fb74cb70b5","stage":"ResponseStarted","requestURI":"/api/v1/namespaces/loki/secrets?labelSelector=\u0026timeoutSeconds=60\u0026watch=True","verb":"watch","user":{"username":"system:serviceaccount:loki:loki-grafana","uid":"0e105dab-801f-4268-b49b-bbda5a15bacd","groups":["system:serviceaccounts","system:serviceaccounts:loki","system:authenticated"],"extra":{"authentication.kubernetes.io/pod-name":["loki-grafana-d78bcb4d7-p5ftf"],"authentication.kubernetes.io/pod-uid":["09f94407-dbce-4eea-b530-5ddced60dd28"]}},"sourceIPs":["192.168.66.13"],"userAgent":"OpenAPI-Generator/23.6.0/python","objectRef":{"resource":"secrets","namespace":"loki","apiVersion":"v1"},"responseStatus":{"metadata":{},"code":200},"requestReceivedTimestamp":"2025-08-08T04:14:18.393420Z","stageTimestamp":"2025-08-08T04:14:18.394961Z","annotations":{"authorization.k8s.io/decision":"allow","authorization.k8s.io/reason":"RBAC: allowed by ClusterRoleBinding \"loki-grafana-clusterrolebinding\" of ClusterRole \"loki-grafana-clusterrole\" to ServiceAccount \"loki-grafana/loki\""}} # 使用 jq 命令转义 json 格式 ,没有 jq 需要安装 yum install jq
[root@k8s
-master01 audit-logs]# jq . audit.log { "kind": "Event", "apiVersion": "audit.k8s.io/v1", "level": "Metadata", "auditID": "0d6278c3-d858-41a1-b59d-b6fb74cb70b5", "stage": "ResponseStarted", "requestURI": "/api/v1/namespaces/loki/secrets?labelSelector=&timeoutSeconds=60&watch=True", "verb": "watch", "user": { "username": "system:serviceaccount:loki:loki-grafana", "uid": "0e105dab-801f-4268-b49b-bbda5a15bacd", "groups": [ "system:serviceaccounts", "system:serviceaccounts:loki", "system:authenticated" ], "extra": { "authentication.kubernetes.io/pod-name": [ "loki-grafana-d78bcb4d7-p5ftf" ], "authentication.kubernetes.io/pod-uid": [ "09f94407-dbce-4eea-b530-5ddced60dd28" ] } }, "sourceIPs": [ "192.168.66.13" ], "userAgent": "OpenAPI-Generator/23.6.0/python", "objectRef": { "resource": "secrets", "namespace": "loki", "apiVersion": "v1" }, "responseStatus": { "metadata": {}, "code": 200 }, "requestReceivedTimestamp": "2025-08-08T04:14:18.393420Z", "stageTimestamp": "2025-08-08T04:14:18.394961Z", "annotations": { "authorization.k8s.io/decision": "allow", "authorization.k8s.io/reason": "RBAC: allowed by ClusterRoleBinding \"loki-grafana-clusterrolebinding\" of ClusterRole \"loki-grafana-clusterrole\" to ServiceAccount \"loki-grafana/loki\"" } }

(5)注意

  rules 字段必须在审计策略文件中书写,无 rules规则 的策略将被视为非法配置

# 当然也可以使用最低限度的审计策略文件在 Metadata 级别记录所有请求
# 在 Metadata 级别为所有请求生成日志
apiVersion: audit.k8s.io/v1
kind: Policy
rules:
- level: Metadata

 

官网 审计Policy 配置请参考文章: https://kubernetes.io/zh-cn/docs/reference/config-api/apiserver-audit.v1/#audit-k8s-io-v1-Policy

———————————————————————————————————————————————————————————————————————————

                                                                                                                         无敌小马爱学习

posted on 2025-08-05 11:40  马俊南  阅读(62)  评论(0)    收藏  举报