最近一系列的文章重點介紹了Kubernetes部署失敗的10種常見原因。這些原因涵蓋了從缺少輸入和錯誤輸入,到超出資源限制。在大多數情況下,kubectl describe命令可以幫助確定背后的原因。
Kubernetes部署的無效輸入包括指定不存在的容器鏡像,或者指定沒有訪問權限的容器鏡像。因為默認注冊表是Dockerhub,所以如果使用了其它注冊表(如Amazon ECR或Quay.io),則需要指定注冊表URL。私有注冊表在訪問鏡像時需要相關證書。 當要拉取的標簽名稱無效時,鏡像拉取也可能遇到錯誤。比如在latest標簽不存在但鏡像存在時,鏡像拉取就會失敗(如果沒有特別指定,“latest”就是默認標簽)。此外網絡問題也可能會導致錯誤。這類情況下的錯誤消息彼此間十分相似,因此需要更深入的檢查以確定確切的原因。
Kubernetes中的部署失敗常常導致特定的Pod無法啟動。可以使用“kubectl describe pod
如果把Kubernetes中的默認策略設置為不總是從注冊表中拉取,則即使提交了更新后的改動并推送鏡像,這些改動也可能不可見。在產品中推薦的解決方法是為每個鏡像分配唯一標簽,并在拉取請求中使用這些標簽。此外在部署配置中指定不存在的持久卷(persistent volumes)也可能導致部署失敗。
另外兩種無效輸入是缺少程序運行時ConfigMap或Secrets,以及無效的Spec對象。 ConfigMap是一組鍵值對的映射,該組鍵值對屬于應用程序所需的配置數據。ConfigMap可以被指定為CLI參數,環境變量,或已安裝卷中的文件。如果缺少了這些信息,那么Pod創建會停止,并且狀態被設置為“RunContainerError”。Secrets是一種用于存儲敏感數據(如證書)的機制。Secrets缺失將導致類似的問題。ConfigMap和Secrets都可以安裝為卷,如果安裝失敗,則容器創建停止,事件日志的狀態停留在“ContainerCreating”。
另一種部署失敗的原因是無效的Kubernetes Spec對象,這些無效對象是由YAML中的縮進錯誤或拼寫錯誤所導致。通過基于CLI的YAML驗證和使用--dry-run參數,我們可以很容易地避免此類錯誤,如下所示:
kubectl create -f test-application.deploy.yaml --dry-run --validate=true
但該方法需要運行Kubernetes集群。移除對集群依賴的工作正在進行當中,同時也會提供對客戶端驗證的支持。YAML驗證可以被添加到源控制系統中,成為預提交鉤子(pre-commit hook)的一部分。
另一類失敗的Kubernetes部署是因為超出資源限制。Pod和容器都有指定的CPU和內存限制。超出這些限制將導致無法創建Pod。調試該問題需要花一點精力。命令“kubectl describe deployment
部署失敗也可能是因為超出資源配額。當團隊間共享節點數固定的集群時,這種資源配額機制可以用來限制每個命名空間的資源消耗。資源包括Pod,服務和部署,以及計算資源的總量。 同樣,在這種情況下,“kubectl describe”命令能夠幫助我們挖掘出實際的錯誤消息。
當節點未充分使用資源時或者由于資源不足而無法運行Pod時,集群自動調整程序(cluster autoscaler)會自動調整Kubernetes集群大小。如果該自動調整程序未被啟用,那么超出資源配額的部署將會失敗,并且Pod停留在“Pending”狀態。 事件日志將顯示出實際短缺的資源(由于該資源短缺而導致部署失敗)。
應用程序行為的意外更改可能以不同的方式引起部署失敗。應用程序崩潰常常會導致啟動錯誤,該錯誤的錯誤消息是“CrashLoopBackOff”。應用程序日志可以幫助解決此問題。此外,如果配置錯誤或者響應超時,Liveness/Readiness探測可能會停止工作,該探測被Kubernetes用來檢測服務的健康情況。例如,URL健康檢查可能在應用程序中已發生變更,或者由于數據庫變動,URL健康檢查可能無法正常工作。某些URL可能需要一段時間才能響應Readiness檢查,這可能會超時并導致部署失敗。
文章的作者已開源一個腳本,當創建失敗時,該腳本可以在日志里打印出有用的相關信息。
查看英文原文:Common Reasons for Failed Kubernetes Deployments