Kubernetes 是一款管理容器化應用程式的強大工具。然而,與任何複雜的系統一樣,使用它時也可能出錯。當問題出現時, 掌握有效的故障排除技術和工具非常重要。
本文將介紹以下步驟,助您瞭解事件收集的入門知識:
對 Kubernetes 叢集進行故障診斷的第一步是檢索最新的事件。 Kubernetes 中的事件由叢集中的各種元件和物件(如 Pod、節點和服務)生成。它們可提供有關叢集狀態和可能發生的任何問題的資訊。
要檢索最新事件,可以使用 Kubectl get events
命令。這將顯示叢集中所有事件的列表。
kubectl get events
LAST SEEN TYPE REASON OBJECT MESSAGE
78s Warning BackOff pod/bbb Back-off restarting failed container
72s Warning BackOff pod/bbb2 Back-off restarting failed container
12m Normal Pulling pod/bbb3 Pulling image "busybox"
12m Normal Created pod/bbb3 Created container bbb3
46m Normal Started pod/bbb3 Started container bbb3
如上所示,它按 時間排序 顯示了叢集中所有通訊口的列表。您還可以新增 -w
標記,以觀察新事件發生的變化。
這將顯示叢集中發生事件的實時狀態。通過觀察事件,您可以 快速識別可能發生的任何問題。
雖然 kubectl get events
命令有助於檢索事件,但如果事件按時間順序顯示,則很難識別問題。為了更容易識別問題,您可以按照 metadata.creationTimestamp
對事件進行排序。
kubectl get events --sort-by=.metadata.creationTimestamp
LAST SEEN TYPE REASON OBJECT MESSAGE
104s Normal Pulling pod/busybox13 Pulling image "busybox"
88s Warning FailedScheduling pod/mysqldeployment-6f8b755598-phgzr 0/2 nodes are available: 2 Insufficient cpu. preemption: 0/2 nodes are available: 2 No preemption victims found for incoming pod.
104s Warning BackOff pod/busybox6 Back-off restarting failed container
82s Warning ProvisioningFailed persistentvolumeclaim/pv-volume storageclass.storage.k8s.io "csi-hostpath-sc" not found
82s Warning ProvisioningFailed persistentvolumeclaim/pv-volume-2 storageclass.storage.k8s.io "csi-hostpath-sc" not found
如上所示,按 metada.creationTimestamp
排序顯示叢集中所有事件的列表。通過這種方式對通訊口進行排序,您可以快速識別最近的事件和可能出現的任何問題。
如果您發現存在 與聯網或服務發現相關的問題, 終止 kube-proxy
pod 可能會有幫助。 kube-proxy
pod 負責叢集中的聯網和服務發現,因此終止它有助於識別與這些功能相關的任何問題。
要終止 kube-proxy
pod,可以使用 kubectl delete pod
命令。如果您需要指定 kube-proxy pod
的名稱,可以使用 kubectl get pods
命令找到它。
kubectl get pods -n kube-system
NAME READY STATUS RESTARTS AGE
coredns-57575c5f89-66z2h 1/1 Running 1 (45h ago) 36d
coredns-57575c5f89-bcjdn 1/1 Running 1 (45h ago) 36d
etcd-k81 1/1 Running 1 (45h ago) 36d
fluentd-elasticsearch-5fdvc 1/1 Running 2 (45h ago) 60d
fluentd-elasticsearch-wx6x9 1/1 Running 1 (45h ago) 60d
kube-apiserver-k81 1/1 Running 1 (45h ago) 36d
kube-controller-manager-k81 1/1 Running 2 (45h ago) 36d
kube-proxy-bqpb5 1/1 Running 1 (45h ago) 36d
kube-proxy-q94sk 1/1 Running 1 (45h ago) 36d
kube-scheduler-k81 1/1 Running 2 (45h ago) 36d
metrics-server-5c59ff65b6-s4kms 1/1 Running 2 (45h ago) 58d
weave-net-56pl2 2/2 Running 3 (45h ago) 61d
weave-net-rml96 2/2 Running 5 (45h ago) 62d
如上,將顯示 Kube 系統名稱空間中所有 pod 的列表,其中包括 kube-proxy pod
。獲得 kube-proxy pod
的名稱後,就可以使用 kubectl delete pod
命令將其刪除。
kubectl delete pod -n kube-system kube-proxy-q94sk
這將刪除 kube-system 名稱空間中的 kube-proxy pod
。Kubernetes 會自動建立一個新的 kube-proxy pod
來替代它。
您可以使用以下命令檢查事件:
kubectl get events -n=kube-system --sort-by=.metadata.creationTimestamp
LAST SEEN TYPE REASON OBJECT MESSAGE
4m59s Normal Killing pod/kube-proxy-bqpb5 Stopping container kube-proxy
4m58s Normal Scheduled pod/kube-proxy-cbkx6 Successfully assigned kube-system/kube-proxy-cbkx6 to k82
4m58s Normal SuccessfulCreate daemonset/kube-proxy Created pod: kube-proxy-cbkx6
4m57s Normal Pulled pod/kube-proxy-cbkx6 Container image "registry.k8s.io/kube-proxy:v1.24.11" already present on machine
將事件儲存在位於 PV 中的 Pod,是跟蹤 Kubernetes 叢集中所發生事件的有效方法。下面是關於如何操作的分步講解:
要在 pod 中連線 Kubernetes API,您需要賦予它適當的許可權。下面是一個將許可權繫結到 pod 的 YAML 檔案範例。
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: event-logger
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: cluster-admin
subjects:
- kind: ServiceAccount
name: default
namespace: default
現在我們已經設定好 ClusterRoleBind,可以建立一個持久捲來儲存我們的事件。下面是一個使用 hostPath
建立 PC 的 YAML 檔案範例:
# pv.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
name: my-pv
spec:
capacity:
storage: 1Gi
accessModes:
- ReadWriteOnce
hostPath:
path: /mnt/data
---
# pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: my-pvc
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
volumeName: my-pv
現在,我們已經設定好 PV 和 PVC,可以建立 Pod 來收集事件了。下面是一個 YAML 檔案範例,用於建立一個 Pod,在 Pod 中連線到 Kubernetes API,並將所有事件儲存到檔案 events.log
中。
apiVersion: v1
kind: Pod
metadata:
name: event-logger
spec:
containers:
- name: event-logger
image: alpine
command: ["/bin/sh", "-c"]
args:
- |
apk add --no-cache curl jq && while true; do
EVENTS=$(curl -s -k -H "Authorization: Bearer $(cat /var/run/secrets/kubernetes.io/serviceaccount/token)" https://${KUBERNETES_SERVICE_HOST}/api/v1/events | jq -r '.items[]')
if [ -n "$EVENTS" ]; then
echo "$EVENTS" >> /pv/events.log
fi
sleep 10
done
volumeMounts:
- name: event-log
mountPath: /pv
- name: sa-token
mountPath: /var/run/secrets/kubernetes.io/serviceaccount
readOnly: true
volumes:
- name: event-log
persistentVolumeClaim:
claimName: my-pvc
- name: sa-token
projected:
sources:
- serviceAccountToken:
path: token
expirationSeconds: 7200
- configMap:
name: kube-root-ca.crt
該 Pod 將執行一個安裝了 curl
和 jq 的簡單 shell 指令碼,使用 event-logger ClusterRoleBinding
連線到 Kubernetes API,並將所有事件儲存在 /pv/events.log 中。
可以執行以下命令檢查事件:
kubectl exec event-logger -- cat /pv/events.log
通過使用這些故障排除技術和工具,您可以 保持 Kubernetes 叢集的健康和平穩執行。檢索最新事件、模擬問題並將事件儲存在位於 PV 中的 pod 中,是有效維護叢集的基本步驟。隨著您對 Kubernetes 的使用經驗越來越豐富,您可以探索更高階的工具,如用於分析事件的 Kibana、Prometheus 或 Grafana,以及集中式紀錄檔記錄解決方案,如 Elasticsearch 或 Fluentd。