)
Kubernetes Terminated with exit code 1 錯誤排查指南從原理到實戰refine 項目工程實踐【免費下載鏈接】refineA React Framework for building internal tools, admin panels, dashboards B2B apps with unmatched flexibility.項目地址: https://gitcode.com/GitHub_Trending/re/refine本篇技術指南源自 refine 項目技術博客的工程實踐沉淀系統講解 Kubernetes 中 Terminated with exit code 1 錯誤的完整排查思路從退出碼的底層原理出發覆蓋應用運行時錯誤、容器配置問題、健康檢查失敗、依賴缺失、資源限制與信號處理六大常見誘因并給出從kubectl logs到系統級/網絡級診斷的完整命令工具箱與 10 條規避最佳實踐。讀完本文你將掌握一套可復制的排查流程并能結合本倉庫中 Helm 部署模板 與 示例 Dockerfile 的實際配置從源頭預防容器以非零退出碼反復崩潰。理解 Exit Code 1什么是退出碼Exit Code與任何 Unix 類系統一致Kubernetes 容器內的進程停止運行時容器引擎會向 Kubernetes 上報一個退出碼exit code。退出碼 0 通常表示成功而任何非零值例如 1都表示出錯。退出碼 1 的出現通常表明發生了一次錯誤——它告訴你容器化應用的執行出了問題但不會直接告訴你問題是什么。這也是排查工作的起點退出碼 1 本身只是一個信號真正的根因需要結合日志、事件和配置進一步定位。相關延伸refine 技術博客中還有一篇姊妹文章 《Kubernetes Exit Code 137》其中給出了一張常見退出碼對照表Exit Code 0 表示開發者主動終止、Exit Code 125/126/127 分別對應docker run調用失敗、命令無法調用、命令指向不存在的文件或目錄。退出碼 1 在表格中的定義正是容器因應用錯誤或鏡像規格引用錯誤而停止。導致 Exit Code 1 的常見場景應用運行時錯誤Application Runtime Errors執行錯誤例如運行時異常或關鍵任務未能完成都會導致應用以退出碼 1 退出。應用自身的內部自檢一旦發現無法正常運行通常就會觸發這一退出# 示例 Python 片段條件不滿足時以退出碼 1 退出 if not critical_service_available(): print(Critical service is not available. Exiting.) exit(1)容器配置問題Container Configuration Issues容器 spec 中的 command 或參數配置錯誤會導致容器立即終止。例如command 中指定的命令不存在或拼寫錯誤容器會以退出碼 1 退出# Kubernetes YAML 片段command 中 exitt 是拼寫錯誤 containers: - name: myapp image: myapp:latest command: [/bin/sh, -c, exitt 1] # exitt is a typo健康檢查失敗Failed Health Checks反復未通過 liveness存活探針或 readiness就緒探針檢查的容器會被 Kubernetes 終止。雖然這通常表現為重啟而非直接返回退出碼 1但它會讓容器始終無法保持運行狀態是崩潰循環的重要誘因。容器內依賴問題Dependency Issues Inside Containers容器化應用的依賴若未滿足——例如缺少動態庫、外部服務不可達——應用會以退出碼 1 退出。資源限制約束Resource Limit Constraints容器有資源上限超出后可能被終止。不過這種情況通常表現為OOMKilled退出碼 137而非退出碼 1除非你的應用被顯式設計為用自定義退出碼處理此類場景。信號處理不當Improper Signal Handling如果應用不能妥善處理終止信號SIGTERMKubernetes 優雅關停容器的嘗試可能以退出碼 1 的粗暴退出告終。初步排查步驟第一步查看容器日志尋找直接線索以退出碼 1 退出的容器應當首先檢查日志。日志通常包含容器進程的輸出能直接揭示進程退出的原因。使用kubectl logs查看容器日志kubectl logs your-pod-name將your-pod-name替換為你的 Pod 名稱。如果 Pod 內有多個容器需通過-c參數指定容器名kubectl logs your-pod-name -c pods-container-name示例輸出如下Error: Invalid configuration at /app/server.js:20:21 at Layer.handle [as handle_request] (/app/node_modules/express/lib/router/layer.js:95:5) ... Process exited with status code 1這段輸出表明配置存在問題這是一個很好的調查切入點。專家提示容器多次以非零退出碼如exit code 1退出會讓 Kubernetes 進入CrashLoopBackOff狀態——退出碼 1 反復出現與崩潰循環互為表里。refine 博客中的另一篇文章 《Kubernetes CrashLoopBackOff 詳解》 專門講解了這一狀態Kubernetes 會以指數級退避延遲嘗試重啟失敗的容器多次失敗后即進入CrashLoopBackOff。排查時若在kubectl describe pod輸出中看到Backoff、Failed、CrashLoopBackOff等關鍵字說明容器已多次以非零退出碼崩潰需要結合日志定位根因。第二步核對容器與應用配置有時是容器或應用的配置本身出錯。檢查 Kubernetes 清單和應用配置文件。查看 Deployment 的完整 YAMLkubectl get deployment your-deployment-name -o yaml查看特定 Pod 的配置kubectl get pod your-pod-name -o yaml重點關注環境變量、command 參數、volume 掛載是否存在配置錯誤。專家提示除了kubectl logs還可以檢查與 Pod 關聯的事件events尋找終止前的異常記錄kubectl describe pod pod-name該命令提供 Pod 生命周期事件的詳細信息包括導致終止的錯誤。高級診斷技術A. 應用專屬調試工具每種編程語言或框架都有自己的調試工具可用于深入理解錯誤性質。以 Node.js 應用為例# 在容器中安裝 node-inspect 并以 inspect 標志啟動應用 kubectl exec -it pod-name -- npm install -g node-inspect kubectl exec -it pod-name -- node --inspect-brk0.0.0.0:9229 app.js記得在 Dockerfile 與 Kubernetes deployment 中暴露調試端口如果尚未暴露# Dockerfile 片段 EXPOSE 9229# Kubernetes deployment 片段 ports: - containerPort: 9229 name: debug protocol: TCPB. 網絡與依賴檢查檢查應用與外部服務或數據庫的連接配置是否正確。可以使用kubectl exec在 Pod 內執行網絡檢查# 檢查數據庫是否可達 kubectl exec pod-name -- nc -zv db-service-name db-port如果使用 ORM 或數據庫客戶端開啟詳細日志以捕獲連接錯誤細節// 以使用 Sequelize 的 Node.js 應用為例 const sequelize new Sequelize(database, username, password, { host: db-service-name, dialect: mysql, logging: console.log, });C. 容器環境問題Docker 或 Kubernetes 層面的容器環境問題也可能導致退出碼 1。常見陷阱包括環境變量配置錯誤文件路徑或權限不正確資源限制被觸達內存、CPU診斷命令查看已終止容器的日志# 獲取已終止容器的日志 kubectl logs your-pod-name --previous常見容器設置陷阱環境變量確保所有必需的環境變量都已設置。查看當前環境變量kubectl exec your-pod-name -- env文件權限如果應用需要讀寫容器內文件權限可能引發問題# 通過以下命令檢查文件權限 kubectl exec your-pod-name -- ls -l /path/to/check資源限制Kubernetes 允許為容器設置資源限制若限制過低應用可能被終止# Kubernetes deployment 片段設置資源限制 resources: limits: cpu: 1 memory: 1024Mi系統與網絡層面的排查當 Pod 以 Terminated with exit code 1 終止時通常意味著應用級錯誤但同樣需要排查可能間接引發問題的系統與網絡層面。系統級日志優先檢查系統日志。資源不足是進程被突然終止的典型原因。排查步驟找到 Pod 所在的 Kubernetes 節點使用kubectl describe node node-name獲取節點狀態摘要檢查是否存在指示資源瓶頸的事件或條件檢查各項資源的使用情況內存free -hCPUtop或htop磁盤df -h提示密切關注OOMKilled事件它表示 Pod 因內存不足Out Of Memory被殺。若dmesg或/var/log/syslog中出現Out of memory: Killed process就是明確的線索。網絡配置檢查網絡配置它們可能中斷與 Pod 或容器間的通信。排查步驟運行以下命令驗證 Kubernetes 網絡策略kubectl get networkpolicies --all-namespaces確認 Pod 的網絡接口配置與集群網絡一致檢查節點上是否有防火墻規則阻止流量可用以下命令驗證sudo iptables -L -nsudo ufw status專家提示留意防火墻日志中的丟包記錄或用tcpdump追蹤網絡數據包。防火墻規則防火墻也可能阻斷應用需要路由的流量。確保防火墻規則與應用的網絡需求不沖突。排查步驟用iptables或你的防火墻管理工具列出當前規則將應用所需端口與防火墻放行端口交叉比對檢查問題出現前后防火墻規則是否有近期改動。列出 iptables 規則sudo iptables -S規避與修復此錯誤的最佳實踐校驗容器入口點Entrypoint確保入口腳本可執行且 shebang 行#!/bin/bash正確。入口點未找到或不可執行時常見報錯為No such file or directory。關于 ENTRYPOINT 的 shell 形式與 exec 形式的差異exec 形式不會經過/bin/sh -c的 shell 解析信號處理更可靠可參考 refine 博客文章 《How to Use Docker EntryPoint》。檢查應用依賴確認所有必需的庫與依賴都存在。容器內缺少依賴常導致Library not found類錯誤。審查應用代碼復查近期代碼變更。日志中的Undefined variable、Syntax error等往往指向新代碼問題。配置存活探針Liveness Probes在 Kubernetes 中配置存活探針。kubectl get events顯示 Pod 頻繁重啟通常意味著存活檢查失敗。分析日志用kubectl logs pod-name獲取即時錯誤輸出。Permission denied信息可能表示執行權限問題。監控資源使用為內存與 CPU 設置告警及時發現超用。狀態為OOMKilled的 Pod 表示已超出內存限制。優雅處理信號確保應用妥善處理SIGTERM等信號以實現正常關停。日志顯示Signal received: SIGTERM卻未優雅退出即為信號處理不當。避免硬編碼路徑優先使用相對路徑或環境變量。File not found錯誤常因硬編碼路徑在容器文件系統中不存在導致。使用 Init 容器利用 init 容器在主應用啟動前準備好環境。kubectl describe pod pod-name中 init 容器的失敗日志表示環境準備環節有問題。本地先行測試先在本地運行容器以發現差異。Environment variable not set錯誤常源于本地與容器環境的差異。結合倉庫實踐從 refine 項目的 Helm chart 與 Dockerfile 看穩定性配置為了把上述排查經驗轉化為預防措施本倉庫中實際運行著兩個可直接對照的容器化示例可以作為健康配置的參照。探針與資源限制文檔站的 Helm 模板documentation/k8s/refine-documentation/templates/deployment.yaml 中refine-documentation服務的容器配置同時定義了存活探針與就緒探針均通過 HTTP GET 請求根路徑完成檢查livenessProbe: httpGet: path: / port: http readinessProbe: httpGet: path: / port: http這正是最佳實踐第 4 條配置存活探針的落地寫法當容器內部服務無法響應時探針會讓 Kubernetes 及時重啟容器從而將反復以退出碼 1 崩潰這類問題收斂為可觀測、可自愈的探針失敗事件。資源限制在 values.yaml 中以模板變量形式定義注釋中給出了cpu: 100m/memory: 128Mi的示例并配合 hpa.yaml 中的targetCPUUtilizationPercentage、targetMemoryUtilizationPercentage實現按 CPU/內存利用率的水平擴縮容。對照本文的資源排查章節為容器設置合理的requests與limits正是避免因資源不足被強制終止OOMKilled的關鍵手段。多階段構建與 CMD真實項目 Dockerfileexamples/with-material-ui-vite/Dockerfile 采用多階段構建base → deps → builder → runner并在 runner 階段設置USER refine后以CMD [serve]exec 形式啟動靜態文件服務examples/store/Dockerfile 同樣在構建后切換到USER refine通過CMD [node, ./examples/store/server.js]以 exec 形式啟動 Next.js standalone 服務并顯式聲明EXPOSE 3000與ENV PORT 3000。對照本文最佳實踐這三處細節都對應著具體風險點多階段構建減少鏡像層數與體積從源頭避免容器內依賴缺失/不完整Library not found、No such file or directoryCMD 使用 exec 形式讓容器主進程直接成為 PID 1避免 shell 包裝導致SIGTERM無法直達應用進程對應優雅處理信號此點與 《How to Use Docker EntryPoint》 中exec 形式直接運行二進制、不經過 shell 解析的原理一致**顯式ENV PORT**避免因環境變量未設置導致的應用啟動失敗對應檢查應用依賴/環境變量。這些配置共同降低了容器以退出碼 1 啟動即退出的概率也讓本地測試通過、部署后失敗的差異問題更容易暴露。關聯排查退出碼 1 與 137、CrashLoopBackOff 的區分排查退出碼 1 時建議同步了解它的兩個鄰居以免誤判方向Exit Code 137OOMKilled由操作系統 OOM killer 觸發本質是128 9(SIGKILL)代表容器超出內存限制被強制殺死根因通常是內存泄漏、請求/限制配置不當或流量突增。詳見 《Kubernetes Exit Code 137》。與退出碼 1 不同137 不指向應用邏輯錯誤而是指向內存資源管理問題。CrashLoopBackOff這是容器反復以非零退出碼崩潰后的終態表現本身不是一種根因而是診斷入口。詳見 《Kubernetes CrashLoopBackOff 詳解》。一張快速的判斷路線圖看到非零退出碼 → 先kubectl logs看應用自身輸出 → 再kubectl describe pod看事件與狀態區分OOMKilled、Backoff、Failed→ 若為 137 則轉向內存排查若為 1 則按本文的配置、依賴、信號、入口點檢查清單逐項核對。結論本文系統梳理了 Kubernetes 中 Terminated with exit code 1 錯誤的常見成因與排查流程。無論是 YAML 中不經意的拼寫錯誤、資源瓶頸還是應用內部錯誤都可以按照本文給出的步驟逐層定位并解決。退出碼 1 只是一個入口信號真正的價值在于建立從日志 → 事件 → 配置 → 系統/網絡 → 代碼與鏡像的完整排查鏈路同時參照本倉庫中 Helm 部署模板、values.yaml 與兩個 Dockerfile 的實踐——配置探針、設定資源限制、多階段構建、exec 形式 CMD、顯式環境變量——就能在問題發生之前先把容器從易崩潰變為可自愈、可觀測。【免費下載鏈接】refineA React Framework for building internal tools, admin panels, dashboards B2B apps with unmatched flexibility.項目地址: https://gitcode.com/GitHub_Trending/re/refine創作聲明:本文部分內容由AI輔助生成(AIGC),僅供參考