看懂狀態、警告與診斷
服務停擺或叢集出狀況時,去哪裡看原因,以及每個畫面讀的是哪些 Kubernetes 資料、用 kubectl 怎麼查到同樣的內容。
服務出問題時,先看 首頁 的 需要你處理,再點進服務的 概覽 看 出了什麼問題。這些畫面都只讀取叢集,不會修改任何東西。每一項都附有 修正 或 怎麼處理,要改設定時才會出現檢查變更的步驟。
下面依畫面說明它在哪裡、讀的是什麼,以及用 kubectl 怎麼查到同樣的資料。Zeabur 以你的權限讀取,讀不到的部分會在畫面上說明,例如 部分檢查需要你沒有的權限。
首頁:哪些服務停擺
Section titled “首頁:哪些服務停擺”首頁 的 需要你處理 列出目前有問題的服務。同一個原因造成的問題會合成一組,例如 25 個服務都卡在同一個映像檔拉不下來。
如果原因在叢集這一側,畫面會標成 叢集,寫出 起因 和 影響 的服務、網域和專案數。修好這個原因,這些服務就會一起恢復。Zeabur 會把下面幾種情況當成叢集的問題:
| 起因 | 判斷方式 | 影響範圍 |
|---|---|---|
| Ingress 控制器(Traefik 或 ingress-nginx)沒有就緒的副本 | 帶 app.kubernetes.io/name: traefik 等 label 的工作負載,想要副本卻一個都沒有就緒 | 這個 IngressClass 的所有網域 |
| cert-manager 沒有就緒的副本 | cert-manager 的控制器或 webhook 沒有就緒的副本 | 向它要憑證的 Ingress,憑證不會簽發或續約 |
| 叢集 DNS 沒有就緒的副本 | 帶 k8s-app: kube-dns 的工作負載 | 用名稱呼叫其他服務的服務 |
| metrics-server 沒有就緒的副本 | 帶 app.kubernetes.io/name: metrics-server 的工作負載 | 用量數字和自動擴縮停止 |
| 節點未就緒或不再回報 | 節點的 Ready 狀態是 False 或 Unknown | 在這個節點上有副本的服務 |
用 kubectl 查同樣的資料:
kubectl get nodeskubectl get deploy,daemonset -A -l app.kubernetes.io/name=traefikkubectl get deploy -A -l k8s-app=kube-dns「哪些服務受到影響」是 Zeabur 把 Ingress、節點和服務對起來算出的,kubectl 沒有直接對應的指令。
服務的「出了什麼問題」
Section titled “服務的「出了什麼問題」”服務有問題時,概覽 最上方會出現 出了什麼問題:一句話說原因,一句話說 怎麼處理,旁邊有 開啟日誌、調整記憶體、健康檢查 這類按鈕直接帶你去改。展開 依據 可以看到判斷用到的值,展開 原始錯誤 可以看到是哪個 副本、結束碼、重新啟動次數和容器的訊息。回報問題時,按 複製診斷 把全文貼上。
Zeabur 讀的是 kubelet 回報的容器狀態、副本的排程狀態、工作負載的狀況和事件,會判斷這些情況:
- 容器一直當機重啟,或記憶體用完被終止(結束碼 137)。
- 健康檢查一直失敗,或排程任務的一次執行以錯誤結束。
- 映像檔拉不下來。
- 少了機密變數或設定檔,或少了裡面的某個鍵,容器無法建立。
- 沒有節點有足夠的資源,副本排不進去。
- ResourceQuota 或 Pod Security 拒絕建立副本。
- 有人用名稱連到這個服務,卻沒有 Service 選到它的副本;Service 的
targetPort不是容器的連接埠;Service 沒有就緒的副本。
只算最近的失敗:容器正常跑了 10 分鐘以上,之前的重新啟動就不再列出,和 kubelet 重設退避時間的規則一樣。找不到已知原因時,畫面會寫出第一個沒就緒的副本卡在哪裡、最新的一則事件,以及還有幾個副本在服務。
用 kubectl 查同樣的資料:
kubectl -n shop get pods -l app.kubernetes.io/name=webkubectl -n shop describe pod <副本名稱>kubectl -n shop logs <副本名稱> --previouskubectl -n shop get events --field-selector involvedObject.name=<副本名稱>describe 的 Last State 有上一次結束的原因和結束碼,Events 有排程和拉映像檔的訊息。
專案頁和 叢集 → 概覽 的 缺少的設定,列出現在還沒出事、但容易出事的設定。每一項標 警告(可能造成停機或資料遺失)或 建議,附上依據的文件連結,以及 修正、安裝 或 設定備份 按鈕。例如:
- 容器沒有設定 CPU 和記憶體的保留量,或沒有記憶體上限。
- 服務沒有就緒檢查,「執行中」只代表容器已啟動。
- 資料寫在容器裡,沒有掛磁碟,重新部署就會消失。
- 磁碟沒有備份。
- 專案沒有連線規則,所有服務都能互相連線。
- 路由指向不存在的 Service,或叢集還在用已停止維護的 Ingress 控制器。
這些規則是 Zeabur 自己的檢查,kubectl 沒有對應的指令。個別項目可以自己查,例如看哪些容器沒有記憶體上限:
kubectl -n shop get deploy -o custom-columns=NAME:.metadata.name,MEMORY:.spec.template.spec.containers[*].resources.limits.memory叢集的「需要處理」
Section titled “叢集的「需要處理」”叢集 → 概覽 的 需要處理 列出影響整個叢集的事,例如 Kubernetes 版本已終止支援、kubelet 版本超出支援的差距、節點記憶體或磁碟快滿、節點未就緒,以及已安裝的元件有新版本。沒有問題時顯示 沒有需要處理的項目。
用 kubectl 查同樣的資料:
kubectl versionkubectl get nodes -o widekubectl describe node <節點名稱>describe node 的 Conditions 有 MemoryPressure、DiskPressure 和 Ready。版本的支援期限和元件的新版本,是 Zeabur 對照 Zeabur Catalog 得出的,kubectl 沒有對應的指令。
最近一小時的警告
Section titled “最近一小時的警告”叢集 → 概覽 的 最近一小時的警告 列出叢集本身的 Warning 事件:沒有 Namespace 的、關於節點的,以及 kube-system 這類 kube- 開頭 Namespace 裡的事件。專案的事件不在這裡,在服務 概覽 的 警告 和 事件 分頁。事件太多時只讀最新的 5,000 則,畫面會寫 只讀取了最新的 5,000 則事件。
kubectl get events -A --field-selector type=Warning,involvedObject.kind=Nodekubectl -n kube-system get events --field-selector type=Warning --sort-by=.lastTimestampKubernetes 預設只保留一小時的事件,更早的事件 kubectl 也查不到。
執行期警示(Falco)
Section titled “執行期警示(Falco)”裝了 Falco 之後,Falco 看到可疑的行為,例如在容器裡開 shell、讀取敏感檔案,就會留下一則警示。服務 概覽 的 執行期警示 列出這個服務的副本的警示,專案頁也看得到。不屬於任何 Namespace 的警示,例如節點本身的程序,會出現在 叢集 → 概覽 的 節點警示,沒有警示時這個區塊不會出現。
警示存在 falcosidekick 寫的 PolicyReport:有 Namespace 的放在那個 Namespace 的 falco-policy-report,其他的放在 ClusterPolicyReport falco-cluster-policy-report。從 Zeabur Catalog 安裝的 Falco 每份報告只留最新的 100 則,所以這裡是近期的警示,不是全部。
kubectl -n shop get policyreport falco-policy-report -o yamlkubectl get clusterpolicyreport falco-cluster-policy-report -o yaml每則警示在 results 裡,policy 是 Falco 規則名稱,severity 是嚴重程度,properties 有副本名稱和 Falco 的原始訊息。誰能讀 policyreports,由 Kubernetes 的 RBAC 決定。
要把警示送到 Slack 或信箱,見把叢集警示送到通知管道。
服務 概覽 的 網路 卡片,每個網域和私有位址各一行,寫出 可連線、無法連線 或 無法從叢集內確認。展開後是請求經過的每一步,每一步列出 預期 和 實際,有問題的那一步附 修正:
| 步驟 | Zeabur 檢查什麼 | 用 kubectl 或其他指令查 |
|---|---|---|
| DNS | 從 Zeabur 所在的地方查得到這個網域 | dig +short shop.example.com |
| 入口位址 | 查到的位址之一是 Ingress status.loadBalancer 的位址 | kubectl -n shop get ingress -o wide |
| Ingress 控制器 | 這個 IngressClass 的控制器有就緒的副本 | kubectl get ingressclass,再查控制器的 Deployment |
| 憑證 | spec.tls 底下的主機,cert-manager 的 Certificate 是 Ready | kubectl -n shop get certificate |
| 路由 | 控制器已在 Ingress 寫入位址;HTTPRoute 有 Accepted | kubectl -n shop describe httproute <名稱> |
| 私有位址 | 路由指到的 Service 存在、有那個連接埠,而且選到這個服務的副本 | kubectl -n shop get endpointslices -l kubernetes.io/service-name=web |
| 連接埠 | Service 的 targetPort 是容器的連接埠 | kubectl -n shop get svc web -o yaml |
| 就緒副本 | 至少一個副本已就緒 | kubectl -n shop get pods -l app.kubernetes.io/name=web |
私有位址 <服務>.<專案>.svc.cluster.local 只檢查最後三步。程式有沒有聽在 0.0.0.0 而不是 127.0.0.1,要進容器才看得到,這裡不檢查。DNS 查不到或查到別的位址時會寫 無法從叢集內確認:前面有 CDN 或 Proxy,或叢集內的 DNS 和外面看到的不同,都會這樣。
服務 網路 分頁的 連線規則 依 NetworkPolicy 算出哪些服務 允許、部分允許或被擋住連到這個服務,以及是哪條 規則 決定的。沒有規則選到這個服務時,畫面寫 沒有規則套用到這個服務,所以允許所有連線。 新增和移除規則見私有網路與連線規則。
kubectl -n shop get networkpolicykubectl -n shop describe networkpolicy <名稱>describe 列出每條規則選到的副本和允許的來源。把多條規則合起來、換算成「哪個服務能連到哪個服務」是 Zeabur 算的,kubectl 沒有對應的指令。
修好之後:
- 服務 概覽 的 出了什麼問題 消失,網路 卡片每一行都是 可連線。
- 叢集 → 概覽 顯示 沒有需要處理的項目。
kubectl -n shop get pods的副本都是Running,READY欄滿了。