掌握Kubernetes Pod故障排除:高級(jí)策略和方案
Kubernetes(K8s)部署通常會(huì)帶來(lái)各種角度的挑戰(zhàn),包括 pod、服務(wù)、ingress、無(wú)響應(yīng)集群、控制平面和高可用性設(shè)置。Kubernetes pod 是 Kubernetes 生態(tài)系統(tǒng)中最小的可部署單元,封裝了一個(gè)或多個(gè)共享資源和網(wǎng)絡(luò)的容器。Pod 旨在運(yùn)行應(yīng)用程序或進(jìn)程的單個(gè)實(shí)例,并根據(jù)需要?jiǎng)?chuàng)建和處置。Pod 對(duì)于在 K8s 環(huán)境中擴(kuò)展、更新和維護(hù)應(yīng)用程序至關(guān)重要。
譯自 Master Kubernetes Pods: Advanced Troubleshooting Strategies,作者 None。
本文探討了 Kubernetes pod 面臨的挑戰(zhàn)以及要采取的故障排除步驟。運(yùn)行 Kubernetes pod 時(shí)遇到的部分錯(cuò)誤消息包括:
- ImagePullBackoff
- ErrImagePull
- InvalidImageName
- CrashLoopBackOff
有時(shí),您甚至不會(huì)遇到列出的錯(cuò)誤,但仍會(huì)發(fā)現(xiàn)您的 pod 失敗。首先,需要注意的是,在調(diào)試任何 Kubernetes 資源時(shí),您都應(yīng)該了解 API 參考。它解釋了如何定義各種 Kubernetes API 以及 pod/部署中的多個(gè)對(duì)象如何工作。文檔在 Kubernetes 網(wǎng)站上的 API 參考中定義得很明確。在這種情況下,在調(diào)試 pod 時(shí),從 API 參考中選擇 pod 對(duì)象以詳細(xì)了解 pod 的工作原理。它定義了進(jìn)入 pod 的字段,即版本、類(lèi)型、元數(shù)據(jù)、規(guī)范和狀態(tài)。Kubernetes 還提供了一個(gè)作弊小炒,其中包含所需命令的指南。
先決條件
本文假設(shè)讀者具備以下條件:
- 已安裝 Kind 以進(jìn)行場(chǎng)景演示
- 對(duì) Kubernetes 架構(gòu)有中級(jí)了解
- Kubectl 命令行工具
Kubernetes Pod 錯(cuò)誤 - ImagePullBackoff
該錯(cuò)誤顯示有三個(gè)不同的原因:
- 無(wú)效鏡像
- 無(wú)效標(biāo)簽
- 無(wú)效權(quán)限
當(dāng)您沒(méi)有有關(guān)鏡像的正確信息時(shí),就會(huì)出現(xiàn)這些情況。您可能也沒(méi)有從其存儲(chǔ)庫(kù)(私有存儲(chǔ)庫(kù))中提取鏡像的權(quán)限。為了在下面的示例中演示這一點(diǎn),我們創(chuàng)建了一個(gè) nginx 部署:
? ~ kubectl create deploy nginx --image=nginxdeployment.apps/nginx
created
Pod 正在運(yùn)行后,獲取 pod 名稱(chēng):
? ~ kubectl get pods
NAME READY STATUS RESTARTS AGE
nginx-8f458dc5b-hcrsh 1/1 Running 0 100s
復(fù)制正在運(yùn)行的 pod 的名稱(chēng)并獲取有關(guān)它的更多信息:
? ~ kubectl describe pod nginx-8f458dc5b-hcrsh
Name: nginx-8f458dc5b-hcrsh
hable:NoExecute op=Exists for 300s
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 2m43s default-scheduler Successfully assigned default/nginx-8f458dc5b-hcrsh to k8s-troubleshooting-control-plane
Normal Pulling 2m43s kubelet Pulling image "nginx"
Normal Pulled 100s kubelet Successfully pulled image "nginx" in 1m2.220189835s
Normal Created 100s kubelet Created container nginx
Normal Started 100s kubelet Started container nginx
鏡像已成功拉取。您的 Kubernetes pod 正在運(yùn)行,沒(méi)有錯(cuò)誤。
要演示 ImagePullBackoff,請(qǐng)編輯部署 YAML 文件并指定一個(gè)不存在的鏡像:
? kubectl edit deploy nginx
containers:
-image: nginxdoestexist
imagePullPolicy: Always
name: nginx
新 pod 未成功部署
? ~ kubectl get pods
NAME READY STATUS RESTARTS AGE
nginx-5b847fdb95-mx4pq 0/1 ErrImagePull 0 3m40s
nginx-8f458dc5b-hcrsh 1/1 Running 0 38m
顯示 ImagePullBackoff 錯(cuò)誤
? ~ kubectl describe pod nginx-6f46cbfbcb-c92bl
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 88s default-scheduler Successfully assigned default/nginx-6f46cbfbcb-c92bl to k8s-troubleshooting-control-plane
Normal Pulling 40s (x3 over 88s) kubelet Pulling image "nginxdoesntexist"
Warning Failed 37s (x3 over 85s) kubelet Failed to pull image "nginxdoesntexist": rpc error: code = Unknown desc = failed to pull and unpack image "docker.io/library/nginxdoesntexist:latest": failed to resolve reference "docker.io/library/nginxdoesntexist:latest": pull access denied, repository does not exist or may require authorization: server message: insufficient_scope: authorization failed
Warning Failed 37s (x3 over 85s) kubelet Error: ErrImagePull
Normal BackOff 11s (x4 over 85s) kubelet Back-off pulling image "nginxdoesntexist"
Warning Failed 11s (x4 over 85s) kubelet Error: ImagePullBackOff
Kubernetes Pod 錯(cuò)誤 - 已拉取鏡像但 Pod 處于 pending 狀態(tài)。
每當(dāng)你在生產(chǎn)環(huán)境中運(yùn)行 K8s 時(shí),K8s 管理員會(huì)根據(jù)集群內(nèi)運(yùn)行的命名空間的要求為每個(gè)命名空間分配資源配額。命名空間用于在集群內(nèi)進(jìn)行邏輯分離。
當(dāng)資源配額中的規(guī)范不滿足 Pod 中應(yīng)用程序的最低要求時(shí),就會(huì)拋出“Image pulled, but the pod is still pending”錯(cuò)誤。在以下示例中,創(chuàng)建一個(gè)名為 payments 的命名空間:
? ~ kubectl create ns payments
namespace/payments created
使用相關(guān)規(guī)范創(chuàng)建資源配額
? ~ cat resourcequota.yaml
apiVersion: v1
kind: ResourceQuota
metadata:
name: compute-resources
spec:
hard:
requests.cpu: "1"
requests.memory: 1Gi
limits.cpu: "2"
limits.memory: 4Gi
將資源配額分配給命名空間 payments
? ~ kubectl apply -f resourcequota.yaml -n paymentsresourcequota/compute-resources created
在具有資源配額限制的命名空間內(nèi)創(chuàng)建新部署:
kubectl create deploy nginx --image=nginx -n paymentsdeployment.apps/nginx created
盡管已成功創(chuàng)建部署,但沒(méi)有 Pod 存在:
? ~ kubectl get pods -n payments
No resources found in payments namespace
已創(chuàng)建部署,但是沒(méi)有處于準(zhǔn)備狀態(tài)的 Pod,沒(méi)有更新的 Pod,也沒(méi)有可用的 Pod:
? ~ kubectl get deploy -n payments
NAME READY UP-TO-DATE AVAILABLE AGE
nginx 0/1 0 0 7m4s
要進(jìn)一步調(diào)試,請(qǐng)描述 nginx 部署。Pod 創(chuàng)建失敗:
? ~ kubectl describe deploy nginx -n payments
Name: nginx
Namespace: payments
CreationTimestamp: Wed, 24 May 2023 21:37:55 +0300
Labels: app=nginx
Annotations: deployment.kubernetes.io/revision: 1
Selector: app=nginx
Replicas: 1 desired | 0 updated | 0 total | 0 available | 1 unavailable
StrategyType: RollingUpdate
MinReadySeconds: 0
RollingUpdateStrategy: 25% max unavailable, 25% max surge
Pod Template:
Labels: app=nginx
Containers:
nginx:
Image: nginx
Port: <none>
Host Port: <none>
Environment: <none>
Mounts: <none>
Volumes: <none>
Conditions:
Type Status Reason
---- ------ ------
Available False MinimumReplicasUnavailable
ReplicaFailure True FailedCreate
Progressing False ProgressDeadlineExceeded
OldReplicaSets: <none>
NewReplicaSet: nginx-8f458dc5b (0/1 replicas created)
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal ScalingReplicaSet 10m deployment-controller Scaled up replica set nginx-8f458dc5b to 1
從 Kubernetes 事件進(jìn)行的進(jìn)一步分析顯示 Pod 創(chuàng)建所需的內(nèi)存不足。
? ~ kubectl get events --sort-by=/metadata.creationTimestamp
當(dāng)你的鏡像已成功拉取,并且你的容器已創(chuàng)建,但你的運(yùn)行時(shí)配置失敗時(shí),就會(huì)發(fā)生此錯(cuò)誤。例如,如果你有一個(gè)正在嘗試寫(xiě)入不存在的文件夾或沒(méi)有寫(xiě)入該文件夾的權(quán)限的正在工作的 Python 應(yīng)用程序。最初,應(yīng)用程序會(huì)執(zhí)行,然后遇到錯(cuò)誤。如果你的應(yīng)用程序邏輯中出現(xiàn) panic ,則容器將停止。容器將進(jìn)入 CrashLoopBackOff。最終,你觀察到部署沒(méi)有 Pod,即存在一個(gè) Pod,但它沒(méi)有運(yùn)行并拋出 CrashLoopbackoff 錯(cuò)誤。
存活和就緒探測(cè)失敗
存活(Liveness)探測(cè)檢測(cè) Pod 是否已進(jìn)入損壞狀態(tài)且無(wú)法再提供流量。Kubernetes 將為您重新啟動(dòng) Pod。就緒(readiness )探測(cè)檢查您的應(yīng)用程序是否已準(zhǔn)備好處理流量。就緒探測(cè)確保您的應(yīng)用程序從配置映射中提取所有必需的配置并啟動(dòng)其線程。只有完成此過(guò)程后,您的應(yīng)用程序才準(zhǔn)備好接收流量。如果您的應(yīng)用程序在此過(guò)程中遇到錯(cuò)誤,它也會(huì)進(jìn)入 CrashLoopBackoff。
開(kāi)始故障排除!
本文概述了 Kubernetes Pod 的故障排除技術(shù)。它解決了在部署 Pod 時(shí)遇到的常見(jiàn)錯(cuò)誤,并提供了解決這些錯(cuò)誤的實(shí)用解決方案。它還深入了解了在理解 Kubernetes 工作原理和有效識(shí)別和解決問(wèn)題時(shí)至關(guān)重要的參考頁(yè)面和備忘單。通過(guò)遵循本文中提供的指導(dǎo),讀者可以提高他們的故障排除技能,并簡(jiǎn)化其 Kubernetes Pod 的部署和管理。