审计

Kubernetes **审计**提供了一组与安全相关的、按时间顺序排列的记录,记录了集群中操作序列。集群会审计由用户、使用 Kubernetes API 的应用程序以及控制平面本身生成的活动。

审计允许集群管理员回答以下问题:

  • 发生了什么?
  • 何时发生?
  • 谁发起的?
  • 在什么对象上发生?
  • 在哪里被观察到?
  • 从哪里发起的?
  • 去往哪里?

审计记录的生命周期始于 kube-apiserver 组件内部。请求在执行的每个阶段都会生成一个审计事件,然后根据特定策略进行预处理并写入后端。策略决定了记录哪些内容,后端则持久化记录。当前的后端实现包括日志文件和 Webhook。

每个请求都可以记录一个关联的 **阶段**。定义的阶段包括:

  • RequestReceived - 审计处理程序收到请求后,在将其委派给处理程序链之前立即生成的事件阶段。
  • ResponseStarted - 响应头已发送,但响应体尚未发送。此阶段仅针对长时间运行的请求(例如 watch)生成。
  • ResponseComplete - 响应体已完成,不再发送任何字节。
  • Panic - 发生 panic 时生成的事件。

审计日志功能会增加 API 服务器的内存消耗,因为每个请求所需的一些审计上下文会被存储。内存消耗取决于审计日志配置。

审计策略

审计策略定义了哪些事件应该被记录以及它们应该包含哪些数据的规则。审计策略对象结构在 audit.k8s.io API 组 中定义。当事件被处理时,它会与规则列表按顺序进行比较。第一个匹配的规则设置事件的**审计级别**。定义的审计级别包括:

  • None - 不记录与此规则匹配的事件。
  • Metadata - 记录包含元数据(请求用户、时间戳、资源、动词等)但不包含请求或响应体的事件。
  • Request - 记录包含请求元数据和请求体但不包含响应体的事件。这不适用于非资源请求。
  • RequestResponse - 记录包含请求元数据、请求体和响应体的事件。这不适用于非资源请求。

你可以使用 --audit-policy-file 标志将包含策略的文件传递给 kube-apiserver。如果省略该标志,则不会记录任何事件。请注意,审计策略文件中**必须**提供 rules 字段。没有(0)规则的策略被视为非法。

以下是一个审计策略文件示例:

apiVersion: audit.k8s.io/v1 # This is required.
kind: Policy
# Don't generate audit events for all requests in RequestReceived stage.
omitStages:
  - "RequestReceived"
rules:
  # Log pod changes at RequestResponse level
  - level: RequestResponse
    resources:
    - group: ""
      # Resource "pods" doesn't match requests to any subresource of pods,
      # which is consistent with the RBAC policy.
      resources: ["pods"]
  # Log "pods/log", "pods/status" at Metadata level
  - level: Metadata
    resources:
    - group: ""
      resources: ["pods/log", "pods/status"]

  # Don't log requests to a configmap called "controller-leader"
  - level: None
    resources:
    - group: ""
      resources: ["configmaps"]
      resourceNames: ["controller-leader"]

  # Don't log watch requests by the "system:kube-proxy" on endpoints or services
  - level: None
    users: ["system:kube-proxy"]
    verbs: ["watch"]
    resources:
    - group: "" # core API group
      resources: ["endpoints", "services"]

  # Don't log authenticated requests to certain non-resource URL paths.
  - level: None
    userGroups: ["system:authenticated"]
    nonResourceURLs:
    - "/api*" # Wildcard matching.
    - "/version"

  # Log the request body of configmap changes in kube-system.
  - level: Request
    resources:
    - group: "" # core API group
      resources: ["configmaps"]
    # This rule only applies to resources in the "kube-system" namespace.
    # The empty string "" can be used to select non-namespaced resources.
    namespaces: ["kube-system"]

  # Log configmap and secret changes in all other namespaces at the Metadata level.
  - level: Metadata
    resources:
    - group: "" # core API group
      resources: ["secrets", "configmaps"]

  # Log all other resources in core and extensions at the Request level.
  - level: Request
    resources:
    - group: "" # core API group
    - group: "extensions" # Version of group should NOT be included.

  # A catch-all rule to log all other requests at the Metadata level.
  - level: Metadata
    # Long-running requests like watches that fall under this rule will not
    # generate an audit event in RequestReceived.
    omitStages:
      - "RequestReceived"

你可以使用一个最小审计策略文件来以 Metadata 级别记录所有请求:

# Log all requests at the Metadata level.
apiVersion: audit.k8s.io/v1
kind: Policy
rules:
- level: Metadata

如果你正在创建自己的审计配置文件,可以使用 Google Container-Optimized OS 的审计配置文件作为起点。你可以查看 configure-helper.sh 脚本,该脚本会生成一个审计策略文件。你可以直接查看脚本以了解大部分审计策略文件内容。

你还可以参考 Policy 配置参考 以获取有关定义字段的详细信息。

审计后端

审计后端将审计事件持久化到外部存储。开箱即用,kube-apiserver 提供两个后端:

  • 日志后端,将事件写入文件系统。
  • Webhook 后端,将事件发送到外部 HTTP API。

在所有情况下,审计事件都遵循 Kubernetes API 在 audit.k8s.io API 组 中定义的结构。

日志后端

日志后端将审计事件写入 JSONlines 格式的文件中。你可以使用以下 kube-apiserver 标志配置日志审计后端:

  • --audit-log-path 指定日志后端用于写入审计事件的日志文件路径。不指定此标志将禁用日志后端。- 表示标准输出。
  • --audit-log-maxage 定义保留旧审计日志文件的最大天数。
  • --audit-log-maxbackup 定义要保留的审计日志文件的最大数量。
  • --audit-log-maxsize 定义审计日志文件在轮换前允许的最大兆字节大小。

如果集群的控制平面将 kube-apiserver 作为 Pod 运行,请记住将 hostPath 挂载到策略文件和日志文件的位置,以便持久化审计记录。例如:

  - --audit-policy-file=/etc/kubernetes/audit-policy.yaml
  - --audit-log-path=/var/log/kubernetes/audit/audit.log

然后挂载卷:

...
volumeMounts:
  - mountPath: /etc/kubernetes/audit-policy.yaml
    name: audit
    readOnly: true
  - mountPath: /var/log/kubernetes/audit/
    name: audit-log
    readOnly: false

最后配置 hostPath

...
volumes:
- name: audit
  hostPath:
    path: /etc/kubernetes/audit-policy.yaml
    type: File

- name: audit-log
  hostPath:
    path: /var/log/kubernetes/audit/
    type: DirectoryOrCreate

Webhook 后端

Webhook 审计后端将审计事件发送到远程 Web API,该 API 被认为是 Kubernetes API 的一种形式,包括身份验证方式。你可以使用以下 kube-apiserver 标志配置 Webhook 审计后端:

  • --audit-webhook-config-file 指定包含 Webhook 配置的文件的路径。Webhook 配置实际上是一个专门的 kubeconfig
  • --audit-webhook-initial-backoff 指定第一次失败请求后重试前等待的时间。后续请求将以指数退避的方式重试。

Webhook 配置文件使用 kubeconfig 格式指定服务的远程地址以及用于连接的凭据。

事件批处理

logwebhook 后端都支持批处理。以下是每个后端特有的可用标志列表。默认情况下,webhook 后端**启用**批处理和节流,而 log 后端**禁用**批处理和节流。

  • --audit-webhook-mode 定义缓冲策略。以下之一:
    • batch - 缓冲事件并以批处理方式异步处理它们。这是 webhook 后端的默认模式。
    • blocking - 在处理每个独立事件时阻塞 API 服务器的响应。
    • blocking-strict - 与 blocking 相同,但在 RequestReceived 阶段审计日志失败时,kube-apiserver 的整个请求都会失败。

以下标志仅在 batch 模式下使用:

  • --audit-webhook-batch-buffer-size 定义批处理前要缓冲的事件数量。如果传入事件速率超过缓冲区,事件将被丢弃。默认值为 10000。
  • --audit-webhook-batch-max-size 定义一个批次中事件的最大数量。默认值为 400。
  • --audit-webhook-batch-max-wait 定义在无条件地批处理队列中的事件之前等待的最长时间。默认值为 30 秒。
  • --audit-webhook-batch-throttle-enable 定义是否启用批处理节流。默认情况下启用节流。
  • --audit-webhook-batch-throttle-qps 定义每秒生成的批处理最大平均数量。默认值为 10。
  • --audit-webhook-batch-throttle-burst 定义如果之前允许的 QPS 未充分利用,则在同一时刻生成的最大批处理数量。默认值为 15。

  • --audit-log-mode 定义缓冲策略。以下之一:
    • batch - 缓冲事件并以批处理方式异步处理它们。不建议将批处理用于 log 后端。
    • blocking - 在处理每个独立事件时阻塞 API 服务器的响应。这是 log 后端的默认模式。
    • blocking-strict - 与 blocking 相同,但在 RequestReceived 阶段审计日志失败时,kube-apiserver 的整个请求都会失败。

以下标志仅在 batch 模式下使用(默认情况下 log 后端**禁用**批处理,当批处理禁用时,所有与批处理相关的标志都会被忽略):

  • --audit-log-batch-buffer-size 定义批处理前要缓冲的事件数量。如果传入事件速率超过缓冲区,事件将被丢弃。
  • --audit-log-batch-max-size 定义一个批次中事件的最大数量。
  • --audit-log-batch-max-wait 定义在无条件地批处理队列中的事件之前等待的最长时间。
  • --audit-log-batch-throttle-enable 定义是否启用批处理节流。
  • --audit-log-batch-throttle-qps 定义每秒生成的批处理最大平均数量。
  • --audit-log-batch-throttle-burst 定义如果之前允许的 QPS 未充分利用,则在同一时刻生成的最大批处理数量。

参数调优

参数应设置为适应 API 服务器的负载。

例如,如果 kube-apiserver 每秒收到 100 个请求,并且每个请求仅在 ResponseStartedResponseComplete 阶段进行审计,则应考虑每秒生成约 200 个审计事件。假设一个批次中最多有 100 个事件,则应将节流级别设置为至少每秒 2 个查询。假设后端最多需要 5 秒才能写入事件,则应将缓冲区大小设置为可容纳 5 秒的事件;即:10 个批次,或 1000 个事件。

但在大多数情况下,默认参数应该足够了,你无需担心手动设置它们。你可以查看 kube-apiserver 暴露的以下 Prometheus 指标和日志,以监控审计子系统的状态。

  • apiserver_audit_event_total 指标包含导出的审计事件总数。
  • apiserver_audit_error_total 指标包含由于导出期间发生错误而丢弃的事件总数。

日志条目截断

日志和 Webhook 后端都支持限制记录事件的大小。例如,以下是日志后端可用的标志列表:

  • audit-log-truncate-enabled 是否启用事件和批处理截断。
  • audit-log-truncate-max-batch-size 发送到底层后端的批处理的最大字节大小。
  • audit-log-truncate-max-event-size 发送到底层后端的审计事件的最大字节大小。

默认情况下,webhooklog 都禁用截断,集群管理员应设置 audit-log-truncate-enabledaudit-webhook-truncate-enabled 以启用此功能。

下一步

上次修改时间:2025 年 3 月 16 日太平洋标准时间下午 5:03:使用选项卡在单独的选项卡中列出每个后端特有的标志。(cc8fd8152a)