<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          【圖解】Kubernetes Deployment 故障排查指南

          共 7428字,需瀏覽 15分鐘

           ·

          2021-04-19 14:58

          來源:K8sMeetup社區(qū)

          如果你不知道從何下手,那么在 Kubernetes 中排查故障可能會是一項艱難的任務(wù)。文本以超詳細的圖解說明了如何對 Kubernetes Deployment 進行故障排查,相信會對你有啟發(fā)。

          太長不看版:下面這張圖可以幫助你調(diào)試 Kubernetes 中的 Deployment。

          當(dāng)你想要在 Kubernetes 中部署應(yīng)用程序時,通常需要定義 3 個組件:
          • Deployment:創(chuàng)建 Pod 副本的方法;
          • Service:內(nèi)部負載均衡器,將流量路由到 Pod;
          • Ingress:描述流量如何從外部集群流向 Service;
          可以用下面的示意圖來簡單說明。

          Kubernetes 中應(yīng)用程序通過內(nèi)部和外部兩層負載均衡器暴露


          內(nèi)部負載均衡器叫 Service,外部負載均衡器叫 Ingress

          Pod 不是直接部署的。相反,Deployment 會創(chuàng)建 Pod,并監(jiān)控 Pod

          假設(shè)你希望部署一個簡單的 Hello World 應(yīng)用程序,這個應(yīng)用程序的 YAML 應(yīng)該類似于如下內(nèi)容:

          定義很長,很容易忽略組件之間的相互關(guān)系。例如:
          • 何時應(yīng)使用端口 80,何時應(yīng)使用端口 8080?
          • 是否應(yīng)該為每個服務(wù)創(chuàng)建一個新端口,以免沖突?
          • 標簽(label)名稱重要嗎?應(yīng)該保持標簽名稱一致嗎?
          在進行調(diào)試之前,讓我們回顧一下這三個組件之間的關(guān)系。我們從 Deployment 和 Service 開始。
          K8sMeetup
          連接 Deployment 和 Service

          令人驚訝的是,Deployment 和 Service 之間根本沒有連接相反,Service 直接指向 Pod,完全跳過了 Deployment。因此,你應(yīng)該關(guān)注的是 Pod 和 Service 之間是如何相互關(guān)聯(lián)的。

          請記住以下三件事:

          • Service selector 應(yīng)至少匹配 Pod 的一個標簽;

          • Service 的 targetPort 應(yīng)該與 Pod 的 containerPort 匹配;

          • Service 端口可以是任何數(shù)字。多個 Service 可以使用同一個端口,因為每個 Service 分配到的 IP 地址不同;

          下圖總結(jié)了如何連接端口:

          考慮通過 Service 暴露的以下 Pod

          在創(chuàng)建 Pod 時,需要為 Pod 中的每個容器定義端口 containerPort

          創(chuàng)建 Service 時,可以定義 porttargetPort。但是哪一個應(yīng)該和容器連接呢

          targetPortconatinerPort 需始終匹配

          如果容器暴露的是端口 3000,那么 targetPort 應(yīng)該也是 3000
          如果查看 YAML 文件,標簽和 port/targetPort 應(yīng)該是匹配的。

          那 Deployment 頂部的 track:canary 標簽?zāi)兀恳惨ヅ渖蠁幔?/span>
          這個標簽也屬于 Deployment,但 Service selector 不使用它來路由流量。換句話說,你可以放心地刪除它或為它分配別的值。
          matchLables selector 呢?它必須始終與 Pod 的標簽匹配,Deployment 用它來跟蹤 Pod。
          假設(shè)你做了正確的更改,你應(yīng)該如何測試它呢?可以使用以下命令檢查 Pod 是否具有正確的標簽:

          或者如果有屬于多個應(yīng)用程序的 Pod:

          其中 any-name=my-appany-name:my-app標簽。
          仍然有問題?你也可以連接到 Pod!可以在 kubectl 中使用 port-forward 命令來連接到 Service 并測試該連接。

          其中:
          • service/<service name> 是 service 的名稱(在當(dāng)前的 YAML 文件中是 "my service")。
          • 3000 是你想在計算機上開啟的端口。
          • 80 是由 Service 在 port 字段中暴露的端口。
          如果可以連接,說明設(shè)置正確。如果不能連接,很可能是標簽弄錯了或端口不匹配。
          K8sMeetup
          連接 Service 和 Ingress
          暴露應(yīng)用程序的下一步是配置 Ingress。Ingress 必須知道如何檢索 Service,然后連接 Pod 并將流量路由到它們。Ingress 按名稱和暴露的端口檢索正確的 Service。
          Ingress 和 Service 中必須匹配的有:
          1. Ingress 的 service.port 必須匹配 Service 的 port
          2. Ingress 的 service.name 必須匹配 Service 的 name
          下圖概括了如何連接這些 port:

          你已經(jīng)知道了 Service 會暴露一個 port

          Ingress 有一個字段叫做 ServicePort

          Service 的 port 和 Ingress 的 ServicePort 必須始終匹配

          如果你要把端口 80 分配給一個 Service,必須把 ServicePort 也改成 80

          實際操作中,你應(yīng)該看看這幾行:

          如何測試 Ingress 是否正常運行?
          你可以使用之前的策略,即 kubectl port-forward,但是要注意是連接到 Ingress controller 而不是 Service。
          首先,使用以下命令為 Ingress controller 檢索 Pod 名稱:

          驗證 Ingress Pod(可能在另一個命名空間中),描述它來檢索端口:

          最后,連接到 Pod:

          此時,你每次訪問計算機上的端口 3000 時,請求都會轉(zhuǎn)發(fā)到 Ingress controller Pod 的端口 80。
          如果訪問 http://localhost:3000,則應(yīng)找到提供網(wǎng)頁的應(yīng)用程序。
          K8sMeetup
          關(guān)于端口的總結(jié)
          快速總結(jié)一下哪些端口和標簽應(yīng)該匹配:
          • Service selector 應(yīng)該和 Pod 的標簽匹配;
          • Service 的 targetPort 應(yīng)該和 Pod 里面容器的 containerPort 匹配;
          • Service 端口可以是任意數(shù)字。多個 Service 可以使用同一個端口,因為不同的 Service 分配的 IP 地址不同;
          • Ingress 的 service.port 應(yīng)該和 Service 的 port 匹配;
          • Service 的名稱應(yīng)該和 Ingress 中 service.name 字段匹配;
          了解如何構(gòu)造 YAML 文件中的定義只是開始。出問題了怎么辦?可能 Pod 無法啟動了,或崩潰了。
          K8sMeetup
          3個步驟排查 kubernetes Deployment 故障
          在深入探究有故障的 Deploymen 時,必須明確 Kubernetes 是如何工作的。由于每個 Deployment 中都有三個組件,因此你應(yīng)該從下往上依次調(diào)試所有組件。
          • 確保 Pod 正在運行;
          • 著重關(guān)注讓 Service 將流量路由到 Pod;
          • 檢查 Ingress 的配置是否正確。

          應(yīng)該從最底層開始為 Deployment 做故障排查。首先,檢查 Pod 是否已就緒并在運行中

          如果 Pod 已就緒,應(yīng)該檢查 Service 是否能將流量路由到 Pod

          最后,檢查 Service 和 Ingress 之間的連接

          排查 Pod 故障

          大多數(shù)情況下,問題出在 Pod 本身。你應(yīng)該確保 Pod 已就緒并且在運行中。那么如何檢查呢?

          在上面的輸出中,最后一個 Pod 是就緒且在運行的,但是前兩個 Pod 既沒有就緒,也沒有運行。你怎么檢查哪里出了問題呢?
          以下 4 個命令可以對 Pod 做故障排查:
          • kubectl logs <pod name> 有助于檢索 Pod 中容器的日志;
          • kubectl describe pod <pod name> 對檢索與 Pod 相關(guān)的事件列表很有用;
          • kubectl get pod <pod name> 可提取 Kubernetes 中存儲的 Pod 的 YAML 定義;
          • kubectl exec -ti <pod name> bash 可在 Pod 中的一個容器運行一個交互式命令。
          那么你該用哪個命令呢?具體情況具體分析,通常這些命令要結(jié)合起來用。

          常見的 Pod 報錯

          Pod 可能會在啟動和運行時出現(xiàn)錯誤。
          啟動時的錯誤包括:
          • ImagePullBackoff
          • ImageInspectError
          • ErrImagePull
          • ErrImageNeverPull
          • RegistryUnavailable
          • InvalidImageName
          運行中的錯誤包括:
          • CrashLoopBackOff
          • RunContainerError
          • KillContainerError
          • VerifyNonRootError
          • RunInitContainerError
          • CreatePodSandboxError
          • ConfigPodSandboxError
          • KillPodSandboxError
          • SetupNetworkError
          • TeardownNetworkError
          有些錯誤的頻率很高。下面是最常見的錯誤以及解決方法。

          ImagePullBackOff

          當(dāng) Kubernetes 無法檢索 Pod 中某一個容器的鏡像時會報這個錯。常見的原因如下:
          • 鏡像名稱無效——比如,你拼錯了鏡像名稱,或者鏡像不存在。
          • 為鏡像指定了一個不存在的標簽。
          • 正在檢索的鏡像屬于私有 registry,Kubernetes 沒有訪問的憑證。
          前兩種情況可以通過改正鏡像名稱/標簽解決。對于最后一種情況,應(yīng)該將私有 registry 的訪問憑證通過 Secret 添加到 Kubernetes 中,并在 Pod 中引用它。
          官方文檔中有解決方法示例:https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/

          CrashLoopBackOff

          如果容器無法啟動,Kubernetes 將顯示 CrashloopBackOff 的信息。通常,在如下情況下容器無法啟動:
          • 應(yīng)用程序中存在錯誤,阻止了容器的啟動;
          • 容器配置有誤:StackOverFlow 上這個問題就是如此 https://stackoverflow.com/questions/41604499/my-kubernetes-pods-keep-crashing-with-crashloopbackoff-but-i-cant-find-any-lo
          • Liveness 探針失敗多次。
          你應(yīng)該嘗試檢索容器日志,查看為什么容器無法啟動。如果你無法查看日志是因為容器重啟得太快了,可以用如下命令:

          這個命令將打印前一個容器的錯誤消息。

          RunContainerError

          當(dāng)容器無法啟動時會出現(xiàn)這個錯誤。它甚至?xí)谌萜骼锏膽?yīng)用程序啟動之前出現(xiàn)。這個問題通常是由于如下錯誤配置造成的:
          • 掛載不存在的卷,如 ConfigMap 或 Secret;
          • 將只讀卷掛載為讀寫卷。
          可以使用 kubectl describe pod <pod-name> 命令檢查和分析這個錯誤。

          Pod 處于 Pending 的狀態(tài)

          當(dāng)你創(chuàng)建了一個 Pod,這個 Pod 處于 Pending 的狀態(tài)。為什么會這樣?
          假設(shè)你的調(diào)度器組件運行良好,原因可能有這些:
          • 集群沒有足夠的資源(例如 CPU 和內(nèi)存)來運行 Pod。
          • 當(dāng)前的命名空間具有 ResourceQuota 對象,創(chuàng)建 Pod 將使命名空間超過配額。
          • 該 Pod 綁定了一個處于 Pending 狀態(tài)的 PersistentVolumeClaim。
          最好的選擇是在 kubectl describe 命令中檢查事件

          對于因 ResourceQuota 造成的錯誤,可以使用以下方法檢查群集日志:

          Pod 處于未就緒狀態(tài)

          如果 Pod 正在運行但未就緒,則表示“就緒”探針失敗。
          當(dāng)“就緒”探針失敗時,則 Pod 未連接到服務(wù),并且沒有流量轉(zhuǎn)發(fā)到該實例。
          就緒探針故障是應(yīng)用程序相關(guān)的錯誤,因此應(yīng)該檢查 kubectl describe 中的“事件”以驗證錯誤。

          排查 Service 故障

          如果 Pod 在運行中且已就緒,但仍無法收到應(yīng)用程序的響應(yīng),就應(yīng)檢查 Service 的配置是否正確。
          Service 會根據(jù) Pod 的標簽將流量路由到 Pod。因此,應(yīng)該先檢查 Service 定位了多少個 Pod。
          可以通過檢查 Service 中的 Endpoint 來做到這一點:

          一個 Endpoint 是一對 <ip address:port> ,當(dāng) Service 定位到一個 Pod 后,至少應(yīng)該有一個 Endpoint。
          如果“Endpoint”部分為空,有兩種解釋:
          • 正在運行的 Pod 沒有正確的標簽(應(yīng)該檢查一下是否在正確的命名空間中);
          • Service 的 selector 標簽拼寫有誤。
          如果能看到 Endpoint 列表,但仍然無法訪問應(yīng)用程序,則 service 中的 targetPort 可能出問題了。如何測試 Service 呢?無論什么類型的 Service,都可以用 kubectl port-forward 來連接:

          其中:
          • <service-name> 是 Service 的名稱;
          • 3000 是你想在計算機上打開的端口;
          • 80 是 Service 暴露的端口。

          排查 Ingress 故障
          如果已經(jīng)到了這個階段,那么意味著:
          • Pod 在運行中且是就緒狀態(tài);
          • Service 可以分發(fā)流量分配到 Pod。
          但是你仍然看不到應(yīng)用程序的響應(yīng)。這很有可能是 Ingress 配置出錯了。
          因為 Ingress controller 是集群中的第三方組件,根據(jù) Ingress controller 的類型有不同的調(diào)試技巧。但是在進入到 Ingress 專用工具之前,可以先做些簡單的檢查。
          Ingress 使用 service.nameservice.port 連接到 Service。應(yīng)該檢查一下這些配置是否正確。
          可以用以下命令檢查 Ingress 配置是否正確:

          如果 Backend 列為空,那么配置中肯定出現(xiàn)了錯誤。如果在 Backend 列能看到 Endpoint,但仍然無法訪問應(yīng)用程序,問題可能是:
          • 將 Ingress 暴露到公網(wǎng)的方式;
          • 將集群暴露到公網(wǎng)的方式;
          可以通過直接連接到 Ingress pod 將基礎(chǔ)設(shè)施問題和 Ingress 隔離開。
          首先,為 Ingress controller (可能在其他的命名空間中)檢索 Pod:

          描述它來檢索端口:

          最后,連接到 Pod:

          到這一步,每次你訪問計算機上端口 3000,請求都會轉(zhuǎn)發(fā)到 Pod 中的端口 80。
          現(xiàn)在問題解決了嗎?
          • 如果解決了,那么就是基礎(chǔ)設(shè)施問題。你要看一下流量是如何路由到集群的。
          • 如果沒有解決,那么是 Ingress controller 的問題,你應(yīng)該調(diào)試 controller。
          如果還是不能讓 Ingress controller 正常,應(yīng)該開始調(diào)試它。
          Ingress Controller 有很多版本,使用較多的包括 Nginx,HAProxy,Traefik 等。查閱一下你使用的 Ingress Controller 的文檔,找到故障排除指南。
          因為 Ingress Nginx (https://github.com/kubernetes/ingress-nginx)是最流行的 Ingress Controller,因此我們在下一節(jié)介紹一些技巧。

          調(diào)試 Ingress Nginx

          Ingress-nginx 項目有一個針對 Kubectl 的官方插件:https://kubernetes.github.io/ingress-nginx/kubectl-plugin/
          你可以使用 kubectl ingress-nginx 來進行如下操作:
          • 檢查日志、Backend、證書等;
          • 連接到 Ingress;
          • 檢查當(dāng)前配置。
          可以嘗試以下三個命令:
          • kubectl ingress-nginx lint :用于檢查 nginx.conf;
          • kubectl ingress-nginx backend:用于檢查 Backend(類似 kubectl describe ingress <ingress-name>);
          • kubectl ingress-nginx logs:用于檢查日志。

          請注意,你可能需要使用 --namespace為 Ingress controller 指定正確的命名空間。

          K8sMeetup
          總結(jié)
          如果你不知從何下手,那么在 Kubernetes 中進行故障排查可能會是一項艱巨的任務(wù)。始終記得從下往上解決問題:從 Pod 開始,然后到 Service 和 Ingress。
          本文中的調(diào)試技巧也適用于其他地方,比如:
          • 出現(xiàn)故障的 Job 和 CronJob;
          • StatefulSet 和 DaemonSet。
          感謝 Gergely Risko, Daniel Weibel, Charles Christyraj 為本文提出的寶貴建議。
          原文鏈接:https://learnk8s.io/troubleshooting-deployments


          - END -

          公眾號后臺回復(fù)「加群」加入一線高級工程師技術(shù)交流群,一起交流進步。

           推薦閱讀 

          讓運維簡單高效,輕松搞定運維管理平臺 
          備份和遷移 Kubernetes 利器:Velero
          搭建一套完整的企業(yè)級 K8s 集群(v1.20,二進制方式)
          記一次 Kubernetes 機器內(nèi)核問題排查
          Shell 腳本進階,經(jīng)典用法及其案例
          Kubernetes 集群網(wǎng)絡(luò)從懵圈到熟悉
          記一次 Linux服務(wù)器被入侵后的排查思路
          5個面試的關(guān)鍵技巧,助你拿到想要的offer!



          點亮,服務(wù)器三年不宕機

          瀏覽 61
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  狂野欧美做受XXXX高潮 | AV2014天堂网 | 国内久久| 婷婷色在线观看 | 一区二区三视频 |