跳至內容

如何在 Amazon EKS 中對 Kubernetes Pod 問題進行疑難排解?

4 分的閱讀內容
0

我的 Amazon Elastic Kubernetes Service (Amazon EKS) 叢集中的 Kubernetes Pod 發生故障。我想要找出 Pod 故障的根本原因。

解決方法

找出造成您 Pod 問題的錯誤

  1. 若要取得您 Pod 的相關資訊,請執行以下 kubectl describe 命令:

    kubectl describe pod YOUR_POD_NAME -n YOUR_NAMESPACE

    **注意:**將 YOUR_POD_NAME 替換為您的 Pod 名稱,並將 YOUR_NAMESPACE 替換為您的命名空間。

  2. 在命令輸出的 Events (事件) 區段中找出錯誤訊息。

    輸出範例:

    Events:
      Type     Reason            Age                From               Message
      ----     ------            ----               ----               -------
      Warning  FailedScheduling  24s                default-scheduler  no nodes available to schedule pods
      Warning  FailedScheduling  19s (x2 over 22s)  default-scheduler  no nodes available to schedule pods

根據您收到的錯誤訊息,使用以下疑難排解步驟來解決 Pod 問題。

EBS 磁碟區掛載問題

以下是 kubectl describe pod ebs-pod 命令的輸出範例。輸出顯示 Amazon Elastic Block Store (Amazon EBS) 磁碟區掛載的磁碟區節點相容性錯誤:

Name:         ebs-pod
...
Status:       Pending
...
Events:
  Type     Reason            Age                 From               Message
  ----     ------            ----                ----               -------
  Warning FailedScheduling 88s (x20 over 96m) default-scheduler 0/2 nodes are available 2 node(s) had volume node affinity conflict

當您在多個可用區域為 Pod 排程 Persistent Volume Claims (PVC) 時,就會發生上述錯誤。您無法排程 Pod,因為 Pod 無法從另一個可用區域連線到該磁碟區。若要解決此問題,您必須在單一可用區域中排程 PVC。

若要疑難排解上述錯誤,請完成以下步驟:

  1. 若要取得命名空間中所有 PVC 的資訊,請執行以下 kubectl get pvc 命令:

    kubectl get pvc -n YOUR_NAMESPACE

    **注意:**將 YOUR_NAMESPACE 替換為您的命名空間。

  2. 若要取得 Persistent Volume (PV) 的資訊,請執行以下 kubectl get pv 命令:

    kubectl get pv
  3. 若要找到對應您 PVC 的 PV,請執行以下 kubectl describe pv 命令:

    kubectl describe pv your_PV

    **注意:**將 your_PV 替換為您的 PV 名稱。

  4. 確認從上述命令取得的磁碟區 ID 是否與正確的可用區域相關聯。

  5. 查看該可用區域所在的節點。

如果出現磁碟區節點相容性衝突,請採取以下其中一種操作:

  • 使用污點與容忍度確保使用 Amazon EBS 掛載的 Pod 排程到正確的節點。該節點必須位於 EBS 磁碟區所在的可用區域。如需更多資訊,請參閱 Kubernetes 網站上的污點和容忍度
  • 對於 StatefulSet 中的每個 Pod,使用 StatefulSets 而非 Deployment,在相同可用區域中建立唯一的 EBS 磁碟區。如需更多資訊,請參閱 Kubernetes 網站上的 StatefulSets

您的 Pod 或 StatefulSet 可能卡在Pending (擱置中) 狀態。即使您的 Pod 或 StatefulSet 與 EBS 磁碟區位於相同可用區域,也可能發生此情況。若要解決此問題,請執行以下 kubectl logs 命令以檢查 Amazon EBS CSI 代理程式 Pod 的日誌:

kubectl logs your-ebs-csi-controller -n your-kube-system -c your-csi-provisioner

**注意:**將 your-ebs-csi-controller 替換為您的 Amazon EBS CSI 控制器。同時,將 your-kube-system 替換為您預設的命名空間,並將 your-csi-provisioner 替換為您用來提取日誌的容器名稱。

ContainerCreating 狀態錯誤

當您的 Pod 卡在 ContainerCreating 狀態,且 networkPlugin: cni 未為您的 Pod 指派 IP 位址時,會出現以下錯誤訊息:

「Failed to create pod sandbox: rpc error: code = Unknown desc = failed to set up sandbox container "0fdf25254b1888afeda8bf89bc1dcb093d0661ae2c8c65a4736e473c73714c65" network for pod "test": networkPlugin cni failed to set up pod "test" network: add cmd: failed to assign an IP address to container.」

若要疑難排解 ContainerCreating 狀態錯誤,請採取以下操作:

  • 查看您的子網路是否有可用 IP 位址來解決問題。開啟 Amazon Virtual Private Cloud (Amazon VPC) console (Amazon Virtual Private Cloud (Amazon VPC) 主控台)。在導覽窗格的 Virtual private cloud (虛擬私有雲端) 下,選擇 Subnets (子網路)。
  • 確認 aws-node 的 Pod 處於 Running (執行中) 狀態。同時,確保您使用支援的最新 Amazon VPC CNI 版本
  • 查看執行個體上的 Pod 數量是否已達到 Pod 最大數量
  • 在您排程 Pod 的節點中,於 var/log/aws-routed-eni 路徑下,檢查 ipamd 日誌與外掛程式中的錯誤訊息。

CrashLoopBackOff 狀態錯誤

您收到「Back-Off restarting failed container」錯誤訊息。

上述錯誤訊息發生的原因是容器反覆啟動失敗,然後進入 CrashLoopBackOff 狀態,並在 Pod 中持續重新啟動。

以下問題可能導致容器反覆啟動失敗:

  • 記憶體不足
  • 資源超載
  • 部署錯誤
  • 外部相依性問題,例如 DNS 錯誤
  • 第三方相依性
  • 連接埠衝突造成的容器層級失敗

若要取得目前 Pod 日誌中的錯誤,請執行以下 kubectl logs 命令:

kubectl logs YOUR_POD_NAME -n YOUR_NAMESPACE

**注意:**將 YOUR_POD_NAME 替換為您的 Pod 名稱,並將 YOUR_NAMESPACE 替換為您的命名空間。

若取得先前當機 Pod 的日誌錯誤,請執行以下 kubectl logs --previous 命令:

kubectl logs --previous YOUR_POD_NAME -n YOUR_NAMESPACE

**注意:**將 YOUR_POD_NAME 替換為您的 Pod 名稱,並將 YOUR_NAMESPACE 替換為您的命名空間。

探查失敗錯誤

Pod 當機時,您會因為連線遭拒或用戶端逾時而收到探查失敗錯誤訊息。

對連線遭拒進行疑難排解

若探查因連線遭拒而失敗,那麼您可能會收到以下其中一則錯誤訊息:

  • 「Liveness probe failed: Get https://$POD_IP:8080/<healthcheck_path>: dial tcp POD_IP:8080: connect: connection refused.」
  • 「Readiness probe failed: Get https://$POD_IP:8080/<healthcheck_path>: dial tcp POD_IP:8080: connect: connection refused.」

若要對連線遭拒進行疑難排解,請完成以下步驟:

  1. 若要從工作節點手動取得在 Pod 資訊清單上定義的運作狀態檢查路徑,請執行以下命令:

    [ec2-user@ip-10-5-1-12 ~]$ curl -ikv podIP:8080//your_healthcheck_path

    **注意:**將 podIP 替換為您的 Pod IP 位址,並將 your_healthcheck_path 替換為您的路徑名稱。

  2. 請檢查 Pod 資訊清單中為活躍性探查就緒探查失敗的 Pod 所定義的運作狀態檢查路徑。若要檢查運作狀態檢查路徑,請執行以下命令:

    local@bastion-host ~ % kubectl exec YOUR_POD_NAME -- curl -ikv "http://localhost:8080/your_healthcheck_path"

    **注意:**將 YOUR_POD_NAME 替換為您的 Pod 名稱。

  3. 在堡壘主機上執行相同的容器映像檔。

  4. 檢查您是否能取得在資訊清單中探查所定義的運作狀態檢查路徑。接著,檢查容器日誌中是否有失敗、逾時或錯誤的記錄。

  5. 若要檢查執行 Pod 的工作節點中 kubelet 日誌的錯誤,請執行以下 journalctl 命令:

    [ec2-user@ip-10-5-1-12 ~]$ journalctl -u kubelet //optionally 'grep' with pod name

用戶端逾時疑難排解

若探查因用戶端逾時而失敗,那麼您可能會收到以下其中一則錯誤訊息:

  • 「Liveness probe failed: Get "http://podIP:8080/<healthcheck_path> ": context deadline exceeded (Client.Timeout exceeded while awaiting headers).」
  • 「Readiness probe failed: Get "http://podIP:8080/<healthcheck_path> ": context deadline exceeded (Client.Timeout exceeded while awaiting headers).」

若要對用戶端逾時進行疑難排解,請檢查您應用程式 Pod 的「活躍性探查」與「就緒探查」組態是否正確。

如果您對 Pod 使用安全群組且 ENABLE_POD_ENI=true,則必須關閉 TCP 早期解多工器。此動作可讓 kubelet 連線至使用 TCP 的分支網路介面上的 Pod。

若要關閉 TCP 早期解多工器,請執行以下 kubectl patch 命令:

kubectl patch daemonset aws-node -n kube-system \-p '{"spec": {"template": {"spec": {"initContainers": [{"env":[{"name":"DISABLE_TCP_EARLY_DEMUX","value":"true"}],"name":"aws-vpc-cni-init"}]}}}}'

ImagePullBackOff 錯誤

當 Pod 中執行的容器無法從容器登錄檔提取所需映像檔時,就會發生 ImagePullBackOff 錯誤。

以下問題可能導致此錯誤:

  • 網路連線問題
  • 映像檔名稱或標籤錯誤
  • 缺少憑證
  • 權限不足

若要確定造成問題的原因,請完成以下步驟:

  1. 若要取得 Pod 的狀態,請執行以下命令:

    kubectl get pods -n YOUR_NAMESPACE

    **注意:**將 YOUR_NAMESPACE 替換為您的命名空間。

  2. 若要取得 Pod 的失敗詳細資訊,請執行以下命令:

    kubectl describe pod YOUR_POD_NAME -n YOUR_NAMESPACE

    **注意:**將 YOUR_POD_NAME 替換為您的 Pod 名稱,並將 YOUR_NAMESPACE 替換為您的命名空間。

    輸出範例:

    Events:
    Type     Reason     Age                From                Message
    ----     ------     ----               ----                -------
    Normal   Scheduled  18m                default-scheduler   Successfully assigned kube-system/kube-proxy-h4np6 to XXX.XXX.eu-west-1.compute.internal
    Normal   Pulling    16m (x4 over 18m)  kubelet             Pulling image "<account-id>.dkr.ecr.eu-west-1.amazonaws.com/eks/kube-proxy:v1.21.5-eksbuild.2"
    Warning  Failed     16m (x4 over 18m)  kubelet             Failed to pull image "<account-d>.dkr.ecr.eu-west-1.amazonaws.com/eks/kube-proxy:v1.21.5-eksbuild.2": rpc error: code = Unknown desc = Error response from daemon: manifest for <account-id>.dkr.ecr.eu-west-1.amazonaws.com/eks/kube-proxy:v1.21.5-eksbuild.2 not found: manifest unknown: Requested image not found

若要對 ImagePullBackOff 錯誤進行疑難排解,請參閱如何對 Amazon EKS 中的 Pod 狀態 ErrImagePull 和 ImagePullBackoff 錯誤進行疑難排解?

AWS 官方已更新 2 個月前