antony@notes:~/kubernetes$ cat "Logging-Operator.md"
Logging Operator
Logging Operator — Kubernetes 日誌管理解決方案
Preface
本篇文章會先介紹什麼是 Logging Operator,並透過 Rancher Logging 實作將 Pod Log 導入 OpenSearch
簡介
Logging Operator 是一套專為 Kubernetes 環境設計的日誌管理工具。它能夠自動部署與設定完整的日誌收集流程(logging pipeline),讓你不必手動處理繁瑣的日誌基礎設施配置。
運作流程
Logging Operator 的日誌處理分為三個階段:
1. 日誌收集(Log Collector)
Operator 會在 Kubernetes 叢集中的每個節點上部署一個 Fluent Bit DaemonSet,負責從節點的檔案系統中收集 App Containers 和應用程式的日誌。
2. 中繼資料 enrichment(Metadata Enrichment)
Fluent Bit 會查詢 Kubernetes API,為日誌附加 Pod 的相關中繼資料(metadata),例如 Pod 名稱、namespace、標籤等。接著,將日誌連同這些中繼資料一併傳送給日誌轉發器(Log Forwarder)。
3. 日誌轉發(Log Forwarding)
日誌轉發器負責接收、過濾與轉換傳入的日誌,並將處理完的結果傳送到一個或多個目的地輸出(destination outputs)。
目前支援的日誌轉發器有兩種:
| 轉發器 | 說明 |
|---|---|
| Fluentd | 廣泛使用的開源日誌轉發工具 |
| syslog-ng(透過 AxoSyslog 發行版) | 高效能的系統日誌處理引擎 |

安全性
所有日誌的傳輸皆透過經過驗證(authenticated)且加密(encrypted)的通道進行,確保資料在傳輸過程中的安全性。
核心優勢
Logging Operator 最大的特色在於:你可以將日誌的行為描述直接定義在應用程式的 Helm Chart 中,Operator 會自動完成其餘的部署與配置工作。
換句話說,日誌設定可以隨著應用程式一起版本控制與部署,實現基礎設施即程式碼(Infrastructure as Code)的理念。
功能特色
Logging Operator 提供以下核心功能:
- Namespace 隔離:日誌流(flow)與輸出(output)可以限定在特定的 namespace 中運作,實現多租戶隔離。
- 原生 Kubernetes Label Selector:直接使用 Kubernetes 原生的標籤選擇器來篩選要收集的日誌來源。
- 安全通訊(TLS):所有日誌傳輸皆支援 TLS 加密,確保資料安全。
- 設定檔驗證:自動驗證設定是否正確,降低配置錯誤的風險。
- 多重 Flow 支援:同一份日誌可以經由多條 flow 進行不同的過濾與轉換處理。
- 多重 Output 支援:同一份日誌可以同時傳送到多個儲存目的地,例如 S3、GCS、Elasticsearch、Loki 等。
- 多重 Logging 系統支援:在同一個叢集中可以部署多套 Fluentd 與 Fluent Bit 實例,滿足不同的日誌需求。
- 雙轉發器引擎:同時支援 syslog-ng 與 Fluentd 作為核心日誌路由元件。
架構概覽
Logging Operator 管理日誌基礎設施中的三個核心角色:日誌收集器(Log Collector)、日誌轉發器(Log Forwarder),以及定義日誌該送往何處的路由規則。
日誌收集器(Log Collector)
- 部署在每個 Kubernetes 節點上的端點代理程式(endpoint agent)。
- 負責收集該節點上所有 App Container 的日誌,並傳送給日誌轉發器。
- 目前使用 Fluent Bit 作為日誌收集器。
日誌轉發器(Log Forwarder / Log Aggregator)
- 接收來自收集器的日誌後,進行過濾(filter)與轉換(transform)。
- 將處理後的日誌傳送到一個或多個目的地輸出。
- 支援兩種轉發器引擎:
| 轉發器 | 適用場景 |
|---|---|
| Fluentd | 生態系成熟、外掛豐富,適合大多數使用情境 |
| syslog-ng | 高效能、低資源消耗,適合需要進階日誌處理邏輯的場景 |
如何選擇適合的轉發器,可參考官方文件 Which log forwarder to use。
路由規則(Flow & Output)
你可以透過 Flow 自訂資源來過濾、處理日誌訊息,並將它們路由到適當的 Output(目的地),例如 Elasticsearch 或 Amazon S3。
除了 namespace 層級的 flow 與 output,你也可以定義叢集層級的 ClusterFlow 與 ClusterOutput,讓所有 namespace 的使用者都能引用同一組集中式輸出,但無法修改其設定。
注意: Flow 與 Output 資源是依據你選用的轉發器類型(Fluentd 或 syslog-ng)而不同的,兩者的 CRD 不能混用。
Custom Resource Definitions(CRD)一覽
共用資源
| CRD | 說明 | 作用範圍 |
|---|---|---|
| logging | 定義叢集的日誌基礎設施,包含日誌收集器與轉發器的設定。也可包含 Fluent Bit、Fluentd、syslog-ng 的配置。自 4.5 版起,這些元件也可作為獨立資源分開設定。 | 叢集層級 |
Fluentd 專用 CRD
| CRD | 說明 | 作用範圍 |
|---|---|---|
| output | 定義 Fluentd 的日誌輸出目的地。 | Namespace |
| flow | 定義 Fluentd 的日誌路由規則,使用 filter 與 output 將選定的日誌導向指定目的地。 | Namespace |
| clusteroutput | 定義可供所有 flow 與 clusterflow 使用的 Fluentd 輸出。預設僅在 controlNamespace 中生效,除非設定 allowClusterResourcesFromAllNamespaces: true。 | 叢集層級 |
| clusterflow | 定義可從所有 namespace 收集日誌的 Fluentd 路由規則。預設僅在 controlNamespace 中生效,除非設定 allowClusterResourcesFromAllNamespaces: true。 | 叢集層級 |
syslog-ng 專用 CRD
| CRD | 說明 | 作用範圍 |
|---|---|---|
| SyslogNGOutput | 定義 syslog-ng 的日誌輸出目的地。 | Namespace |
| SyslogNGFlow | 定義 syslog-ng 的日誌路由規則,使用 filter 與 output 將選定的日誌導向指定目的地。 | Namespace |
| SyslogNGClusterOutput | 定義可供所有 flow 與 clusterflow 使用的 syslog-ng 輸出。預設僅在 controlNamespace 中生效,除非設定 allowClusterResourcesFromAllNamespaces: true。 | 叢集層級 |
| SyslogNGClusterFlow | 定義可從所有 namespace 收集日誌的 syslog-ng 路由規則。預設僅在 controlNamespace 中生效,除非設定 allowClusterResourcesFromAllNamespaces: true。 | 叢集層級 |
Fluentd 與 syslog-ng 的 CRD 結構相似,但各自針對自身引擎的特性進行了調整。選用哪一組 CRD 取決於你在
logging資源中選擇的轉發器類型。
Rancher Logging — 將 Pod Log 導入 OpenSearch 實作指南
環境概述
Rancher 的日誌管理由 Logging operator 提供支持。 以下實作將透過 Rancher logging,將指定 Kubernetes Pod 的 stdout log 經由 Fluentd 轉送至外部 OpenSearch。
環境準備
- Rancher 安裝 DownStream RKE2 Cluster
- DownStream RKE2 Cluster 已安裝 Rancher Logging
- 在 DownStream RKE2 Cluster 外部已安裝好 opensearch
步驟一:建立 Namespace
kubectl create ns app步驟二:部署測試用 Pod
建立一個每秒輸出一行遞增計數 log 的 Pod,用以驗證 log pipeline 是否正常運作。
cat <<'EOF' | kubectl apply -f -
apiVersion: v1
kind: Pod
metadata:
name: test-logging-pod
namespace: app
labels:
logging-test: "true"
spec:
automountServiceAccountToken: false
securityContext:
runAsNonRoot: true
runAsUser: 1000
runAsGroup: 1000
seccompProfile:
type: RuntimeDefault
containers:
- name: sak
image: rancherlabs/swiss-army-knife:latest
command: ["/bin/sh"]
args:
- -c
- |
i=0; while true; do echo "$(date) INFO $i"; i=$((i+1)); sleep 1; done
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities:
drop:
- ALL
EOF確認 Pod 已正常啟動:
kubectl -n app get pods -l logging-test=true預期輸出:
NAME READY STATUS RESTARTS AGE
test-logging-pod 1/1 Running 0 5s確認 log 輸出正常:
kubectl -n app logs test-logging-pod預期輸出(每秒遞增一行):
Mon Mar 16 07:43:57 UTC 2026 INFO 0
Mon Mar 16 07:43:58 UTC 2026 INFO 1
Mon Mar 16 07:43:59 UTC 2026 INFO 2
...步驟三:建立 OpenSearch 認證 Secret
將 OpenSearch 的帳號密碼以 kubernetes.io/basic-auth 類型的 Secret 儲存於叢集中,供後續 Output CR 引用。
PW='Test12345@'
kubectl create secret generic opensearch-user-auth \
--namespace=app \
--type=kubernetes.io/basic-auth \
--from-literal=username=admin \
--from-literal=password=$PW步驟四:建立 Logging Output CR
定義 Fluentd 將 log 發送至 OpenSearch 的目標端點與 buffer 策略。
cat <<'EOF' | kubectl apply -f -
apiVersion: logging.banzaicloud.io/v1beta1
kind: Output
metadata:
name: opensearch-admin
namespace: app
spec:
opensearch:
host: opensearch-node.kubeantony.com
port: 9200
scheme: https
ssl_verify: false
ssl_version: TLSv1_2
suppress_type_name: true
user: admin
password:
valueFrom:
secretKeyRef:
key: password
name: opensearch-user-auth
buffer:
flush_interval: 10s
flush_mode: interval
retry_type: exponential_backoff
retry_forever: true
chunk_limit_size: 8MB
total_limit_size: 512MB
EOFBuffer 參數說明
| 參數 | 值 | 說明 |
|---|---|---|
flush_mode | interval | 以固定時間間隔觸發 flush,在即時性與效能間取得平衡 |
flush_interval | 10s | 每 10 秒將累積的 log 批次送出 |
chunk_limit_size | 8MB | 單一 chunk 上限;達到後即使未到 flush 時間也會送出,防止記憶體暴漲 |
total_limit_size | 512MB | 所有 buffer 佔用的磁碟空間上限;超過後新 log 將依 overflow_action 處理 |
retry_type | exponential_backoff | 發送失敗時以指數退避策略重試(1s → 2s → 4s → …),避免對 OpenSearch 造成衝擊 |
retry_forever | true | 無限重試直到成功,確保 log 不遺失(代價是 buffer 可能在長時間故障時被填滿) |
確認 Output 資源已建立(此時 ACTIVE 為 false 是正常的,表示尚未被任何 Flow 引用):
kubectl -n app get outputs.logging.banzaicloud.io預期輸出:
NAME ACTIVE PROBLEMS
opensearch-admin false步驟五:建立 Logging Flow CR
建立 Flow 將帶有 logging-test: "true" label 的 Pod log 路由至上一步定義的 Output。
cat <<'EOF' | kubectl apply -f -
apiVersion: logging.banzaicloud.io/v1beta1
kind: Flow
metadata:
name: app-to-opensearch
namespace: app
spec:
match:
- select:
labels:
logging-test: "true"
localOutputRefs:
- opensearch-admin
EOF確認 Flow 已啟用:
kubectl -n app get flows.logging.banzaicloud.io預期輸出:
NAME ACTIVE PROBLEMS
app-to-opensearch true步驟六:於 OpenSearch 驗證 Log 寫入
確認索引已建立
於 OpenSearch Dashboards 左上角選單進入 Index Management → Indexes,搜尋 fluentd,應可看到對應索引已自動建立。

查詢最新 Log
於 Dev Tools 執行以下查詢,取得最近 3 筆 log:
GET fluentd/_search
{
"size": 3,
"sort": [{ "time": { "order": "desc" }}],
"query": {
"match_all": {}
}
}回傳結果中,每筆文件的 _source 應包含 message(原始 log 訊息)、kubernetes(Pod metadata)、以及 time(時間戳記)等欄位,代表 log pipeline 已完整串通。

以下為其中一筆 log
{
"took": 1000,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 10000,
"relation": "gte"
},
"max_score": null,
"hits": [
{
"_index": "fluentd",
"_id": "q0239pwBR50SWBx4toac",
"_score": null,
"_source": {
"time": "2026-03-16T20:55:59.312256038+08:00",
"stream": "stdout",
"logtag": "F",
"message": "Mon Mar 16 12:55:59 UTC 2026 INFO 9961",
"kubernetes": {
"pod_name": "test-logging-pod",
"namespace_name": "app",
"pod_id": "50148584-185c-475c-b203-4120526c755d",
"labels": {
"logging-test": "true"
},
"annotations": {
"kubectl.kubernetes.io/last-applied-configuration": """{"apiVersion":"v1","kind":"Pod","metadata":{"annotations":{},"labels":{"logging-test":"true"},"name":"test-logging-pod","namespace":"app"},"spec":{"automountServiceAccountToken":false,"containers":[{"args":["-c","i=0; while true; do echo \"$(date) INFO $i\"; i=$((i+1)); sleep 1; done\n"],"command":["/bin/sh"],"image":"rancherlabs/swiss-army-knife:latest","name":"sak","securityContext":{"allowPrivilegeEscalation":false,"capabilities":{"drop":["ALL"]},"readOnlyRootFilesystem":true}}],"securityContext":{"runAsGroup":1000,"runAsNonRoot":true,"runAsUser":1000,"seccompProfile":{"type":"RuntimeDefault"}}}}
"""
},
"host": "rke2-w2",
"container_name": "sak",
"docker_id": "d820db7b9416cde0b968f2e2fa314e74d656a064def3ecc183b7768bef65102a",
"container_hash": "docker.io/rancherlabs/swiss-army-knife@sha256:af25a3ace6269adb9e494b693644bc2f897ec872076d78f78bc5ded69f2ee222",
"container_image": "docker.io/rancherlabs/swiss-army-knife:latest"
},
"kubernetes_namespace": {
"name": "app",
"labels": {
"field.cattle.io/projectId": "p-pzhk7",
"kubernetes.io/metadata.name": "app"
}
}
},
"sort": [
1773665759312
]
}
]
}
}log 架構說明
以下逐層說明這個 OpenSearch 查詢回應的結構:

第一層:查詢執行資訊
took 表示 OpenSearch 花了 1000 毫秒完成這次查詢。timed_out: false 代表查詢在設定的超時限制內完成。_shards 記錄了參與查詢的分片狀態,這裡只有 1 個分片且執行成功、無失敗。
第二層:結果集合 hits
hits.total.value 為 10000,搭配 relation: "gte" 表示實際命中數量「大於或等於」10,000 筆,這是 OpenSearch 預設的計數上限(track_total_hits 未啟用精確計數時的行為)。max_score 為 null 是因為查詢使用了 sort 排序,此時相關性分數不會被計算。
第三層:單筆文件 hits.hits[]
每筆文件包含 _index(寫入的索引名稱,這裡是 fluentd)、_id(OpenSearch 自動產生的文件 ID)、以及 sort(排序欄位的原始值,此處為 time 的毫秒級 epoch)。
第四層:_source — Fluentd 寫入的原始資料
這是最核心的部分,由 Fluentd 的 Kubernetes metadata filter 自動附加:
time:log 產生的時間戳記(ISO 8601 格式,含時區)message:容器的原始 stdout 輸出內容stream:輸出流類型,stdout或stderrlogtag:CRI log 的完整性標記,F代表完整行(Full),P代表部分行(Partial,尚有後續)kubernetes:Pod 層級的元資料,包含 pod 名稱、namespace、pod ID、labels、annotations、所在節點(host)、容器名稱與 image 資訊kubernetes_namespace:Namespace 層級的元資料,包含名稱及其 labels(如 Rancher 的 projectId)
Rancher Logging — 將 Pod Log 導入 OpenSearch 實作指南 2
環境概述
以下實作將透過 Rancher logging,將指定 Kubernetes namespace 底下所有 Pods 的 log 經由 Fluentd 轉送至外部 logstash 再轉送到 opensearch。
環境準備
- Rancher 安裝 DownStream RKE2 Cluster
- DownStream RKE2 Cluster 已安裝 Rancher Logging
- 在 DownStream RKE2 Cluster 外部已安裝好 logstash
- 在 DownStream RKE2 Cluster 外部已安裝好 opensearch
開始實作
# Secret: CA 憑證
kubectl -n kube-system create secret generic logstash-ca \
--from-file=ca.crt=/etc/logstash/certs/ca.crt
# Secret: basic auth 帳密
kubectl -n kube-system create secret generic logstash-auth \
--from-literal=username=logstash \
--from-literal=password=logstash
cat <<'EOF' | kubectl apply -f -
apiVersion: logging.banzaicloud.io/v1beta1
kind: Output
metadata:
name: logstash-http
namespace: kube-system
spec:
apiVersion: logging.banzaicloud.io/v1beta1
kind: Output
metadata:
name: logstash-http
namespace: kube-system
spec:
http:
endpoint: "https://logstash.kubeantony.com:8080"
content_type: "application/json"
json_array: true
auth:
username:
valueFrom:
secretKeyRef:
name: logstash-auth
key: username
password:
valueFrom:
secretKeyRef:
name: logstash-auth
key: password
tls_ca_cert_path:
mountFrom:
secretKeyRef:
name: logstash-ca
key: ca.crt
buffer:
type: file
flush_interval: 5s
flush_mode: interval
timekey: 1m
timekey_wait: 10s
total_limit_size: 1GB
EOF
cat <<'EOF' | kubectl apply -f -
apiVersion: logging.banzaicloud.io/v1beta1
kind: Flow
metadata:
name: kube-logs
namespace: kube-system
spec:
match:
- select: {}
localOutputRefs:
- logstash-http
EOF確認索引已建立
於 OpenSearch Dashboards 左上角選單進入 Index Management → Indexes,搜尋 fluentd,應可看到對應索引已自動建立。

查詢最新 Log
於 Dev Tools 執行以下查詢,對日誌索引執行無條件檢索,並依時間戳(@timestamp)降序排列以提取最新的一筆數據紀錄:
GET opensearch-logstash-docker-2026.03.24/_search
{
"size": 1,
"query": {
"match_all": {}
},
"sort": [{"@timestamp": "desc"}]
}回傳結果中,每筆文件的 _source 應包含 message(原始 log 訊息)、kubernetes(Pod metadata)、以及 time(時間戳記)等欄位,代表 log pipeline 已完整串通。

以下為其中一筆 log
{
"took": 563,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 10000,
"relation": "gte"
},
"max_score": null,
"hits": [
{
"_index": "opensearch-logstash-docker-2026.03.24",
"_id": "ielEH50BXMB4tDz9Y0CX",
"_score": null,
"_source": {
"logtag": "F",
"message": "W0324 09:54:23.735867 1 logging.go:55] [core] [Channel #4240 SubChannel #4241]grpc: addrConn.createTransport failed to connect to {Addr: \"127.0.0.1:2379\", ServerName: \"127.0.0.1:2379\", BalancerAttributes: {\"<%!p(pickfirstleaf.managedByPickfirstKeyType={})>\": \"<%!p(bool=true)>\" }}. Err: connection error: desc = \"transport: Error while dialing: dial tcp 127.0.0.1:2379: operation was canceled\"",
"url": {
"domain": "logstash.kubeantony.com",
"path": "/",
"port": 8080
},
"kubernetes": {
"container_hash": "registry.rancher.com/rancher/hardened-kubernetes@sha256:4fab2ebc142aa1bb04a9641daebd6197404040806758cb3f3e78a6acfde47853",
"annotations": {
"kubernetes.io/config.mirror": "88a0909b75e7783678932b6535c63316",
"kubernetes.io/config.hash": "88a0909b75e7783678932b6535c63316",
"kubernetes.io/config.source": "file",
"kubernetes.io/config.seen": "2026-03-04T13:33:01.249775809+08:00"
},
"pod_name": "kube-apiserver-rke2-c2",
"container_image": "registry.rancher.com/rancher/hardened-kubernetes:v1.34.4-rke2r1-build20260210",
"labels": {
"tier": "control-plane",
"component": "kube-apiserver"
},
"host": "rke2-c2",
"container_name": "kube-apiserver",
"pod_id": "80dc734a-bbbc-48bc-a95f-ba88100ec24b",
"docker_id": "61c3121ba35fa4fa01f25037d1f27181d0b455cb350d196de37b55f13edb2444",
"namespace_name": "kube-system"
},
"@timestamp": "2026-03-24T09:54:28.785431836Z",
"user_agent": {
"original": "Ruby"
},
"http": {
"version": "HTTP/1.1",
"request": {
"body": {
"bytes": "1448"
},
"mime_type": "application/json"
},
"method": "POST"
},
"event": {
"original": """[{"time":"2026-03-24T17:54:23.73604561+08:00","stream":"stderr","logtag":"F","message":"W0324 09:54:23.735867 1 logging.go:55] [core] [Channel #4240 SubChannel #4241]grpc: addrConn.createTransport failed to connect to {Addr: \"127.0.0.1:2379\", ServerName: \"127.0.0.1:2379\", BalancerAttributes: {\"<%!p(pickfirstleaf.managedByPickfirstKeyType={})>\": \"<%!p(bool=true)>\" }}. Err: connection error: desc = \"transport: Error while dialing: dial tcp 127.0.0.1:2379: operation was canceled\"","kubernetes":{"pod_name":"kube-apiserver-rke2-c2","namespace_name":"kube-system","pod_id":"80dc734a-bbbc-48bc-a95f-ba88100ec24b","labels":{"component":"kube-apiserver","tier":"control-plane"},"annotations":{"kubernetes.io/config.hash":"88a0909b75e7783678932b6535c63316","kubernetes.io/config.mirror":"88a0909b75e7783678932b6535c63316","kubernetes.io/config.seen":"2026-03-04T13:33:01.249775809+08:00","kubernetes.io/config.source":"file"},"host":"rke2-c2","container_name":"kube-apiserver","docker_id":"61c3121ba35fa4fa01f25037d1f27181d0b455cb350d196de37b55f13edb2444","container_hash":"registry.rancher.com/rancher/hardened-kubernetes@sha256:4fab2ebc142aa1bb04a9641daebd6197404040806758cb3f3e78a6acfde47853","container_image":"registry.rancher.com/rancher/hardened-kubernetes:v1.34.4-rke2r1-build20260210"},"kubernetes_namespace":{"name":"kube-system","labels":{"field.cattle.io/projectId":"p-xnskv","kubernetes.io/metadata.name":"kube-system"}}}
]"""
},
"stream": "stderr",
"time": "2026-03-24T17:54:23.73604561+08:00",
"@version": "1",
"host": {
"ip": "192.168.11.156"
},
"kubernetes_namespace": {
"name": "kube-system",
"labels": {
"field.cattle.io/projectId": "p-xnskv",
"kubernetes.io/metadata.name": "kube-system"
}
}
},
"sort": [
1774346068785
]
}
]
}
}沒問題!我將根據您提供的架構,結合這份日誌的實際內容進行邏輯拆解與解釋。這份日誌記錄了 2026-03-24 某個 Kubernetes 核心組件發生連線異常的瞬間。
Log 架構邏輯說明
以下逐層說明這個 OpenSearch 查詢回應的結構:
第一層:查詢執行資訊 (Query Execution Info)
took: 表示 OpenSearch 花了 563 毫秒 完成這次查詢。timed_out: false: 代表查詢在設定的超時限制內順利完成。_shards: 記錄了參與查詢的分片狀態,這裡只有 1 個分片 且執行成功、無失敗,顯示索引結構較為簡單或資料量尚在單一分片承載範圍內。
第二層:結果集合 hits (Result Metadata)
hits.total.value: 10000 搭配relation: "gte": 表示實際命中數量「大於或等於」10,000 筆。這是 OpenSearch 為了查詢效能所做的預設優化(未開啟track_total_hits),告訴運維人員:符合條件的日誌非常多,這只是冰山一角。max_score: null: 因為我們在命令中使用了sort(依照時間排序),OpenSearch 會跳過相關性分數(Relevance Score)的計算,這在日誌分析中是標準做法。
第三層:單筆文件 hits.hits[] (Document Identity)
_index: 寫入的索引名稱為opensearch-logstash-docker-2026.03.24。_id: 該筆日誌的唯一標記符ielEH50BXMB4tDz9Y0CX。sort: 排序欄位的原始值1774346068785(這是一個毫秒級的 Epoch 時間戳記,對應到@timestamp)。
第四層:_source — 採集器寫入的原始資料 (Enriched Data)
這是運維診斷的核心,由日誌採集器(如 Logstash/Fluentd)自動附加的元資料:
- 時間戳記與時區邏輯:
message內:09:54:23(容器原始輸出的 UTC 時間)。time:17:54:23...+08:00(採集器轉換後的本地時間,兩者相差 8 小時)。@timestamp:09:54:28Z(OpenSearch 儲存用的標準 UTC 格式,比 log 產出晚 5 秒,代表處理延遲)。
message: 核心錯誤內容,顯示kube-apiserver無法連線至本地的etcd(127.0.0.1:2379)。stream: stderr: 標記這是一條錯誤流日誌,並非正常的標準輸出。logtag: F: 代表這是一行完整的(Full)Log,沒有因為長度限制而被截斷。kubernetes(Pod 元資料):- 定位:發生在命名空間
kube-system中的 Podkube-apiserver-rke2-c2。 - 環境:運行於節點
rke2-c2,映像檔版本為v1.34.4。 - 身份識別:包含
pod_id與docker_id,方便進一步去主機端(Node)下docker/crictl inspect指令查核。
- 定位:發生在命名空間
kubernetes_namespace: 顯示該 Namespace 屬於 Rancher 專案p-xnskv,這有助於在多租戶環境下快速判斷受影響的專案範圍。