獲取 Kubernetes 中 Pod 的連續日誌流
1. 概述
Kubernetes 中的日誌流對於容器化環境中運行的應用程序的監控和故障排除至關重要。它提供對 Pod 內容器生成的日誌的實時訪問。
在本文中,我們將學習如何使用kubectl logs
命令從 Kubernetes pod 獲取連續的日誌流。
2. 理解場景
讓我們從使用ubuntu
映像並每分鐘打印一條消息的 pod 的ubuntu-pod.yaml
配置文件開始:
$ cat ubuntu-pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: ubuntu-pod
spec:
containers:
- name: ubuntu-container
image: ubuntu
command: ["bash", "-c", "while true; do echo 'running ...' && sleep 60 done"]
我們可以看到command
屬性中指定了一個無限while
循環。因此, pod 應該永遠保持運行狀態,同時每分鐘記錄一條消息。
現在,讓我們使用kubectl apply
命令從我們的配置文件創建ubuntu-pod
:
$ kubectl apply -f ubuntu-pod.yaml
pod/ubuntu-pod created
此外,我們可以驗證 pod 確實已啟動並正在運行:
$ kubectl get pods --field-selector metadata.name=ubuntu-pod
NAME READY STATUS RESTARTS AGE
ubuntu-pod 1/1 Running 0 3m7s
最後,讓我們使用kubectl logs
命令來檢查ubuntu-pod
日誌:
$ kubectl logs ubuntu-pod
running ...
running ...
running ...
running ...
running ...
$
偉大的!我們可以在控制台上看到到目前為止生成的日誌消息。之後,控制權轉移到命令提示符( $
),我們不再看到日誌流。但是,如果我們正在排除問題,實時日誌流可以反映應用程序的最新狀態並有助於有效監控。
因此,讓我們開始學習可用於從 Pod 獲取日誌流的技術。
3. 使用–follow
選項流式傳輸日誌
讓我們使用 kubectl logs 命令的 –follow 選項來查看來自ubuntu-pod
kubectl logs
–follow
流:
$ kubectl logs --follow ubuntu-pod
running ...
running ...
running ...
running ...
running ...
running ...
running ...
有趣的是,這種方法不會將控制權轉移到命令提示符( $
)。因此,讓我們等待一分鐘,看看控制台上彈出下一條消息:
running ...
極好的!正如預期的那樣,出現了一條新的日誌消息。這是因為我們的 Pod 每分鐘都會生成日誌消息。
儘管如此,關於 Kubernetes 中的流日誌還有很多東西需要了解。那麼,讓我們準備好深入探討這一點。
4.豐富日誌流
在本節中,我們將學習如何使用kubectl logs
命令提供的選項通過元數據豐富日誌流消息。
4.1.帶時間戳
了解日誌消息的時間戳可能是除了消息本身之外最重要的細節。 kubectl logs
命令提供了–timestamps
選項,我們可以使用它在消息的開頭附加時間戳。
讓我們看看在 Kubernetes 集群中運行的ubuntu-pod
的實際情況:
$ kubectl logs --follow --timestamps ubuntu-pod
2023-07-30T03:09:49.368021900Z running ...
2023-07-30T03:10:49.368683774Z running ...
2023-07-30T03:11:49.370931509Z running ...
我們可以注意到消息與時間戳詳細信息一起顯示。此外,我們必須記住時間戳採用RFC3339格式。
現在,每當我們的流中彈出一條新消息時,由於日誌行中的保證發生變化,它很容易被注意到:
2023-07-30T03:12:49.372825176Z running ...
精彩的!我們的日誌流現在看起來更有用。
4.2.有源
添加到日誌流中的另一個有用的詳細信息是其來源。幸運的是, kubectl logs
命令也通過它的–prefix
選項為我們提供了這裡的內容。
讓我們繼續前進並使用–prefix
選項通過日誌消息源來豐富我們的流:
$ kubectl logs --follow --prefix ubuntu-pod
[pod/ubuntu-pod/ubuntu-container] running ...
[pod/ubuntu-pod/ubuntu-container] running ...
正如預期的那樣,我們可以注意到我們的流顯示了每個日誌行的 pod 名稱 ( ubuntu-pod
) 和容器名稱 ( ubuntu-container
)。有了這些信息,我們就可以追踪每個日誌行的正確來源。
5. 按大小限制日誌流
在我們的場景中,我們添加了一條相當簡單的日誌消息,並且任意兩條日誌消息之間有足夠的延遲。然而,對於解決實際業務需求的應用程序,應用程序可能會以更高的頻率記錄更長的消息。那麼,讓我們學習如何通過日誌的大小來限制流。
5.1.使用–tail
選項
當我們使用–follow
選項從正在運行的 pod 獲取日誌流時,Kubernetes 首先顯示歷史日誌消息。顯示所有消息後,我們可以看到近乎實時的實時日誌流。但是,如果 Pod 運行多天或在短時間內生成大量日誌事件,這種行為可能會增加噪音。
對於這種情況,我們可以使用–tail
選項將歷史日誌行的大小限制為固定數量。因此,我們應該更快地看到我們的日誌流。
讓我們用來自ubuntu-pod
pod 的日誌流來驗證我們的理解:
$ date
Sun Jul 30 03:19:14 AM UTC 2023
$ kubectl logs --follow --timestamps --tail 2 ubuntu-pod
2023-07-30T03:17:49.383687361Z running ...
2023-07-30T03:18:49.386528064Z running ...
它按預期工作。在輸出中,我們可以看到只顯示了過去的兩條日誌行。
5.2.使用–limit-bytes
選項
日誌大小是我們可以考慮限制日誌流大小的另一個標準。為此,我們可以將–limit-bytes
選項與kubectl logs
命令一起使用。
讓我們首先通過將1
字節的值傳遞給–limit-bytes
選項來檢查日誌流中顯示的每個字節有多少個字符:
$ kubectl logs --follow --limit-bytes 1 ubuntu-pod
r
$
我們可以看到,在這種情況下,一個字節對應一個字符。
由於在我們的場景中,每個日誌行都有11
字符,因此值得通過將11
字節傳遞給–limit-bytes
選項來驗證這一點:
$ kubectl logs --follow --limit-bytes 11 ubuntu-pod
running ...
$
完美的!我們已經驗證了我們的理解。然而,我們必須注意到,在這兩種情況下,控制權都立即轉移到命令提示符( $
)。這是因為**–limit-bytes
選項適用於整個日誌流,而不僅僅是歷史日誌**。
最後,讓我們使用–limit-bytes
選項傳遞500
字節來查看來自ubuntu-pod
日誌流:
$ kubectl logs --follow --limit-bytes 500 ubuntu-pod
running ...
running ...
running ...
running ...
running ...
running ...
running ...
running ...
running ...
running ...
running ...
running ...
running ...
running ...
在這種情況下,值得注意的是,流一旦達到500
字符就會關閉。
6. 按時間限制日誌流
在本節中,讓我們看看如何使用基於時間的選項(例如–since
和–since-time
來限制日誌流。
6.1.使用–since
選項
我們可以使用–since
選項指定持續時間,將歷史日誌行限制為過去的特定時間。
讓我們首先將300s
( 300
秒)傳遞給–since
選項,並查看來自ubuntu-pod
的日誌流:
$ date
Sun Jul 30 03:28:51 AM UTC 2023
$ kubectl logs --follow --timestamps --since 300s ubuntu-pod
2023-07-30T03:24:49.398533266Z running ...
2023-07-30T03:25:49.401017157Z running ...
2023-07-30T03:26:49.402346354Z running ...
2023-07-30T03:27:49.404715543Z running ...
2023-07-30T03:28:49.407544746Z running ...
我們可以注意到,日誌流中只顯示了過去的 5 行日誌。這是因為我們的應用程序每分鐘記錄一次,計算起來300
秒內記錄了5
次。
此外,我們還可以以分鐘為單位傳遞持續時間。讓我們通過使用–since
選項傳遞2m
來驗證這一點:
$ date
Sun Jul 30 03:29:53 AM UTC 2023
$ kubectl logs --follow --timestamps --since 2m ubuntu-pod
2023-07-30T03:28:49.407544746Z running ...
2023-07-30T03:29:49.409491441Z running ...
結果看起來是正確的。
接下來,讓我們使用–since
選項傳遞0.05h
(3 分鐘),以確認我們甚至可以傳遞小數參數:
$ date
Sun Jul 30 03:31:43 AM UTC 2023
$ kubectl logs --follow --timestamps --since 0.05h ubuntu-pod
2023-07-30T03:28:49.407544746Z running ...
2023-07-30T03:29:49.409491441Z running ...
2023-07-30T03:30:49.411283477Z running ...
最後,讓我們看一個有趣的場景,其中我們使用–since
選項傳遞2m120s
:
$ date
Sun Jul 30 03:30:36 AM UTC 2023
$ kubectl logs --follow --timestamps --since 2m120s ubuntu-pod
2023-07-30T03:26:49.402346354Z running ...
2023-07-30T03:27:49.404715543Z running ...
2023-07-30T03:28:49.407544746Z running ...
2023-07-30T03:29:49.409491441Z running ...
我們可以注意到流中出現了四個日誌行。它幫助我們理解總持續時間是通過添加所有單獨的持續時間來計算的,並且不會根據時間單位的優先級排除任何內容。
6.2.使用–since-time
選項
如果我們想限制日誌流僅顯示特定時間戳之後的消息,我們可以使用-since-time
選項。
讓我們檢查當前時間並使用–since-time
選項傳遞過去幾分鐘的時間戳:
$ date
Sun Jul 30 03:35:47 AM UTC 2023
$ kubectl logs --follow --timestamps --since-time 2023-07-30T03:30:00.000000000Z ubuntu-pod
2023-07-30T03:30:49.411283477Z running ...
2023-07-30T03:31:49.414355691Z running ...
2023-07-30T03:32:49.416516375Z running ...
2023-07-30T03:33:49.418557475Z running ...
2023-07-30T03:34:49.420578582Z running ...
它工作得很好。由於我們傳遞了過去5
分鐘的時間戳,因此我們只能看到 5 個歷史日誌行,因為應用程序每分鐘記錄一條消息。
此外,如果我們傳遞未來的時間戳,我們的日誌流將不會顯示任何內容,直到時間正確:
$ kubectl logs --follow --timestamps --since-time 2024-07-30T03:30:00.000000000Z ubuntu-pod
因此,如果我們想在獲取日誌流之前等待特定時間,我們可以使用這種行為。
7. 多個容器的流式日誌
在本節中,我們將學習如何從內部有多個容器的 Pod 流式傳輸日誌。
7.1.設置
首先,讓我們編寫 pod 配置,使其定義多個容器,即ubuntu-container-1
和ubuntu-container-2
:
$ cat ubuntu-multi-containers.yaml
apiVersion: v1
kind: Pod
metadata:
name: ubuntu-pod-multi-containers
spec:
containers:
- name: ubuntu-container-1
image: ubuntu
command: ["bash", "-c", "while true; do echo 'running container-1...' && sleep 60; done"]
- name: ubuntu-container-2
image: ubuntu
command: ["bash", "-c", "while true; do echo 'running container-2...' && sleep 60; done"]
接下來,讓我們應用此配置來創建包含多個容器的 pod:
$ kubectl apply -f ubuntu-multi-containers.yaml
pod/ubuntu-pod-multi-containers created
此外,我們可以驗證 Pod 是否已啟動並正在運行,並且2/2
容器是否已READY
:
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
ubuntu-pod-multi-containers 2/2 Running 0 58s
最後,讓我們看看是否可以使用現有的方法來查看 pod 中的日誌:
$ kubectl logs --follow ubuntu-pod-multi-containers
Defaulted container "ubuntu-container-1" out of: ubuntu-container-1, ubuntu-container-2
running container-1...
running container-1...
雖然我們可以看到日誌流,但它來自單個容器。
7.2.從特定容器流式傳輸
我們可以使用–container
選項來傳遞容器名稱。讓我們使用它來顯式地從ubuntu-container-2
容器獲取日誌流:
$ kubectl logs --follow ubuntu-pod-multi-containers --container ubuntu-container-2
running container-2...
running container-2...
看起來我們已經做對了。
7.3.所有集裝箱
如果我們通過多次傳遞–container
選項來指定多個容器名稱,我們將從列表中的最後一個容器獲取日誌流。讓我們驗證一下這個行為:
$ kubectl logs -f ubuntu-pod-multi-containers --container ubuntu-container-1 --container ubuntu-container-2
running container-2...
running container-2...
對於我們想要從 pod 內運行的所有容器獲取日誌的場景,我們可以傳遞–all-containers
選項:
$ kubectl logs -f ubuntu-pod-multi-containers --all-containers
running container-2...
running container-2...
running container-1...
running container-1...
極好的!我們已經搞定了這一點。
8. 部署 Pod 的流式傳輸日誌
在本節中,我們將學習如何從使用 Kubernetes 部署資源管理的 Pod 中傳輸日誌。
8.1.設置
首先,讓我們看一下部署資源的ubuntu-deployment.yaml
配置:
$ cat ubuntu-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: ubuntu-deployment
spec:
replicas: 3
selector:
matchLabels:
app: ubuntu-app
template:
metadata:
labels:
app: ubuntu-app
spec:
containers:
- name: ubuntu-container
image: ubuntu
command: ["bash", "-c", "while true; do echo $(hostname)' is running ...' && sleep 60; done"]
現在,讓我們apply
配置來創建ubuntu-deployment
部署:
$ kubectl apply -f ubuntu-deployment.yaml
deployment.apps/ubuntu-deployment created
最後,讓我們驗證 pod 是否已啟動並正在運行:
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
ubuntu-deployment-7ffd5967d-m2h59 1/1 Running 0 25s
ubuntu-deployment-7ffd5967d-trdv6 1/1 Running 0 25s
ubuntu-deployment-7ffd5967d-zpvxg 1/1 Running 0 25s
我們可以看到 Pod 的名稱有一個動態後綴。因此,雖然我們可以通過傳遞各個 Pod 的名稱來流式傳輸日誌,但這有點不方便。
8.2.按標籤流式傳輸日誌
我們在部署配置中使用ubuntu-app
值定義了app
程序標籤。因此,所有由ubuntu-deployment
管理的 Pod 都有這個標籤。
現在,如果我們想要流式傳輸部署中所有 Pod 的日誌,我們可以使用-l
選項傳遞標籤查詢:
$ kubectl logs -f -l app=ubuntu-app
ubuntu-deployment-7ffd5967d-m2h59 is running ...
ubuntu-deployment-7ffd5967d-trdv6 is running ...
ubuntu-deployment-7ffd5967d-zpvxg is running ...
ubuntu-deployment-7ffd5967d-zpvxg is running ...
ubuntu-deployment-7ffd5967d-trdv6 is running ...
ubuntu-deployment-7ffd5967d-m2h59 is running ...
偉大的!我們可以看到日誌流包含來自所有三個 Pod 的日誌行。
9. 結論
在本文中,我們學習瞭如何使用kubectl logs
命令的–follow
選項從 Kubernetes 集群中運行的 pod 獲取連續的日誌流。此外,我們還探索了多個其他選項,例如timestamps
、 prefix
、 since
、 since-time
、 limit-bytes
等來微調日誌。
最後,我們學習瞭如何流式傳輸特定容器、Pod 中的所有容器或部署管理的所有 Pod 的日誌。