Kubernetes 審計

2022-05-30 16:29 更新

審計

FEATURE STATE: Kubernetes v1.24 [beta]

Kubernetes 審計(Auditing) 功能提供了與安全相關(guān)的、按時間順序排列的記錄集, 記錄每個用戶、使用 Kubernetes API 的應(yīng)用以及控制面自身引發(fā)的活動。

審計功能使得集群管理員能夠回答以下問題:

  • 發(fā)生了什么?
  • 什么時候發(fā)生的?
  • 誰觸發(fā)的?
  • 活動發(fā)生在哪個(些)對象上?
  • 在哪觀察到的?
  • 它從哪觸發(fā)的?
  • 活動的后續(xù)處理行為是什么?

審計記錄最初產(chǎn)生于 kube-apiserver 內(nèi)部。每個請求在不同執(zhí)行階段都會生成審計事件;這些審計事件會根據(jù)特定策略 被預(yù)處理并寫入后端。策略確定要記錄的內(nèi)容和用來存儲記錄的后端。 當(dāng)前的后端支持日志文件和 webhook。

每個請求都可被記錄其相關(guān)的 階段(stage)。已定義的階段有:

  • ?RequestReceived ?- 此階段對應(yīng)審計處理器接收到請求后,并且在委托給 其余處理器之前生成的事件。
  • ?ResponseStarted ?- 在響應(yīng)消息的頭部發(fā)送后,響應(yīng)消息體發(fā)送前生成的事件。 只有長時間運行的請求(例如 watch)才會生成這個階段。
  • ?ResponseComplete ?- 當(dāng)響應(yīng)消息體完成并且沒有更多數(shù)據(jù)需要傳輸?shù)臅r候。
  • ?Panic ?- 當(dāng) panic 發(fā)生時生成。

Note: 審計事件配置 的配置與 Event API 對象不同。

審計日志記錄功能會增加 API server 的內(nèi)存消耗,因為需要為每個請求存儲審計所需的某些上下文。 此外,內(nèi)存消耗取決于審計日志記錄的配置。

審計策略 

審計政策定義了關(guān)于應(yīng)記錄哪些事件以及應(yīng)包含哪些數(shù)據(jù)的規(guī)則。 審計策略對象結(jié)構(gòu)定義在 ?audit.k8s.io? API 組 處理事件時,將按順序與規(guī)則列表進(jìn)行比較。第一個匹配規(guī)則設(shè)置事件的 審計級別(Audit Level)。已定義的審計級別有:

  • ?None ?- 符合這條規(guī)則的日志將不會記錄。
  • ?Metadata ?- 記錄請求的元數(shù)據(jù)(請求的用戶、時間戳、資源、動詞等等), 但是不記錄請求或者響應(yīng)的消息體。
  • ?Request ?- 記錄事件的元數(shù)據(jù)和請求的消息體,但是不記錄響應(yīng)的消息體。 這不適用于非資源類型的請求。
  • ?RequestResponse ?- 記錄事件的元數(shù)據(jù),請求和響應(yīng)的消息體。這不適用于非資源類型的請求。

你可以使用 ?--audit-policy-file? 標(biāo)志將包含策略的文件傳遞給 ?kube-apiserver?。 如果不設(shè)置該標(biāo)志,則不記錄事件。 注意 ?rules ?字段 必須 在審計策略文件中提供。沒有(0)規(guī)則的策略將被視為非法配置。

以下是一個審計策略文件的示例:

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 ?級別記錄所有請求:

# 在 Metadata 級別為所有請求生成日志
apiVersion: audit.k8s.io/v1beta1
kind: Policy
rules:
- level: Metadata

如果你在打磨自己的審計配置文件,你可以使用為 Google Container-Optimized OS 設(shè)計的審計配置作為出發(fā)點。你可以參考 configure-helper.sh 腳本,該腳本能夠生成審計策略文件。你可以直接在腳本中看到審計策略的絕大部份內(nèi)容。

你也可以參考 ?Policy ?配置參考 以獲取有關(guān)已定義字段的詳細(xì)信息。

審計后端 

審計后端實現(xiàn)將審計事件導(dǎo)出到外部存儲。?Kube-apiserver? 默認(rèn)提供兩個后端:

  • Log 后端,將事件寫入到文件系統(tǒng)
  • Webhook 后端,將事件發(fā)送到外部 HTTP API

在這所有情況下,審計事件均遵循 Kubernetes API 在 ?audit.k8s.io? API 組 中定義的結(jié)構(gòu)。

Note:
對于 patch 請求,請求的消息體需要是設(shè)定 patch 操作的 JSON 所構(gòu)成的一個串, 而不是一個完整的 Kubernetes API 對象 JSON 串。 例如,以下的示例是一個合法的 patch 請求消息體,該請求對應(yīng) ?/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 后端將審計事件寫入 JSONlines 格式的文件。 你可以使用以下 ?kube-apiserver? 標(biāo)志配置 Log 審計后端:

  • ?--audit-log-path? 指定用來寫入審計事件的日志文件路徑。不指定此標(biāo)志會禁用日志后端。?-? 意味著標(biāo)準(zhǔn)化
  • ?--audit-log-maxage? 定義保留舊審計日志文件的最大天數(shù)
  • ?--audit-log-maxbackup? 定義要保留的審計日志文件的最大數(shù)量
  • ?--audit-log-maxsize? 定義審計日志文件的最大大?。ㄕ鬃止?jié))

如果你的集群控制面以 Pod 的形式運行 kube-apiserver,記得要通過 ?hostPath ?卷來訪問策略文件和日志文件所在的目錄,這樣審計記錄才會持久保存下來。例如:

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

接下來掛載數(shù)據(jù)卷:

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 后端將審計事件發(fā)送到遠(yuǎn)程 Web API,該遠(yuǎn)程 API 應(yīng)該暴露與 ?kube-apiserver? 形式相同的 API,包括其身份認(rèn)證機(jī)制。你可以使用如下 kube-apiserver 標(biāo)志來配置 Webhook 審計后端:

  • ?--audit-webhook-config-file? 設(shè)置 Webhook 配置文件的路徑。Webhook 配置文件實際上是一個 kubeconfig 文件。
  • ?--audit-webhook-initial-backoff? 指定在第一次失敗后重發(fā)請求等待的時間。隨后的請求將以指數(shù)退避重試。

Webhook 配置文件使用 kubeconfig 格式指定服務(wù)的遠(yuǎn)程地址和用于連接它的憑據(jù)。

事件批處理 

日志和 Webhook 后端都支持批處理。以 Webhook 為例,以下是可用參數(shù)列表。要獲取日志 后端的同樣參數(shù),請在參數(shù)名稱中將 ?webhook ?替換為 ?log?。 默認(rèn)情況下,在 ?webhook ?中批處理是被啟用的,在 ?log ?中批處理是被禁用的。 同樣,默認(rèn)情況下,在 ?webhook ?中啟用帶寬限制,在 ?log ?中禁用帶寬限制。

  • ?--audit-webhook-mode? 定義緩存策略,可選值如下:
    • ?batch? - 以批處理緩存事件和異步的過程。這是默認(rèn)值。
    • ?blocking? - 在 API 服務(wù)器處理每個單獨事件時,阻塞其響應(yīng)。
    • ?blocking-strict? - 與 ?blocking ?相同,不過當(dāng)審計日志在 RequestReceived 階段 失敗時,整個 API 服務(wù)請求會失效。

以下參數(shù)僅用于 ?batch ?模式。

  • ?--audit-webhook-batch-buffer-size? 定義 batch 之前要緩存的事件數(shù)。 如果傳入事件的速率溢出緩存區(qū),則會丟棄事件。
  • ?--audit-webhook-batch-max-size? 定義一個 batch 中的最大事件數(shù)。
  • ?--audit-webhook-batch-max-wait? 無條件 batch 隊列中的事件前等待的最大事件。
  • ?--audit-webhook-batch-throttle-qps? 每秒生成的最大批次數(shù)。
  • ?--audit-webhook-batch-throttle-burst? 在達(dá)到允許的 QPS 前,同一時刻允許存在的最大 batch 生成數(shù)。

參數(shù)調(diào)整 

需要設(shè)置參數(shù)以適應(yīng) API 服務(wù)器上的負(fù)載。

例如,如果 kube-apiserver 每秒收到 100 個請求,并且每個請求僅在 ?ResponseStarted ?和 ?ResponseComplete ?階段進(jìn)行審計,則應(yīng)該考慮每秒生成約 200 個審計事件。 假設(shè)批處理中最多有 100 個事件,則應(yīng)將限制級別設(shè)置為每秒至少 2 個查詢。 假設(shè)后端最多需要 5 秒鐘來寫入事件,你應(yīng)該設(shè)置緩沖區(qū)大小以容納最多 5 秒的事件, 即 10 個 batch,即 1000 個事件。

但是,在大多數(shù)情況下,默認(rèn)參數(shù)應(yīng)該足夠了,你不必手動設(shè)置它們。 你可以查看 kube-apiserver 公開的以下 Prometheus 指標(biāo),并在日志中監(jiān)控審計子系統(tǒng)的狀態(tài)。

  • ?apiserver_audit_event_total ?包含所有暴露的審計事件數(shù)量的指標(biāo)。
  • ?apiserver_audit_error_total ?在暴露時由于發(fā)生錯誤而被丟棄的事件的數(shù)量。

日志條目截斷 

日志后端和 Webhook 后端都支持限制所輸出的事件的尺寸。 例如,下面是可以為日志后端配置的標(biāo)志列表:

  • ?audit-log-truncate-enabled?:是否棄用事件和批次的截斷處理。
  • ?audit-log-truncate-max-batch-size?:向下層后端發(fā)送的各批次的最大尺寸字節(jié)數(shù)。
  • ?audit-log-truncate-max-event-size?:向下層后端發(fā)送的審計事件的最大尺寸字節(jié)數(shù)。

默認(rèn)情況下,截斷操作在 ?webhook ?和 ?log ?后端都是被禁用的,集群管理員需要設(shè)置 ?audit-log-truncate-enabled? 或 ?audit-webhook-truncate-enabled? 標(biāo)志來啟用此操作。


以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號