審計
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 組 中定義的結構。
注意
對於補丁(patches),請求體是一個包含補丁操作的 JSON 陣列,而不是一個包含相應 Kubernetes API 物件的 JSON 物件。例如,以下請求體是對 /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"
}
]
日誌後端
日誌後端將審計事件寫入 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 格式指定服務的遠端地址以及用於連線的憑據。
事件批處理
log
和 webhook
後端都支援批處理。以下是每個後端特有的可用標誌列表。預設情況下,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 個請求,並且每個請求僅在 ResponseStarted
和 ResponseComplete
階段進行審計,則應考慮每秒生成約 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
傳送到底層後端的審計事件的最大位元組大小。
預設情況下,webhook
和 log
都停用截斷,叢集管理員應設定 audit-log-truncate-enabled
或 audit-webhook-truncate-enabled
以啟用此功能。
下一步
- 瞭解 修改性 Webhook 審計註解。
- 透過閱讀審計配置參考,瞭解有關
Event
和Policy
資源型別的更多資訊。