自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

徹底搞懂 K8S Pod Pending 故障原因及解決方案

云計(jì)算 云原生 運(yùn)維
即使在高成熟度級(jí)別 Kubernetes 集群中 pod pending 也是無(wú)處不在。如果您隨機(jī)詢(xún)問(wèn)任何使用 Kubernetes DevOps 工程師來(lái)確定折磨他們噩夢(mèng)的最常見(jiàn)錯(cuò)誤,pod pending 可能是非常常見(jiàn)的問(wèn)題(可能僅次于 CrashLoopBackOff)。

即使在高成熟度級(jí)別 Kubernetes 集群中 pod pending 也是無(wú)處不在。

如果您隨機(jī)詢(xún)問(wèn)任何使用 Kubernetes DevOps 工程師來(lái)確定折磨他們噩夢(mèng)的最常見(jiàn)錯(cuò)誤,pod pending 可能是非常常見(jiàn)的問(wèn)題(可能僅次于 CrashLoopBackOff)。

嘗試推送更新并看到它卡住會(huì)使 DevOps 緊張。即使解決方案相當(dāng)簡(jiǎn)單,找到 pod 掛起的原因并了解您需要應(yīng)用的更改也很重要(Kubernetes 故障排除很少是微不足道的)。

在本文中,我們將闡明導(dǎo)致此問(wèn)題的不同情況,讓 DevOps 團(tuán)隊(duì)能夠快速找到解決方案,最重要的是,盡可能避免它。

Kubernetes Pod pending 是什么意思?

Kubernetes 中的 Pod 的生命周期由幾個(gè)不同的階段組成:

  • 創(chuàng)建 pod 時(shí),它從Pending階段開(kāi)始。
  • 一旦 pod 被調(diào)度并且容器已經(jīng)啟動(dòng),pod 就會(huì)進(jìn)入Running階段。

大多數(shù) pod 只需要幾秒鐘就可以從 Pending 到 Running 并在該狀態(tài)下度過(guò)大部分時(shí)間。

至此,Pod 已被 Kubernetes 集群接受。但是一個(gè)或多個(gè)容器尚未準(zhǔn)備好對(duì)外提供服務(wù)。這包括 Pod 等待調(diào)度所花費(fèi)的時(shí)間以及通過(guò)網(wǎng)絡(luò)下載容器鏡像所花費(fèi)的時(shí)間。

當(dāng) pod 無(wú)法從 PendingtoRunning 階段前進(jìn)時(shí),生命周期將停止并保留 pod,直到阻止它前進(jìn)的問(wèn)題得到修復(fù)。

如果我們使用 kubectl 列出 pod,我們將看到顯示 Kubernetes pod 掛起情況的輸出:

$ kubectl -n troubleshooting get pods
NAME                                           READY   STATUS    RESTARTS   AGE
stress-6d6cbc8b9d-s4sbh                        0/1     Pending   0          17s

除非我們解決問(wèn)題,否則 pod 被卡住并且不會(huì)運(yùn)行。

排查 Kubernetes pod Pending 的常見(jiàn)原因

有幾個(gè)原因可以阻止 Pod 運(yùn)行,但我們將描述三個(gè)主要問(wèn)題:

  • 調(diào)度問(wèn)題:無(wú)法在任何節(jié)點(diǎn)上調(diào)度 Pod。
  • 鏡像問(wèn)題:下載容器鏡像時(shí)出現(xiàn)問(wèn)題。
  • 依賴(lài)性問(wèn)題:Pod 需要一個(gè)卷、Secret 或 ConfigMap 才能運(yùn)行。

第一個(gè)是最常見(jiàn)的,最后一個(gè)很少見(jiàn)。讓我們?cè)敿?xì)說(shuō)明每種情況。

調(diào)度問(wèn)題導(dǎo)致 Kubernetes Pod Pending

創(chuàng)建 Pod 后,Kubernetes 集群做的第一件事就是嘗試調(diào)度 Pod 在其中一個(gè)節(jié)點(diǎn)上運(yùn)行。這個(gè)過(guò)程通常非??欤⑶?pod 被快速分配給具有足夠資源來(lái)運(yùn)行它的節(jié)點(diǎn)。

為了放置它,集群中的 Pod 被分配給具有更多未請(qǐng)求資源的節(jié)點(diǎn),并繼續(xù)其快樂(lè)而美好的生活,其中充滿(mǎn)了對(duì)請(qǐng)求的符合 SLO 的回復(fù)。

但是,如果此過(guò)程每次都有效,有幾個(gè)因素可能導(dǎo)致集群無(wú)法分配 pod。

讓我們回顧一下最常見(jiàn)的。

任何節(jié)點(diǎn)中都沒(méi)有足夠的資源來(lái)分配 pod

Kubernetes 使用調(diào)度請(qǐng)求來(lái)決定fits節(jié)點(diǎn)中是否有 pod。資源的真正使用無(wú)關(guān)緊要,只有其他 pod 已經(jīng)請(qǐng)求的資源。

effective requests當(dāng)一個(gè) pod 有足夠的可請(qǐng)求資源來(lái)參與該 pod 的內(nèi)存和 CPU 時(shí),它將被調(diào)度到一個(gè)節(jié)點(diǎn)中。并且節(jié)點(diǎn)必須沒(méi)有達(dá)到它可以運(yùn)行的最大 pod 數(shù)。

當(dāng)沒(méi)有任何節(jié)點(diǎn)滿(mǎn)足 pod 的所有要求時(shí),它將保持在 Kubernetes pod 掛起狀態(tài),直到釋放一些資源。

不可調(diào)度的節(jié)點(diǎn)

由于不同的問(wèn)題(節(jié)點(diǎn)壓力)或人為行為(節(jié)點(diǎn)封鎖),節(jié)點(diǎn)可能會(huì)變?yōu)椴豢烧{(diào)度的狀態(tài)。這些節(jié)點(diǎn)在狀態(tài)發(fā)生變化之前不會(huì)調(diào)度任何 pod。

污點(diǎn)和容忍度

污點(diǎn)是 Kubernetes 的一種機(jī)制,它允許我們限制可以分配給不同節(jié)點(diǎn)的 pod。當(dāng)節(jié)點(diǎn)具有 taint 時(shí),只有匹配容忍度的 pod 才能在該節(jié)點(diǎn)中運(yùn)行。

這種機(jī)制允許 Kubernetes 的特殊用途,例如為不同的工作負(fù)載使用不同類(lèi)型的節(jié)點(diǎn)(具有 GPU 的節(jié)點(diǎn),具有不同的 CPU/內(nèi)存比率等)。

即使我們分別描述每個(gè)原因,調(diào)度問(wèn)題也往往是由這些問(wèn)題的組合引起的。通常,您無(wú)法調(diào)度,因?yàn)槟承┕?jié)點(diǎn)已滿(mǎn)而其他節(jié)點(diǎn)已被污染,或者某個(gè)節(jié)點(diǎn)可能由于內(nèi)存壓力而無(wú)法調(diào)度。

為了找出調(diào)度問(wèn)題是什么,您需要查看調(diào)度程序生成的關(guān)于 pod 的事件,其中將詳細(xì)描述阻止節(jié)點(diǎn)分配的原因。我們可以使用 kubectl describe 查看事件,例如:

$ kubectl -n troubleshooting describe pod stress-6d6cbc8b9d-s4sbh
Name:           stress-6d6cbc8b9d-s4sbh
Namespace:      troubleshooting
Priority:       0
Node:           <none>
Labels:         app=stress
                pod-template-hash=6d6cbc8b9d
Annotations:    <none>
Status:         Pending
IP:
IPs:            <none>
Controlled By:  ReplicaSet/stress-6d6cbc8b9d
Containers:
  stress:
    Image:      progrium/stress
    Port:       <none>
    Host Port:  <none>
    Args:
      --cpu
      1
      --vm
      2
      --vm-bytes
      150M
    Limits:
      cpu:     300m
      memory:  120000Mi
    Requests:
      cpu:        200m
      memory:     100000Mi
    Environment:  <none>
    Mounts:
      /var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-snrww (ro)
Conditions:
  Type           Status
  PodScheduled   False
Volumes:
  kube-api-access-snrww:
    Type:                    Projected (a volume that contains injected data from multiple sources)
    TokenExpirationSeconds:  3607
    ConfigMapName:           kube-root-ca.crt
    ConfigMapOptional:       <nil>
    DownwardAPI:             true
QoS Class:                   Burstable
Node-Selectors:              <none>
Tolerations:                 node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
                             node.kubernetes.io/unreachable:NoExecute op=Exists for 300s
Events:
  Type     Reason            Age                   From               Message
  ----     ------            ----                  ----               -------
  Warning  FailedScheduling  4m17s (x41 over 34m)  default-scheduler  0/5 nodes are available: 1 node(s) had taint {node-role.kubernetes.io/master: }, that the pod didn't tolerate, 4 Insufficient memory.

我們可以在輸出中看到消息中的確切原因:

0/5 nodes are available: 1 node(s) had taint {node-role.kubernetes.io/master: }, that the pod didn't tolerate, 4 Insufficient memory.
  • 其中一個(gè)節(jié)點(diǎn)被污染。
  • 其中四個(gè)節(jié)點(diǎn)沒(méi)有足夠的可請(qǐng)求內(nèi)存。

為了解決這個(gè)問(wèn)題,我們有兩個(gè)選擇:

  • 減少 pod 定義中的資源請(qǐng)求大小。
  • 通過(guò)添加更多節(jié)點(diǎn)或增加每個(gè)節(jié)點(diǎn)的大小來(lái)增加集群的容量。

如果要更新當(dāng)前運(yùn)行的工作負(fù)載,還需要考慮另一個(gè)重要因素:升級(jí)策略。

由于此策略,Kubernetes 可以允許工作負(fù)載在更新過(guò)程中創(chuàng)建比平時(shí)更多的 Pod,在創(chuàng)建新 Pod 時(shí)保留舊 Pod 一段時(shí)間。這意味著工作負(fù)載可能會(huì)在一段時(shí)間內(nèi)請(qǐng)求比預(yù)期更多的資源。如果集群沒(méi)有足夠的備用資源,更新將被阻塞,留下一些 pod 待處理,直到進(jìn)程被解除阻塞(或回滾超時(shí)停止更新)。

由于鏡像問(wèn)題,Pod Pending

一旦在一個(gè)節(jié)點(diǎn)中分配了 pod,kubelet就會(huì)嘗試啟動(dòng) pod 中的所有容器。為此,它將嘗試下載鏡像并運(yùn)行它。

有幾個(gè)錯(cuò)誤會(huì)阻止鏡像被下載:

  • 鏡象名稱(chēng)錯(cuò)誤。
  • 錯(cuò)誤的鏡像標(biāo)簽。
  • 錯(cuò)誤的存儲(chǔ)倉(cāng)庫(kù)。
  • 存儲(chǔ)倉(cāng)庫(kù)需要身份驗(yàn)證。

Kubernetes Pod 由于依賴(lài)問(wèn)題而掛起

在 pod 啟動(dòng)之前,kubelet將嘗試檢查與其他 Kubernetes 元素的所有依賴(lài)關(guān)系。如果無(wú)法滿(mǎn)足這些依賴(lài)項(xiàng)之一,則 pod 將保持掛起狀態(tài),直到滿(mǎn)足依賴(lài)項(xiàng)。

在這種情況下,kubectl 將像這樣顯示 pod:

$ kubectl -n mysql get pods 
NAME READY STATUS RESTARTS AGE 
mysql-0 0/1 ContainerCreating 0 97s

在事件中,我們可以看到如下內(nèi)容:

Events:
  Type     Reason       Age                  From               Message
  ----     ------       ----                 ----               -------
  Normal   Scheduled    3m19s                default-scheduler  Successfully assigned mysql/mysql-0 to ip-172-20-38-115.eu-west-1.compute.internal
  Warning  FailedMount  76s                  kubelet            Unable to attach or mount volumes: unmounted volumes=[config], unattached volumes=[kube-api-access-gxjf8 data config]: timed out waiting for the condition
  Warning  FailedMount  71s (x9 over 3m19s)  kubelet            MountVolume.SetUp failed for volume "config" : configmap "mysql" not found

該 Message 列將為您提供足夠的信息,以便能夠查明缺失的元素。常見(jiàn)的原因有:

  • 尚未創(chuàng)建 ConfigMap 或者 Secret,或提供的名稱(chēng)不正確。
  • 無(wú)法在節(jié)點(diǎn)中掛載卷,因?yàn)樗形幢涣硪粋€(gè)節(jié)點(diǎn)釋放。這尤其發(fā)生在更新 statefulset 的過(guò)程中,掛載的卷必須與舊 pod 相同。

結(jié)論

了解 pod 保持在該 Pending 階段的原因是在 Kubernetes 中安全部署和更新工作負(fù)載的關(guān)鍵。能夠快速定位問(wèn)題并加快部署進(jìn)度將為您省去一些麻煩并減少停機(jī)時(shí)間。

責(zé)任編輯:華軒 來(lái)源: 云原生運(yùn)維圈
相關(guān)推薦

2022-12-07 17:33:50

K8Skubernetes

2024-03-18 15:44:48

K8S故障運(yùn)維

2011-05-24 11:26:11

2019-05-22 09:51:28

網(wǎng)絡(luò)故障

2024-01-26 14:35:03

鑒權(quán)K8sNode

2020-05-08 15:20:40

PaaSKubernetes平臺(tái)

2023-07-04 07:30:03

容器Pod組件

2018-10-12 14:34:13

2025-01-07 16:00:00

Kubernetes云原生Pod

2023-09-20 14:30:36

K8s亞馬遜谷歌

2021-07-28 10:10:57

K8SMount PVCPod

2020-08-13 07:04:45

跨域CORS瀏覽器

2022-11-02 10:21:41

K8s pod運(yùn)維

2024-03-28 18:08:44

Kubernetes抓包Pod

2021-04-23 08:35:16

k8s故障檢測(cè)

2022-06-01 09:38:36

KubernetesPod容器

2022-04-22 13:32:01

K8s容器引擎架構(gòu)

2009-07-22 17:37:06

ASP.NET Ses

2022-06-14 07:56:15

Kubernetes存儲(chǔ)架構(gòu)K8S

2023-04-30 00:02:40

K8Skubelet數(shù)據(jù)
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)