Edit This Page

Auditing

FEATURE STATE: Kubernetes v1.13 feature-state-beta.txt
Cette fonctionnalité est actuellement dans un état beta, c’est-à-dire :

  • Les noms de version contiennent: beta (par ex. v2beta3).
  • Le code est bien testé. L’activation de cette fonctionnalité est considérée comme sûre. Elle est activée par défaut.
  • La prise en charge de l’ensemble de la fonctionnalité ne sera pas supprimée, bien que des détails puissent changer.
  • Le schéma et/ou la sémantique des objets peuvent changer de manière incompatible dans une version bêta ou stable ultérieure. Lorsque cela se produira, nous vous fournirons des instructions pour migrer vers la prochaine version. Cela peut nécessiter la suppression, l’édition et la recréation d’objets API. Le processus de changement de version peut nécessiter une certaine réflexion. Cela peut aussi nécessiter une interruption de service pour les applications qui s’appuient sur cette fonctionnalité.
  • Recommandé uniquement pour les utilisations non critiques en raison du risque de changements incompatibles dans les versions ultérieures. Si vous avez plusieurs clusters qui peuvent être mis à niveau indépendamment, vous pouvez assouplir cette restriction.
  • Donnez votre avis sur cette fonctionnalité bêta ! Une fois qu’elle aura quitté la version bêta, ce sera probablement moins évident pour nous d’apporter d’autres changements.

Kubernetes 审计功能提供了与安全相关的按时间顺序排列的记录集,记录单个用户、管理员或系统其他组件影响系统的活动顺序。 它能帮助集群管理员处理以下问题:

Kube-apiserver 执行审计。每个执行阶段的每个请求都会生成一个事件,然后根据特定策略对事件进行预处理并写入后端。 您可以在 设计方案 中找到更多详细信息。 该策略确定记录的内容并且在后端存储记录。当前的后端支持日志文件和 webhook。

每个请求都可以用相关的 “stage” 记录。已知的 stage 有:

Note:

注意 审计日志记录功能会增加 API server 的内存消耗,因为需要为每个请求存储审计所需的某些上下文。 此外,内存消耗取决于审计日志记录的配置。

审计策略

审计政策定义了关于应记录哪些事件以及应包含哪些数据的规则。审计策略对象结构在 audit.k8s.io API 组 中定义。 处理事件时,将按顺序与规则列表进行比较。第一个匹配规则设置事件的 [审计级别][auditing-level]。已知的审计级别有:

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

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

audit/audit-policy.yaml
apiVersion: audit.k8s.io/v1beta1 # 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/v1beta1
kind: Policy
rules:
- level: Metadata

管理员构建自己的审计配置文件时,应使用 GCE 使用的审计配置文件 作为参考。

审计后端

审计后端实现将审计事件导出到外部存储。 Kube-apiserver 提供两个后端:

在这两种情况下,审计事件结构均由 audit.k8s.io API 组中的 API 定义。当前版本的 API 是 v1beta1

Note:

注意: 在 patch 请求的情况下,请求的消息体需要是一个 JSON 串指定 patch 操作,而不是一个完整的 Kubernetes API 对象 JSON 串。 例如,以下的示例是一个合法的 patch 请求消息体,该请求对应 /apis/batch/v1/namespaces/some-namespace/jobs/some-job-name

[
  {
    "op": "replace",
    "path": "/spec/parallelism",
    "value": 0
  },
  {
    "op": "remove",
    "path": "/spec/template/spec/containers/0/terminationMessagePolicy"
  }
]

Log 后端

Log 后端将审计事件写入 JSON 格式的文件。您可以使用以下 kube-apiserver 标志配置 Log 审计后端:

Webhook 后端

Webhook 后端将审计事件发送到远程 API,该远程 API 应该暴露与 kube-apiserver 相同的API。 您可以使用如下 kube-apiserver 标志来配置 webhook 审计后端:

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

Batching

log 和 webhook 后端都支持 batch。以 webhook 为例,以下是可用参数列表。要获取 log 后端的同样参数,请在参数名称中将 webhook 替换为 log。 默认情况下,在 webhook 中启用 batch,在 log 中禁用 batch。同样,默认情况下,在 webhook 中启用限制,在 log 中禁用限制。

以下参数仅用于 batch 模式。

参数调整

需要设置参数以适应 apiserver 上的负载。

例如,如果 kube-apiserver 每秒收到 100 个请求,并且每个请求仅在 ResponseStartedResponseComplete 阶段进行审计,则应该考虑每秒生成约 200 个审计事件。 假设批处理中最多有 100 个事件,则应将限制级别设置为至少 2 个 QPS。 假设后端最多需要 5 秒钟来写入事件,您应该设置缓冲区大小以容纳最多 5 秒的事件,即 10 个 batch,即 1000 个事件。

但是,在大多数情况下,默认参数应该足够了,您不必手动设置它们。您可以查看 kube-apiserver 公开的以下 Prometheus 指标,并在日志中监控审计子系统的状态。

多集群配置

如果您通过 aggregation layer 对 Kubernetes API 进行扩展,那么您也可以为聚合的 apiserver 设置审计日志。 想要这么做,您需要以上述的格式给聚合的 apiserver 配置参数,并且配置日志管道以采用审计日志。不同的 apiserver 可以配置不同的审计配置和策略。

日志选择器示例

使用 fluentd 从日志文件中选择并且分发审计日志

Fluentd 是一个开源的数据采集器,可以从统一的日志层中采集。 在以下示例中,我们将使用 fluentd 来按照命名空间划分审计事件。

  1. 在 kube-apiserver node 节点上安装 fluentd, fluent-plugin-forest and fluent-plugin-rewrite-tag-filter
  2. 为 fluentd 创建一个配置文件

    $ cat <<EOF > /etc/fluentd/config
    # fluentd conf runs in the same host with kube-apiserver
    <source>
        @type tail
        # audit log path of kube-apiserver
        path /var/log/audit
        pos_file /var/log/audit.pos
        format json
        time_key time
        time_format %Y-%m-%dT%H:%M:%S.%N%z
        tag audit
    </source>
    
    <filter audit>
        #https://github.com/fluent/fluent-plugin-rewrite-tag-filter/issues/13
        type record_transformer
        enable_ruby
        <record>
         namespace ${record["objectRef"].nil? ? "none":(record["objectRef"]["namespace"].nil? ?  "none":record["objectRef"]["namespace"])}
        </record>
    </filter>
    
    <match audit>
        # route audit according to namespace element in context
        @type rewrite_tag_filter
        rewriterule1 namespace ^(.+) ${tag}.$1
    </match>
    
    <filter audit.**>
       @type record_transformer
       remove_keys namespace
    </filter>
    
    <match audit.**>
        @type forest
        subtype file
        remove_prefix audit
        <template>
            time_slice_format %Y%m%d%H
            compress gz
            path /var/log/audit-${tag}.*.log
            format json
            include_time_key true
        </template>
    </match>
  1. 启动 fluentd

    $ fluentd -c /etc/fluentd/config  -vv
  1. 给 kube-apiserver 配置以下参数并启动:

    --audit-policy-file=/etc/kubernetes/audit-policy.yaml --audit-log-path=/var/log/kube-audit --audit-log-format=json
  1. /var/log/audit-*.log 文件中检查不同命名空间的审计事件

使用 logstash 采集并分发 webhook 后端的审计事件

Logstash 是一个开源的、服务器端的数据处理工具。在下面的示例中,我们将使用 logstash 采集 webhook 后端的审计事件,并且将来自不同用户的事件存入不同的文件。

  1. 安装 logstash
  2. 为 logstash 创建配置文件

    $ cat <<EOF > /etc/logstash/config
    input{
        http{
            #TODO, figure out a way to use kubeconfig file to authenticate to logstash
            #https://www.elastic.co/guide/en/logstash/current/plugins-inputs-http.html#plugins-inputs-http-ssl
            port=>8888
        }
    }
    filter{
        split{
            # Webhook audit backend sends several events together with EventList
            # split each event here.
            field=>[items]
            # We only need event subelement, remove others.
            remove_field=>[headers, metadata, apiVersion, "@timestamp", kind, "@version", host]
        }
        mutate{
            rename => {items=>event}
        }
    }
    output{
        file{
            # Audit events from different users will be saved into different files.
            path=>"/var/log/kube-audit-%{[event][user][username]}/audit"
        }
    }
  1. 启动 logstash

    $ bin/logstash -f /etc/logstash/config --path.settings /etc/logstash/
  1. 为 kube-apiserver webhook 审计后端创建一个 kubeconfig 文件

    ```none $ cat < /etc/kubernetes/audit-webhook-kubeconfig apiVersion: v1 clusters:

    • cluster: server: http://:8888 name: logstash contexts:
    • context: cluster: logstash user: “” name: default-context current-context: default-context kind: Config preferences: {} users: [] EOF ```
  1. 为 kube-apiserver 配置以下参数并启动:

    --audit-policy-file=/etc/kubernetes/audit-policy.yaml --audit-webhook-config-file=/etc/kubernetes/audit-webhook-kubeconfig
  1. 在 logstash node 节点的 /var/log/kube-audit-*/audit 目录中检查审计事件

注意到,除了文件输出插件外,logstash 还有其它多种输出可以让用户路由不同的数据。例如,用户可以将审计事件发送给支持全文搜索和分析的 elasticsearch 插件。

传统的审计

注意: 传统审计已被弃用,自 1.8 版本以后默认禁用,并且将会在 1.12 版本中彻底移除。 如果想要回退到传统的审计功能,请使用 kube-apiserver 中 feature gate 的 AdvancedAuditing 功能来禁用高级审核功能:

--feature-gates=AdvancedAuditing=false

在传统格式中,每个审计文件条目包含两行:

  1. 请求行包含唯一 ID 以匹配响应和请求元数据,例如源 IP、请求用户、模拟信息和请求的资源等。
  2. 响应行包含与请求行和响应代码相匹配的唯一 ID。
2017-03-21T03:57:09.106841886-04:00 AUDIT: id="c939d2a7-1c37-4ef1-b2f7-4ba9b1e43b53" ip="127.0.0.1" method="GET" user="admin" groups="\"system:masters\",\"system:authenticated\"" as="<self>" asgroups="<lookup>" namespace="default" uri="/api/v1/namespaces/default/pods"
2017-03-21T03:57:09.108403639-04:00 AUDIT: id="c939d2a7-1c37-4ef1-b2f7-4ba9b1e43b53" response="200"

配置

Kube-apiserver 提供以下选项,负责配置审核日志的位置和处理方式:

如果审核日志文件已经存在,则 Kubernetes 会将新的审核日志附加到该文件。 否则,Kubernetes 会在您在 audit-log-path 中指定的位置创建一个审计日志文件。 如果审计日志文件超过了您在 audit-log-maxsize 中指定的大小,则 Kubernetes 将通过在文件名(在文件扩展名之前)附加当前时间戳并重新创建一个新的审计日志文件来重命名当前日志文件。 Kubernetes 可能会在创建新的日志文件时删除旧的日志文件; 您可以通过指定 audit-log-maxbackupaudit-log-maxage 选项来配置保留多少文件以及它们的保留时间。

反馈