系統日誌
系統組件日誌記錄叢集中發生的事件,這對於除錯非常有用。您可以組態日誌詳細程度以查看更多或更少的細節。日誌可以粗略到顯示組件內的錯誤,或者精細到顯示事件的逐步追蹤(例如 HTTP 訪問日誌、pod 狀態變更、控制器動作或排程器決策)。
警告
與此處描述的命令列標記相反,日誌輸出本身不屬於 Kubernetes API 穩定性保證的範圍:個別日誌條目及其格式可能會在不同版本之間變更!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,寫入 stdout | 2>&1 | kube-log-runner (預設行為) |
將兩者重定向到日誌檔案 | 1>>/tmp/log 2>&1 | kube-log-runner -log-file=/tmp/log |
複製到日誌檔案和 stdout | 2>&1 | tee -a /tmp/log | kube-log-runner -log-file=/tmp/log -also-stdout |
僅將 stdout 重定向到日誌檔案 | >/tmp/log | kube-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中所述。
如果開發人員在其元件中使用 WithValues
或 WithName
等其他函數,則日誌條目將包含由呼叫者傳遞到函數中的其他資訊。
對於 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"
值的函數的呼叫者新增的,而無需修改該函數。
在停用情境式日誌記錄的情況下,WithValues
和 WithName
不執行任何操作,並且日誌呼叫會通過全域 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]
警告
JSON 輸出不支援許多標準 klog 標誌。如需不支援的 klog 標誌列表,請參閱命令列工具參考。
並非所有日誌都保證以 JSON 格式寫入(例如,在程序啟動期間)。如果您打算解析日誌,請確保您也可以處理非 JSON 格式的日誌行。
欄位名稱和 JSON 序列化可能會變更。
--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 配置選項 enableSystemLogHandler
和 enableSystemLogQuery
都設定為 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
檢索第一個日誌。
可以使用的完整選項列表如下
選項 | 描述 |
---|---|
boot | boot 顯示來自特定系統啟動的消息 |
pattern | pattern 通過提供的 PERL 相容的正規表示式篩選日誌條目 |
query | query 指定要從中返回日誌的服務或檔案(必要) |
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"
下一步
- 閱讀關於 Kubernetes 日誌記錄架構 的資訊
- 閱讀關於 結構化日誌記錄 的資訊
- 閱讀關於 情境式日誌記錄 的資訊
- 閱讀關於 棄用 klog 專用標誌 的資訊
- 閱讀關於 日誌記錄嚴重性慣例 的資訊
- 閱讀關於 日誌查詢 的資訊