天天看點

Kubernetes 故障排除方式

作者:ElevenLord

Kubernetes 是一款管理容器化應用程式的強大工具。然而,與任何複雜的系統一樣,使用它時也可能出錯。當問題出現時,掌握有效的故障排除技術和工具非常重要。

本文将介紹以下步驟,助您了解事件收集的入門知識:

  • 檢索最新事件
  • 使用 Pod 模拟問題
  • 在位于 PV 的 Pod 中存儲事件

檢索最新事件

對 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 排序顯示叢集中所有事件的清單。通過這種方式對通信口進行排序,您可以快速識别最近的事件和可能出現的任何問題。

使用 Pod 模拟問題

如果您發現存在與聯網或服務發現相關的問題,終止 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 中存儲事件

将事件存儲在位于 PV 中的 Pod,是跟蹤 Kubernetes 叢集中所發生事件的有效方法。下面是關于如何操作的分步講解:

一、為 Pod 添權重限

要在 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           

二、建立持久加密卷 (PV) 和持久加密卷聲明 (PVC)

現在我們已經設定好 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           

三、建立 Pod 以收集事件

現在,我們已經設定好 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。