您可以診斷資源爭用情形,解決 Google Distributed Cloud 中容器速度緩慢、效能不佳或終止的問題。常見原因包括 CPU 節流、OOMKilled Pod、etcd 和 API 伺服器延遲,以及 vSphere CPU 或儲存空間瓶頸。找出原因後,您就能調整工作負載、節點和 VM 的資源,確保叢集穩定運作。
總覽
Google Distributed Cloud 有時可能會發生資源爭用情形,導致容器速度變慢、效能不佳或終止。容器的 CPU 或記憶體用量過高,可能導致這種情況。
CPU 和記憶體管理機制的運作方式
CPU:
- 系統會根據 Pod 中容器指定的 CPU 要求,將 Pod 排定至節點。
- Pod 中的容器無法使用超過容器指定的 CPU 限制
- 容器的 CPU 用量會受到 CPU 限制。
- 如果 CPU 用量在節點層級受到限制,系統會自動根據要求,按比例為容器分配 CPU 週期。
進一步瞭解如何排定含有資源要求的 Pod。
記憶體使用量:
- 系統會根據 Pod 中容器指定的記憶體要求,將 Pod 排定至節點。
- 容器使用的記憶體不得超過容器指定的上限。
- 如未指定記憶體限制,容器可能會耗盡節點上的所有可用記憶體。系統可能會觸發 OOM-Killer (Out Of Memory Killer),並淘汰低優先順序的 Pod。
如要瞭解詳情,請參考下列資源:
問題
容器速度變慢
CPU 爭用問題可能會導致容器速度變慢。可能原因如下:
容器的 CPU 使用率偏高:
如果容器未取得與 CPU 要求成比例的 CPU 週期,或 CPU 要求設定低於容器所需,容器速度可能會變慢。因此,請檢查容器的 CPU 限制與 CPU 使用率比率。
在 Google Cloud 控制台>「Monitoring」>「Metrics Explorer」中,於「PromQL editor」(PromQL 編輯器) 執行下列查詢:
avg_over_time({
"__name__"="kubernetes.io/anthos/container/cpu/limit_utilization",
"monitored_resource"="k8s_container",
"cluster_name"="CLUSTER_NAME",
"container_name"="CONTAINER_NAME",
"pod_name"="POD_NAME",
"namespace_name"="NAMESPACE_NAME"
}[${__interval}])
接著,請執行下列其中一項動作:
- 如果這個比率偏高 (>=0.8),表示容器的 CPU 限制偏低,Kubernetes 會限制容器的 CPU 週期,將 CPU 用量維持在限制範圍內。如要解決這個問題,請提高容器的 CPU 限制。
- 如果這個比率不高 (<0.8),請檢查節點的 CPU 使用率是否偏高。
節點的 CPU 使用率偏高
如果 Pod 的任何個別容器,CPU 限制與使用率的比率不高,則可能是節點沒有足夠的 CPU 週期,可分配給在節點上執行的容器組。請按照下列步驟,查看實際 CPU 使用率與節點上可分配 CPU 的比率:
取得運作緩慢的 Pod 節點:
kubectl get pod –kubeconfig CLUSTER_KUBECONFIG --namespace NAMESPACE POD --output wide在 Google Cloud 控制台 >「Monitoring」 >「Metrics explorer」中,在 PromQL 編輯器中執行下列查詢:
avg_over_time({ "__name__"="kubernetes.io/anthos/node/cpu/allocatable_utilization", "monitored_resource"="k8s_node", "cluster_name"="CLUSTER_NAME", "node_name"="NODE_NAME" }[${__interval}])如果這個比率偏高 (>=0.8),表示節點的 CPU 週期不足,且訂閱過度。請按照下列步驟,檢查該節點上所有其他 Pod 的 CPU 用量,並調查是否有其他容器使用更多 CPU。
- 取得節點上的所有 Pod:
kubectl get pods --all-namespaces -o wide --field-selector spec.nodeName=NODE_NAME- 查看各容器的 CPU 使用率:
avg_over_time({ "__name__"="kubernetes.io/anthos/container/cpu/limit_utilization", "monitored_resource"="k8s_container", "cluster_name"="CLUSTER_NAME", "container_name"="CONTAINER_NAME", "pod_name"="POD_NAME", "namespace_name"="NAMESPACE_NAME" }[${__interval}])如果節點上有其他容器使用大量 CPU,請提高運作緩慢容器的 CPU 要求和限制。這項操作會在其他節點上重新建立 Pod,以取得所需的 CPU 週期。
如果系統 Pod 運作緩慢,請與 Google 支援團隊聯絡。
vSphere 層級的 CPU 超額訂閱
如果節點或 Pod 的 CPU 消耗量不高,但容器速度仍緩慢,則 VM 可能在 vSphere 層級超額訂閱。因此,節點無法從基礎虛擬化取得預期的 CPU 週期。
請按照這些步驟,檢查 VM 是否超額訂閱。如果偵測到超額訂閱,請嘗試下列做法:
- 將部分 VM 移至其他主機。
- 評估並減少主機上每個 VM 的 vCPU 數量。
- 為叢集 VM 分配更多資源。
- 提高容器的 CPU 要求和限制。這項操作會在其他節點上重新建立 Pod,以取得所需的 CPU 週期。
Pod 因記憶體不足而終止
如果容器發生記憶體流失,或記憶體要求和限制設定不當,Pod 可能會因記憶體不足而終止。可能原因如下:
容器記憶體用量偏高
如果 Pod 中的任何容器過度耗用分配的記憶體總量,Pod 可能會因 OOM 而終止。因此,請檢查容器的記憶體要求與記憶體限制比率。
在 Google Cloud 控制台 >「Monitoring」 >「Metrics explorer」中,在 PromQL 編輯器中執行下列查詢:
avg_over_time({
"__name__"="kubernetes.io/anthos/container/memory/limit_utilization",
"monitored_resource"="k8s_container",
"memory_type"="non-evictable",
"cluster_name"="CLUSTER_NAME",
"container_name"="CONTAINER_NAME",
"pod_name"="POD_NAME",
"namespace_name"="NAMESPACE_NAME"
}[${__interval}])
接著,請執行下列其中一項動作:
- 如果這個比率偏高 (>= 0.8),請提高容器的記憶體限制。
- 如果這個比率不高 (<0.8),請檢查節點的記憶體用量是否偏高。
節點記憶體用量偏高
如果節點上執行的所有 Pod 記憶體用量超過可用記憶體,Pod 可能會因 OOM 而終止。因此,請檢查節點上的 MemoryPressure 條件是否為 True。
執行下列指令,並檢查
Conditions區段:kubectl describe nodes --kubeconfig CLUSTER_KUBECONFIG NODE-NAME如果
MemoryPressure條件為True,請檢查節點的記憶體使用率:avg_over_time({ "__name__"="kubernetes.io/anthos/node/memory/allocatable_utilization", "monitored_resource"="k8s_node", "memory_type"="non-evictable", "cluster_name"="CLUSTER_NAME", "node_name"="NODE_NAME", }[${__interval}])如果這個比率偏高 (>= 0.8),代表節點沒有足夠的記憶體可分配給 Pod,這可能是因為某些程序或其他 Pod 消耗大量記憶體。
在 Google Cloud 控制台 >「Monitoring」 >「Metrics Explorer」中,於 PromQL 編輯器執行下列查詢,檢查節點上容器的記憶體用量:
avg_over_time({ "__name__"="kubernetes.io/anthos/container_memory_usage_bytes", "monitored_resource"="k8s_node", "cluster_name"="CLUSTER_NAME", "node_name"="NODE_NAME", }[${__interval}])如果容器的記憶體用量偏高,請檢查容器的運作情形,或視需要提高容器的記憶體要求。
如果系統 Pod 耗用大量記憶體,請與 Google 支援團隊聯絡。
此外,您可以在 Google Distributed Cloud 中啟用自動調度資源功能,根據工作負載需求自動擴充及縮減節點集區。
瞭解如何啟用自動配置器。
Etcd 問題
有時,Anthos clusters on VMware 可能會因 etcd 伺服器問題而發生容器故障,您可能會看到下列情況:
重複的 API 伺服器記錄,格式如下:
etcdserver: request timed out和etcdserver: leader changed重複的 etcd 記錄,格式如下:
W | wal: sync duration of 2.466870869s, expected less than 1s和W | etcdserver: read-only range request * took too long
可能原因如下:
CPU 節流
etcd 伺服器 Pod 和/或 etcd 伺服器執行所在的節點上,CPU 節流可能會導致 etcd 伺服器速度緩慢。請參閱「容器速度變慢」一節中的步驟,檢查是否有任何 CPU 爭用問題。
如果偵測到 ectd 伺服器 Pod 或節點發生 CPU 爭用,請為使用者叢集的控制層節點新增 CPU。使用 gkectl update 編輯使用者叢集設定檔中的 cpus 欄位。
Etcd Pod OOMkilled
etcd Pod 可能會因資源爭用問題而遭到 OOMKilled。請參閱「Pod 遭到 OOMkilled (Out of Memory-Killed)」一節中的步驟,檢查 etcd 伺服器 Pod 和/或 etcd 伺服器執行所在的節點是否有任何記憶體爭用問題。
如果偵測到 etcd Pod 的 OOMkill,請增加使用者叢集控制層節點可用的記憶體。使用 gkectl update 編輯使用者叢集設定檔中的 memoryMB 欄位。
磁碟速度緩慢
如果 etcd 伺服器 Pod 或節點的 CPU 或記憶體用量沒有問題,etcd 速度緩慢的原因可能是基礎資料儲存庫速度緩慢或受到限制。
確認是否發生下列問題:
如要檢查 etcd 伺服器是否花費過多時間讀取/寫入基礎磁碟,請按照下列步驟操作:
擷取 etcd 記錄:
kubectl –kubeconfig ADMIN_CLUSTER_KUBECONFIG logs -n ETCD_POD_NAMESPACE ETCD_POD請尋找下列模式的項目,偵測 etcd 是否需要過長時間才能從磁碟讀取:
W | etcdserver: read-only range request "key:\"/registry/configmaps/default/clusterapi-vsphere-controller-manager-leader-election\" " with result "range_response_count:1 size:685" took too long (6.893127339s) to execute請尋找下列模式的項目,偵測 etcd 是否需要過長時間才能寫入磁碟:
W | wal: sync duration of 2.466870869s, expected less than 1s
如果 etcd 記錄中頻繁出現上述任一或兩種記錄模式,表示磁碟速度緩慢。接著,檢查資料儲存庫和磁碟的效能。
如要查看 etcd 指標,請按照下列步驟操作:
擷取 etcd wal 同步延遲時間:
在 Google Cloud 控制台 >「Monitoring」 >「Metrics explorer」中,在 PromQL 編輯器中執行下列查詢:
histogram_quantile(0.99, sum by ("le") ( increase({ "__name__"="kubernetes.io/anthos/etcd_disk_wal_fsync_duration_seconds_bucket", "monitored_resource"="k8s_container", "cluster_name"="CLUSTER_NAME", "pod_name"="POD_NAME", "namespace_name"="NAMESPACE_NAME" }[${__interval}]) ) )擷取 etcd 寫入延遲時間:
在 Google Cloud 控制台 >「Monitoring」 >「Metrics explorer」中,在 PromQL 編輯器中執行下列查詢:
histogram_quantile(0.99, sum by ("le") ( increase({ "__name__"="kubernetes.io/anthos/etcd_disk_backend_commit_duration_seconds", "monitored_resource"="k8s_container", "cluster_name"="CLUSTER_NAME", "pod_name"="POD_NAME", "namespace_name"="NAMESPACE_NAME" }[${__interval}]) ) )
如果
etcd_disk_wal_fsync_duration_seconds的p99持續超過 10 毫秒,和/或etcd_disk_backend_commit_duration_seconds的p99持續超過 25 毫秒,表示磁碟速度緩慢。接著,檢查資料儲存庫和磁碟的效能。
VM 磁碟的讀取/寫入延遲時間
請按照下列步驟,查看 VM 虛擬磁碟的讀取/寫入延遲時間
找出 etcd Pod 速度緩慢的節點:
kubectl –kubeconfig ADMIN_CLUSTER_KUBECONFIG get pods -n ETCD_POD_NAMESPACE ETCD_POD -owide登入 vSphere,然後選取上一步中找到的 VM: 在 vSphere 中,依序前往「Monitor」(監控) >「Performance」(效能) >「Advanced」(進階),然後在「View」(檢視) 區段中選取「Virtual Disk」(虛擬磁碟),找出虛擬磁碟的讀取和寫入延遲時間。
如果虛擬磁碟讀取/寫入延遲時間過長:
詳情請參閱「資源調度最佳做法」。
API 伺服器問題
如果 Google Distributed Cloud 中的容器與 API 伺服器通訊時發生延遲,或 Kubectl 指令失敗或回應時間過長,可能表示 API 伺服器發生問題。
可能原因如下:
大量 API 要求
如果 API 伺服器收到的要求頻率和數量過高,回應速度可能會變慢。即使 API 伺服器開始限制要求,回應時間仍可能偏慢。因此,請檢查 API 伺服器上的 API 要求頻率。
在 Google Cloud 控制台 >「Monitoring」 >「Metrics explorer」中,在 PromQL 編輯器中執行下列查詢:
sum by (verb) (
rate({
"__name__"="kubernetes.io/anthos/apiserver_request_total",
"monitored_resource"="k8s_container",
"cluster_name"="CLUSTER_NAME",
"pod_name"="APISERVER_POD_NAME",
"namespace_name"="NAMESPACE_NAME"
}[${__interval}])
)
如果 API 要求數量異常增加,請使用 Cloud 稽核記錄,找出可能過於頻繁查詢 API 伺服器的 Pod。
- 如果是系統 Pod,請與 Google 支援團隊聯絡。
- 如果是使用者 Pod,請進一步調查,判斷 API 要求是否符合預期。
CPU 節流
API 伺服器的要求比率偏高,可能會導致 CPU 節流。接著,API 伺服器 Pod 和/或節點上的 CPU 爭用,可能會導致 API 伺服器速度變慢。
請參閱「容器速度變慢」一節,檢查 Pod 和/或節點是否有任何 CPU 爭用問題。
API 伺服器 Pod OOMkilled
API 伺服器 Pod 可能會因資源爭用問題而遭到 OOMKilled。請參閱「Pod 遭 OOMkilled (Out of Memory-Killed)」一節中的步驟,檢查 Pod 和/或節點是否有任何記憶體爭用問題。
etcd 回應速度緩慢
API 伺服器會與 etcd 叢集通訊,為用戶端提供讀取/寫入要求。如果 etcd 速度緩慢或沒有回應,API 伺服器也會變慢。
擷取 API 伺服器的記錄,檢查 API 伺服器是否因 etcd 問題而速度緩慢:
kubectl –kubeconfig ADMIN_CLUSTER_KUBECONFIG logs -n APISERVER_NAMESPACE APISERVER_POD_NAME
如果發現重複出現的記錄,例如 etcdserver: request timedout 或 etcdserver: leader changed,請按照「Etcd 問題」中的步驟解決任何磁碟相關問題。
如果叢集未匯出指標
本文先前介紹的技術,仰賴從叢集匯出至 Google Cloud 專案的指標。
如果叢集未匯出指標,您可以使用指令列調查資源爭用情形。您可以在管理員工作站上執行下列指令,查看指標。
查看節點的指標:
kubectl --kubeconfig CLUSTER_KUBECONFIG get --raw \
/apis/metrics.k8s.io/v1beta1/nodes/NODE_NAME | jq
更改下列內容:
- CLUSTER_KUBECONFIG:叢集 kubeconfig 檔案的路徑
- NODE_NAME:節點名稱
查看 Pod 的指標:
kubectl --kubeconfig CLUSTER_KUBECONFIG get --raw \
/apis/metrics.k8s.io/v1beta1/namespaces/NAMESPACE/pods/POD_NAME | jq
更改下列內容:
- NAMESPACE:Pod 的命名空間
- POD_NAME:Pod 的名稱
查看所有節點的指標:
kubectl --kubeconfig CLUSTER_KUBECONFIG top node
查看命名空間中所有 Pod 的指標:
kubectl --kubeconfig CLUSTER_KUBECONFIG top pod --namespace NAMESPACE
查看命名空間中所有 Pod 內容器的指標:
kubectl --kubeconfig CLUSTER_KUBECONFIG top pod --containers --namespace NAMESPACE
詳情請參閱 kubectl top pod 和 kubectl top node。
您也可以在節點上執行的容器中執行 top 指令。
在容器中執行指令的方法有兩種:
在管理員工作站上執行 kubectl exec,取得容器的殼層。在殼層中執行指令。
建立與節點的 SSH 連線。接著,使用 docker exec 取得容器的殼層。在殼層中執行指令。
後續步驟
如需其他協助,請與 Cloud Customer Care 團隊聯絡。
您也可以參閱「取得支援」,進一步瞭解支援資源,包括: