Kubernetes 審計功能提供了與安全相關的按時間順序排列的記錄集,記錄單個用戶、管理員或系統其他組件影響系統的活動順序。它能幫助集群管理員處理以下問題:
-
發生了什么?
-
什么時候發生的?
-
誰觸發的?
-
為什么發生?
-
在哪觀察到的?
-
它從哪觸發的?
-
它將產生什么后果?
Kube-apiserver 執行審計。每個執行階段的每個請求都會生成一個事件,然后根據特定策略對事件進行預處理並寫入后端。
每個請求都可以用相關的 “stage” 記錄。已知的 stage 有:
-
RequestReceived -事件的 stage 將在審計處理器接收到請求后,並且在委托給其余處理器之前生成。
-
ResponseStarted - 在響應消息的頭部發送后,但是響應消息體發送前。這個 stage 僅為長時間運行的請求生成(例如 watch)。
-
ResponseComplete - 當響應消息體完成並且沒有更多數據需要傳輸的時候。
-
Panic - 當 panic 發生時生成。
Note:
審計日志記錄功能會增加 API server的內存消耗,因為需要為每個請求存儲審計所需的某些上下文。此外,內存消耗取決於審計日志記錄的配置。
審計策略
審計政策定義了關於應記錄哪些事件以及應包含哪些數據的規則。處理事件時,將按順序與規則列表進行比較。第一個匹配規則設置事件的 [審計級別][auditing-level]。已知的審計級別有:
None -符合這條規則的日志將不會記錄。
Metadata -記錄請求的 metadata(請求的用戶、timestamp、resource、verb 等等),但是不記錄請求或者響應的消息體。
Request -記錄事件的 metadata 和請求的消息體,但是不記錄響應的消息體。這不適用於非資源類型的請求。
RequestResponse -記錄事件的 metadata,請求和響應的消息體。這不適用於非資源類型的請求。
您可以使用 --audit-policy-file 標志將包含策略的文件傳遞給 kube-apiserver。如果不設置該標志,則不記錄事件。注意 rules 字段必須在審計策略文件中提供。
以下是一個審計策略文件的示例:
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
審計日志后端
k8s目前提供兩種日志后端,Log后端和webhook后端,Log后端可以將日志輸出到文件,webhook后端將日志發送到遠端日志服務器,接下來暫且只對Log后端日志的記錄配置和采集做一下實踐。
以下實踐組件版本docker ce17,k8s 1.9.2
可以使用以下 kube-apiserver 標志配置 Log 審計后端:
--audit-log-path指定用來寫入審計事件的日志文件路徑。不指定此標志會禁用日志后端。- 意味着標准化
--audit-log-maxage定義了保留舊審計日志文件的最大天數
--audit-log-maxbackup定義了要保留的審計日志文件的最大數量
--audit-log-maxsize定義審計日志文件的最大大小(兆字節)
我司目前集群中kube-apiserver組件作為static pod方式運行,生命周期由kubelet直接管理,static pod由kebelet根據yaml文件創建,yaml存放路徑為/etc/kubernetes/manifests/目錄,其中apiserver由kubelet根據kube-apiserver.yaml創建,Log后端需要在kube-apiserver.yaml的啟動參數里加以下參數:
--feature-gates=AdvancedAuditing=true
--audit-policy-file=/etc/kubernetes/pki/audit-policy.yaml
--audit-log-format=json
--audit-log-path=/var/log/kubernetes/kubernetes-audit
--audit-log-maxage=30
--audit-log-maxbackup=3
--audit-log-maxsize=100
說明:
-
AdvancedAuditing指明啟用高級審計功能,即:可以使--audit-policy-file參數指定審計策略,該參數從k8s 1.8版本以后默認為true;
-
audit-policy-file指定策略文件的位置,該路徑為kube-apiserver容器內的路徑,所以得從宿主機掛載策略文件到容器內,故暫且放在/etc/kubernetes/pki/目錄下;
-
audit-log-format指定最終審計日志的格式為json,該參數默認為json;
-
audit-log-path指定最終審計日志存放在容器內的位置,該位置會自動創建。上述表示最終的審計日志文件為kubernetes-audit
最終配置如下:
修改完成后,kubelet會自動刪除重建kube-apiserver的pod(如果pod被刪除后,過幾分鍾還不被創建,可以修改--audit-log-maxbackup的值保存退出,等待pod被創建---這可能是一個bug),重啟狀態變為running后可以進入容器查看生成的審計日志文件:
查看該日志:
達到100M后:
因為后面要用fluentd作為agent去采集該日志,所以需要把容器內的日志掛載到宿主機目錄下,修改kube-apiserver.yaml如下,即將容器內/var/log/kubernetes目錄掛載到宿主機的/var/log/kubernetes目錄。
日志采集
目前集群中已部署了fluentd+elasticsearch日志方案,所以選用fluentd作為 Logging-agent ,Elasticsearch作為 Logging Backend 。集群中的fluentd-es作為DaemonSet 方式運行,根據DaemonSet的特性,應該在每個Node上都會運行fluentd-es的pod,但實際情況是19環境上3個master節點都沒有該pod。查看名為fluentd-es-v1.22的DaemonSet yaml可以發現,pod只會運行在有alpha.kubernetes.io/fluentd-ds-ready: “true”標簽的node上:
查看master節點的node yaml,發現確實沒有該標簽。故需要在master節點node上添加該標簽:
添加完label后,可以看到在docker-vm-6節點上pod會被自動創建。
Fluentd的配置文件在容器內的/etc/td-agent/td-agent.conf中配置,部分配置截圖如下:
該配置由名為fluentd的ConfigMap指定:
可以看到配置里並不會去采集、轉發審計日志/var/log/kubernetes/kubernetes-audit,所以需要在該ConfigMap中添加以下配置:
添加后的截圖如下:
之后需要重啟一下kube-apiserver節點的fluentd pod,fluentd采集時,也會輸出日志到宿主機的/var/log/fluentd.log里,可以看到錯誤日志等信息,用於定位問題。如果該文件沒有審計日志相關錯誤,日志應該就會被發送到logging-backend:elasticsearch,可以用以下命令驗證:
- 先查看elasticsearch的service IP和Port,然后用curl命令調用rest接口查詢當前集群中所有index信息:
- 查詢到審計日志信息如下,大概有220萬條記錄:
詳細信息如下,和審計日志文件中記錄的一樣:
后續可以用Kibana進行日志展示,Elasticsearch、Fluentd、Kibana即為大名鼎鼎的EFK日志收集方案,還有ELK等,可以根據項目的需求選擇適當的組件。
本公眾號免費提供csdn下載服務,海量IT學習資源,如果你准備入IT坑,勵志成為優秀的程序猿,那么這些資源很適合你,包括但不限於java、go、python、springcloud、elk、嵌入式 、大數據、面試資料、前端 等資源。同時我們組建了一個技術交流群,里面有很多大佬,會不定時分享技術文章,如果你想來一起學習提高,可以公眾號后台回復【2】,免費邀請加技術交流群互相學習提高,會不定期分享編程IT相關資源。
掃碼關注,精彩內容第一時間推給你