系統日誌

系統組件日誌記錄叢集中發生的事件,這對於除錯非常有用。您可以組態日誌詳細程度以查看更多或更少的細節。日誌可以粗略到顯示組件內的錯誤,或者精細到顯示事件的逐步追蹤(例如 HTTP 訪問日誌、pod 狀態變更、控制器動作或排程器決策)。

Klog

klog 是 Kubernetes 日誌記錄函式庫。klog 為 Kubernetes 系統組件產生日誌訊息。

Kubernetes 正在簡化其組件中的日誌記錄。以下 klog 命令列標記 已棄用,從 Kubernetes v1.23 開始,並在 Kubernetes v1.26 中移除

  • --add-dir-header
  • --alsologtostderr
  • --log-backtrace-at
  • --log-dir
  • --log-file
  • --log-file-max-size
  • --logtostderr
  • --one-output
  • --skip-headers
  • --skip-log-headers
  • --stderrthreshold

輸出將始終寫入 stderr,無論輸出格式如何。輸出重定向預計由調用 Kubernetes 組件的組件處理。這可以是 POSIX shell 或 systemd 等工具。

在某些情況下,例如 distroless 容器或 Windows 系統服務,這些選項不可用。然後,kube-log-runner 二進制檔案可以用作 Kubernetes 組件的包裝器來重定向輸出。預構建的二進制檔案包含在幾個 Kubernetes 基礎映像檔中,傳統名稱為 /go-runner,在伺服器和節點發布存檔中為 kube-log-runner

此表顯示 kube-log-runner 調用如何對應於 shell 重定向

用法POSIX shell(例如 bash)kube-log-runner <選項> <cmd>
合併 stderr 和 stdout,寫入 stdout2>&1kube-log-runner (預設行為)
將兩者重定向到日誌檔案1>>/tmp/log 2>&1kube-log-runner -log-file=/tmp/log
複製到日誌檔案和 stdout2>&1 | tee -a /tmp/logkube-log-runner -log-file=/tmp/log -also-stdout
僅將 stdout 重定向到日誌檔案>/tmp/logkube-log-runner -log-file=/tmp/log -redirect-stderr=false

Klog 輸出

傳統 klog 原生格式的範例

I1025 00:15:15.525108       1 httplog.go:79] GET /api/v1/namespaces/kube-system/pods/metrics-server-v0.3.1-57c75779f-9p8wg: (1.512ms) 200 [pod_nanny/v0.0.0 (linux/amd64) kubernetes/$Format 10.56.1.19:51756]

訊息字串可能包含換行符

I1025 00:15:15.525108       1 example.go:79] This is a message
which has a line break.

結構化日誌記錄

功能狀態: Kubernetes v1.23 [beta]

結構化日誌記錄在日誌訊息中引入統一的結構,允許以程式化的方式提取資訊。您可以用更少的精力和成本來儲存和處理結構化日誌。產生日誌訊息的程式碼決定了它使用傳統的非結構化 klog 輸出還是結構化日誌記錄。

結構化日誌訊息的預設格式為文字,其格式與傳統 klog 向後相容

<klog header> "<message>" <key1>="<value1>" <key2>="<value2>" ...

範例

I1025 00:15:15.525108       1 controller_utils.go:116] "Pod status updated" pod="kube-system/kubedns" status="ready"

字串會被加上引號。其他值則使用 %+v 格式化,這可能會導致日誌訊息在下一行繼續顯示 取決於資料

I1025 00:15:15.525108       1 example.go:116] "Example" data="This is text with a line break\nand \"quotation marks\"." someInt=1 someFloat=0.1 someStruct={StringField: First line,
second line.}

情境式日誌記錄

功能狀態: Kubernetes v1.30 [beta]

情境式日誌記錄建立在結構化日誌記錄之上。它主要關於開發人員如何使用日誌記錄呼叫:基於該概念的程式碼更具彈性,並支援更多使用案例,如情境式日誌記錄 KEP中所述。

如果開發人員在其元件中使用 WithValuesWithName 等其他函數,則日誌條目將包含由呼叫者傳遞到函數中的其他資訊。

對於 Kubernetes 1.32,這項功能由 ContextualLogging 功能閘道控制,並且預設為啟用。此功能的基礎架構已在 1.24 版本中新增,而無需修改元件。component-base/logs/example 命令示範了如何使用新的日誌記錄呼叫,以及支援情境式日誌記錄的元件的行為。

$ cd $GOPATH/src/k8s.io/kubernetes/staging/src/k8s.io/component-base/logs/example/cmd/
$ go run . --help
...
      --feature-gates mapStringBool  A set of key=value pairs that describe feature gates for alpha/experimental features. Options are:
                                     AllAlpha=true|false (ALPHA - default=false)
                                     AllBeta=true|false (BETA - default=false)
                                     ContextualLogging=true|false (BETA - default=true)
$ go run . --feature-gates ContextualLogging=true
...
I0222 15:13:31.645988  197901 example.go:54] "runtime" logger="example.myname" foo="bar" duration="1m0s"
I0222 15:13:31.646007  197901 example.go:55] "another runtime" logger="example" foo="bar" duration="1h0m0s" duration="1m0s"

logger 鍵和 foo="bar" 是由呼叫記錄 runtime 訊息和 duration="1m0s" 值的函數的呼叫者新增的,而無需修改該函數。

在停用情境式日誌記錄的情況下,WithValuesWithName 不執行任何操作,並且日誌呼叫會通過全域 klog 日誌記錄器。因此,此額外資訊不再包含在日誌輸出中

$ go run . --feature-gates ContextualLogging=false
...
I0222 15:14:40.497333  198174 example.go:54] "runtime" duration="1m0s"
I0222 15:14:40.497346  198174 example.go:55] "another runtime" duration="1h0m0s" duration="1m0s"

JSON 日誌格式

功能狀態: Kubernetes v1.19 [alpha]

--logging-format=json 標誌將日誌格式從 klog 原生格式變更為 JSON 格式。JSON 日誌格式範例(美化列印)

{
   "ts": 1580306777.04728,
   "v": 4,
   "msg": "Pod status updated",
   "pod":{
      "name": "nginx-1",
      "namespace": "default"
   },
   "status": "ready"
}

具有特殊含義的鍵

  • ts - 時間戳記,以 Unix 時間表示(必要,浮點數)
  • v - 詳細程度(僅適用於資訊訊息,不適用於錯誤訊息,整數)
  • err - 錯誤字串(選用,字串)
  • msg - 訊息(必要,字串)

目前支援 JSON 格式的元件列表

日誌詳細程度層級

-v 標誌控制日誌詳細程度。增加該值會增加記錄的事件數量。減少該值會減少記錄的事件數量。增加詳細程度設定會記錄越來越不嚴重的事件。詳細程度設定為 0 時,僅記錄嚴重事件。

日誌位置

系統元件有兩種型別:在容器中執行的元件和不在容器中執行的元件。例如

  • Kubernetes 排程器和 kube-proxy 在容器中執行。
  • kubelet 和 容器執行期 不在容器中執行。

在具有 systemd 的機器上,kubelet 和容器執行期會寫入 journald。否則,它們會寫入 /var/log 目錄中的 .log 檔案。容器內的系統元件始終寫入 /var/log 目錄中的 .log 檔案,繞過預設的日誌記錄機制。與容器日誌類似,您應該輪換 /var/log 目錄中的系統元件日誌。在 kube-up.sh 腳本建立的 Kubernetes 叢集中,日誌輪換由 logrotate 工具配置。logrotate 工具每天輪換日誌,或在日誌大小超過 100MB 時輪換日誌。

日誌查詢

功能狀態: Kubernetes v1.30 [beta] (預設為停用:false)

為了幫助偵錯節點上的問題,Kubernetes v1.27 引入了一項功能,允許檢視在節點上執行的服務的日誌。若要使用此功能,請確保為該節點啟用 NodeLogQuery 功能閘道,並且 kubelet 配置選項 enableSystemLogHandlerenableSystemLogQuery 都設定為 true。在 Linux 上,假設服務日誌可通過 journald 取得。在 Windows 上,假設服務日誌可在應用程式日誌提供者中取得。在兩個作業系統上,也可以通過讀取 /var/log/ 中的檔案來取得日誌。

如果您已獲得與節點物件互動的授權,則可以在所有節點或僅在子集中試用此功能。以下是從節點檢索 kubelet 服務日誌的範例

# Fetch kubelet logs from a node named node-1.example
kubectl get --raw "/api/v1/nodes/node-1.example/proxy/logs/?query=kubelet"

您也可以擷取檔案,前提是這些檔案位於 kubelet 允許日誌擷取的目錄中。例如,您可以從 Linux 節點上的 /var/log 擷取日誌

kubectl get --raw "/api/v1/nodes/<insert-node-name-here>/proxy/logs/?query=/<insert-log-file-name-here>"

kubelet 使用啟發式方法來檢索日誌。如果您不清楚給定的系統服務是否正在將日誌寫入作業系統的原生日誌記錄器(如 journald)或 /var/log/ 中的日誌檔案,這會很有幫助。啟發式方法首先檢查原生日誌記錄器,如果不可用,則嘗試從 /var/log/<servicename>/var/log/<servicename>.log/var/log/<servicename>/<servicename>.log 檢索第一個日誌。

可以使用的完整選項列表如下

選項描述
bootboot 顯示來自特定系統啟動的消息
patternpattern 通過提供的 PERL 相容的正規表示式篩選日誌條目
queryquery 指定要從中返回日誌的服務或檔案(必要)
sinceTime一個 RFC3339 時間戳記,從該時間開始顯示日誌(包含)
untilTime一個 RFC3339 時間戳記,到該時間為止顯示日誌(包含)
tailLines指定要從日誌末尾檢索多少行;預設值是擷取整個日誌

更複雜查詢的範例

# Fetch kubelet logs from a node named node-1.example that have the word "error"
kubectl get --raw "/api/v1/nodes/node-1.example/proxy/logs/?query=kubelet&pattern=error"

下一步

上次修改時間:2024 年 2 月 22 日下午 3:16 PST:情境式日誌記錄:文件升級為 beta 版 (4f0dc7ad36)