審計

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)