kubernetes 审计与日志 详解

发布时间:2024年01月09日

开头语

写在前面:如有问题,以你为准,

目前24年应届生,各位大佬轻喷,部分资料与图片来自网络

内容较长,页面右上角目录方便跳转

基本

介绍

在Kubernetes集群中,API Server的审计日志记录了哪些用户、哪些服务请求操作集群资源,并且可以编写不同规则 控制忽略、存储的操作日志。

审计日志采用SON格式输出,每条日志都包含丰富的元数据,例如请求的URL、HTTP方法、客户端来源等,你可以使 用监控服务来分析API流量,以检测趋势或河能存在的安全隐患。

这些可能服务会访问API Server:

  1. 管理节点(controller--manager、.scheduler)
  2. 工作节点(kubelet、.kube-proxy)
  3. 集群服务(CoreDNS、Calico、HPA等)
  4. kubectl、.APl、Dashboard

事件 阶段

yaml 解析

https://kubernetes.io/zh-cn/docs/tasks/debug/debug-cluster/audit/

audit-policy

修改配置后是需要删除apiserver容器,等待自动pod自动进行创建

apiVersion: audit.k8s.io/v1 # 这是必填项。

kind: Policy

# 不要在 RequestReceived 阶段为任何请求生成审计事件。

omitStages:

? - "RequestReceived"

rules:

? # 在日志中用 RequestResponse 级别记录 Pod 变化。

? - level: RequestResponse

??? resources:

??? - group: ""

????? # 资源 "pods" 不匹配对任何 Pod 子资源的请求,

????? # 这与 RBAC 策略一致。

????? resources: ["pods"]

? # 在日志中按 Metadata 级别记录 "pods/log"、"pods/status" 请求

? - level: Metadata

??? resources:

??? - group: ""

????? resources: ["pods/log", "pods/status"]



? # 不要在日志中记录对名为 "controller-leader" 的 configmap 的请求。

? - level: None

??? resources:

??? - group: ""

????? resources: ["configmaps"]

????? resourceNames: ["controller-leader"]



? # 不要在日志中记录由 "system:kube-proxy" 发出的对端点或服务的监测请求。

? - level: None

??? users: ["system:kube-proxy"]

??? verbs: ["watch"]

??? resources:

??? - group: "" # core API 组

????? resources: ["endpoints", "services"]



? # 不要在日志中记录对某些非资源 URL 路径的已认证请求。

? - level: None

??? userGroups: ["system:authenticated"]

??? nonResourceURLs:

??? - "/api*" # 通配符匹配。

??? - "/version"



? # 在日志中记录 kube-system 中 configmap 变更的请求消息体。

? - level: Request

??? resources:

??? - group: "" # core API 组

????? resources: ["configmaps"]

??? # 这个规则仅适用于 "kube-system" 名字空间中的资源。

??? # 空字符串 "" 可用于选择非名字空间作用域的资源。

??? namespaces: ["kube-system"]



? # 在日志中用 Metadata 级别记录所有其他名字空间中的 configmap 和 secret 变更。

? - level: Metadata

??? resources:

??? - group: "" # core API 组

????? resources: ["secrets", "configmaps"]



? # 在日志中以 Request 级别记录所有其他 core 和 extensions 组中的资源操作。

? - level: Request

??? resources:

??? - group: "" # core API 组

??? - group: "extensions" # 不应包括在内的组版本。



? # 一个抓取所有的规则,将在日志中以 Metadata 级别记录所有其他请求。

? - level: Metadata

??? # 符合此规则的 watch 等长时间运行的请求将不会

??? # 在 RequestReceived 阶段生成审计事件。

??? omitStages:

????? - "RequestReceived"

示例

除了命名空间 pod 资源相关操作,其他都不记录

apiVersion: audit.k8s.io/v1

kind: Policy

rules:

- level: Metadata

? # namespaces: ["default"] # 执行命名空间

? verbs: ["create","delete"] # 指定相关操作

? resources: # 执行资源

? - group: ""

??? resources: ["pods"]

??? # resourceNames: ["controller-leader"] 指定资源名

- level: None

[root@master audit]# ps -ef | grep apiserver

root????? 831053? 831034? 0 10:27 ???????

root???? 2791437 2791419 71 21:09 ???????? 00:00:08 kube-apiserver --advertise-address=

[root@master audit]# kill -9 2791437

[root@master audit]# kubectl get pod -A

[root@master ~]# kubectl delete? pod web1666

pod "web1666" deleted

[root@master audit]# tail -f /var/log/audit/k8s_audit.log

{

? "kind": "Event",

? "apiVersion": "audit.k8s.io/v1",

? "level": "Metadata",

? "auditID": "c52213b1-0bd6-4790-80ae-7c5aeb159ab9",

? "stage": "ResponseComplete",

? "requestURI": "/api/v1/namespaces/default/pods/web1666",

? "verb": "delete",

? "user": {

??? "username": "system:node:node1",

??? "groups": [

????? "system:nodes",

????? "system:authenticated"

??? ]

? },

? "sourceIPs": [

??? "192.168.100.51"

? ],

? "userAgent": "kubelet/v1.28.1 (linux/amd64) kubernetes/8dc49c4",

? "objectRef": {

??? "resource": "pods",

??? "namespace": "default",

??? "name": "web1666",

??? "apiVersion": "v1"

? },

? "responseStatus": {

??? "metadata": {},

??? "code": 200

? },

? "requestReceivedTimestamp": "2023-11-21T02:11:53.435596Z",

? "stageTimestamp": "2023-11-21T02:11:53.444542Z",

? "annotations": {

??? "authorization.k8s.io/decision": "allow",

??? "authorization.k8s.io/reason": ""

? }

}

审计日志

开启

审计日志支持写入本地文件和Vebhook (发送到外部HTTP API) 两种方式。

启用审计日志功能:

vi /etc/kubernetes/manifests/kube-apiserver.yaml

---audit-policy-file=/etc/kubernetes/audit/audit-policy.yaml

--audit-log-path=/var/log/audit/k8s_audit.log

---audit-log-maxage=30

---audit-log-maxbackup=10

---audit-log-maxsize=100

注:使用hostpath数据卷将宿主机/etc/kubernetes/,audit目录挂载到容器中

mkdir /etc/kubernetes/audit

touch /var/log/audit/k8s_audit.log

?apiserver.yaml 需要修改内容

????? volumeMounts:

????? - mountPath: /etc/kubernetes/audit

????? name: audit

????? readOnly: true

??? - mountPath: /var/log/audit/k8s_audit.log

????? name: audit-log-file



? volumes:???????????

? - hostPath:

????? path: /etc/kubernetes/audit

????? type: DirectoryOrCreate

??? name: audit

? - hostPath:

????? path: /var/log/audit/k8s_audit.log

????? type: File

??? name: audit-log-file

解析

yum -y install jq

日志内容

[root@master kubernetes]# tail -1 /var/log/audit/k8s_audit.log? | jq

{

? "kind": "Event",

? "apiVersion": "audit.k8s.io/v1",

? "level": "Metadata",

? "auditID": "95279099-833a-4a79-b942-9cd5da761cc6",

? "stage": "ResponseComplete", # 在那个阶段处理

? "requestURI": "/healthz",

? "verb": "get",

? "user": {

??? "username": "system:serviceaccount:calico-system:calico-kube-controllers",

??? "uid": "47d3e62f-edcf-4938-b988-ae0b14e40666",

??? "groups": [

????? "system:serviceaccounts",

????? "system:serviceaccounts:calico-system",

????? "system:authenticated"

??? ],

??? "extra": {

????? "authentication.kubernetes.io/pod-name": [

??????? "calico-kube-controllers-6b7b9c649d-xllqh"

????? ],

????? "authentication.kubernetes.io/pod-uid": [

??????? "fbf6ee10-fd48-4e64-bd03-31995dedbe6a"

????? ]

??? }

? },

? "sourceIPs": [

??? "10.244.219.105"

? ],

? "userAgent": "kube-controllers/v0.0.0 (linux/amd64) kubernetes/$Format",

? "responseStatus": {

??? "metadata": {},

??? "code": 200

? },

? "requestReceivedTimestamp": "2023-11-20T09:06:54.725743Z",

? "stageTimestamp": "2023-11-20T09:06:54.727333Z",

? "annotations": {

??? "authorization.k8s.io/decision": "allow",

??? "authorization.k8s.io/reason": "RBAC: allowed by ClusterRoleBinding \"system:public-info-viewer\" of ClusterRole \"system:public-info-viewer\" to Group \"system:authenticated\""

? }

}

内容解析

  1. 事件基本信息
    1. kind: 表示事件的类型,这里是 "Event"。
    2. apiVersion: 表示 Kubernetes 审计 API 的版本,这里是 "audit.k8s.io/v1"。
    3. level: 表示事件的级别,这里是 "Metadata"。
    4. auditID: 事件的唯一标识符。
    5. stage: 表示事件发生的阶段,这里是 "ResponseComplete",表示 API 请求的响应已经完成。
  2. 请求信息
    1. requestURI: 表示请求的 URI,这里是 "/healthz"。
    2. verb: 表示请求的动作,这里是 "get",表示是一个 GET 请求。
    3. user: 提供有关执行请求的用户的详细信息,包括用户名、UID、用户组等。
    4. sourceIPs: 表示请求的来源 IP 地址。
    5. userAgent: 表示发起请求的用户代理信息,这里是 "kube-controllers/v0.0.0 (linux/amd64) kubernetes/$Format"。
  3. 响应信息
    1. responseStatus: 提供有关响应的信息,包括响应代码和元数据。这里是一个成功的响应,HTTP 状态码为 200。
    2. 时间戳:
    3. requestReceivedTimestamp: 表示请求接收的时间戳。
    4. stageTimestamp: 表示事件阶段的时间戳。
  4. 注释信息
  5. annotations: 提供与事件相关的注释信息,这里包括授权决策的一些详细信息。
  6. authorization.k8s.io/decision: 授权决策,这里是 "allow",表示允许请求。
  7. authorization.k8s.io/reason: 授权决策的原因,这里是 "RBAC: allowed by ClusterRoleBinding...",表示通过 ClusterRoleBinding 的 RBAC 规则允许。

示例

[root@master ~]# docker run -d? --name web1666 nginx:1.17.1

[root@master kubernetes]# cat? /var/log/audit/k8s_audit.log? | grep web1666 | jq

日志收集与呈现方案

审计日志文件 + filebeat

审计日志文件 + ELK

审计webhook + logstash

审计webhook + falco

K8S 日志为什么以 stdout 和 stderr 的方式输出

文件描述符? ? ? ? ? ? ? ? ? ? ?作用? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 例子(c语言)

0? ? ?(stdin)? ? ? ? ? ? ? ? ?标准输入? ? ? ? ? ? ? ? ? ? ? ? ? ?fscanf(stdin,"%s",str);

1? ? ?(stdout)? ? ? ? ? ? ? ?标准输出? ? ? ? ? ? ? ? ? ? ? ? ? ?fprintf(stdout,"%s\n","hello");

2? ? ? (stderror)? ? ? ? ? ? ??标准错误输出? ? ? ? ? ? ? ? ? ? fprintf(stderr,"%s\n","error");

1. 简单方便,可以直接使用语言自带的标准库,打印出信息(比如c语言的printf, fprintf函数)作为日志的输入源,不用额外的再建立一个文件。

2. 易管理,可以将容器的标准输出stdout, stderr重定向到log-file.log。 比如将上面的test.c文件编译后,执行? ./a.out >> a.log? 2>&1,就会将标准输出存放到a.log里

nginx 导出日志到logs

使用 volumes 中的 emptyDir: {}

yaml 如图

文章来源:https://blog.csdn.net/weixin_48297181/article/details/135482754
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。