排解叢集建立或升級問題

本頁說明如何解決安裝或升級 Google Distributed Cloud 叢集時發生的問題。

安裝問題

以下各節內容或許有助於排解 Google Distributed Cloud 安裝問題。

暫時性錯誤訊息

Google Distributed Cloud 的安裝程序是持續的協調迴圈。因此,您可能會在安裝期間的記錄中看到暫時性錯誤訊息。

只要安裝作業順利完成,即可放心忽略這些錯誤。以下列出常見的暫時性錯誤記錄訊息:

  Internal error occurred: failed calling webhook "webhook.cert-manager.io": Post
  https://cert-manager-webhook.cert-manager.svc:443/mutate?timeout=10s:
  dial tcp IP_ADDRESS:443: connect: connection refused
  Internal error occurred: failed calling webhook "vcluster.kb.io": Post
  https://webhook-service.kube-system.svc:443/validate-baremetal-cluster-gke-io-v1-cluster?timeout=30s:
  dial tcp IP_ADDRESS:443: connect: connection refused
  Failed to register cluster with GKE Hub; gcloud output: error running command
  'gcloud container fleet memberships register CLUSTER_NAME  --verbosity=error --quiet':
  error: exit status 1, stderr: 'ERROR: (gcloud.container.hub.memberships.register)
  Failed to check if the user is a cluster-admin: Unable to connect to the server: EOF
  Get
  https://127.0.0.1:34483/apis/infrastructure.baremetal.cluster.gke.io/v1/namespaces/cluster-
  cluster1/baremetalmachines: dial tcp 127.0.0.1:34483: connect: connection refused"
  Create Kind Cluster "msg"="apply run failed" "error"="unable to recognize \"/tmp/kout088683152\": no matches for kind \"NetworkLogging\" in version \"networking.gke.io/v1alpha1\""
  Create Kind Cluster "msg"="apply run failed" "error"="unable to recognize \"/tmp/kout869681888\": no matches for kind \"Provider\" in version \"clusterctl.cluster.x-k8s.io/v1alpha3\""

如果 Google Cloud 服務帳戶金鑰已過期,您會看到 bmctl 傳送的下列錯誤訊息:

Error validating cluster config: 3 errors occurred:
        * GKEConnect check failed: Get https://gkehub.googleapis.com/v1beta1/projects/project/locations/global/memberships/admin: oauth2: cannot fetch token: 400 Bad Request
Response: {"error":"invalid_grant","error_description":"Invalid JWT Signature."}
        * ClusterOperations check failed: Post https://cloudresourcemanager.googleapis.com/v1/projects/project:testIamPermissions?alt=json&prettyPrint=false: oauth2: cannot fetch token: 400 Bad Request
Response: {"error":"invalid_grant","error_description":"Invalid JWT Signature."}
        * GCR pull permission for bucket: artifacts.anthos-baremetal-release.appspot.com failed: Get https://storage.googleapis.com/storage/v1/b/artifacts.anthos-baremetal-release.appspot.com/iam/testPermissions?alt=json&permissions=storage.objects.get&permissions=storage.objects.list&prettyPrint=false: oauth2: cannot fetch token: 400 Bad Request
Response: {"error":"invalid_grant","error_description":"Invalid JWT Signature."}

您需要產生新的服務帳戶金鑰

使用啟動叢集偵錯問題

Google Distributed Cloud 建立自我管理 (管理員、混合或獨立) 叢集時,會部署 Kubernetes in Docker (kind) 叢集,暫時託管建立叢集所需的 Kubernetes 控制器。這個暫時性叢集稱為啟動叢集。使用者叢集是由管理員或混合叢集管理,且不使用啟動程序叢集,因此可自行建立及升級。

如果您嘗試安裝時,部署作業中已有 kind 叢集,Google Distributed Cloud 會刪除現有 kind 叢集。只有在安裝或升級成功後,系統才會刪除舊版。 如要保留現有 kind 叢集,即使成功後也一樣,請使用 bmctl--keep-bootstrap-cluster 旗標。

Google Distributed Cloud 會在 WORKSPACE_DIR/.kindkubeconfig 下方建立啟動叢集的設定檔。您只能在建立和升級叢集時連線至啟動程序叢集。

啟動程序叢集需要存取 Docker 存放區,才能提取映像檔。除非使用私人登錄檔,否則登錄檔預設為 Artifact Registry。建立叢集時,bmctl 會建立下列檔案:

  • bmctl-workspace/config.json:包含 Google Cloud 服務帳戶 登錄存取憑證。憑證是從叢集設定檔的 gcrKeyPath 欄位取得。

  • bmctl-workspace/config.toml:包含 kind 叢集中的 containerd 設定。

檢查啟動叢集記錄

如要偵錯啟動叢集,請採取下列步驟:

  • 在建立及升級叢集期間,連線至啟動程序叢集。
  • 取得啟動叢集的記錄。

您可以在用來執行 bmctl 的電腦中,於下列資料夾找到記錄:

  • bmctl-workspace/CLUSTER_NAME/log/create-cluster-TIMESTAMP/bootstrap-cluster/
  • bmctl-workspace/CLUSTER_NAME/log/upgrade-cluster-TIMESTAMP/bootstrap-cluster/

CLUSTER_NAMETIMESTAMP 替換為叢集名稱和對應系統的時間。

如要直接從啟動程序叢集取得記錄,您可以在建立及升級叢集時執行下列指令:

docker exec -it bmctl-control-plane bash

這項指令會在啟動叢集執行的 bmctl 控制層容器中開啟終端機。

如要檢查 kubelet 和 containerd 記錄,請使用下列指令,並在輸出內容中尋找錯誤或警告:

journalctl -u kubelet
journalctl -u containerd

啟用 containerd 偵錯記錄

如果標準 containerd 記錄提供的資訊不足以進行疑難排解,您可以提高記錄層級。診斷複雜問題 (例如登錄檔鏡像或 ImagePullBackOff 錯誤的問題) 時,通常需要提高記錄層級。

如要提高記錄層級,請按照下列步驟操作:

  1. 啟用偵錯記錄功能:

    1. 使用偏好的文字編輯器開啟 containerd 設定檔 (/etc/containerd/config.toml)。

    2. 在檔案中找出 [debug] 區段,然後將 level 的值從 "" 變更為 "debug"

    3. 儲存檔案並結束文字編輯器。

    4. 確認您已成功更新設定檔:

      cat /etc/containerd/config.toml | grep debug
      

      輸出內容應如下所示:

      [debug]
        level = "debug"
          shim_debug = false
      
    5. 如要套用記錄層級變更,請重新啟動 containerd:

      sudo systemctl restart containerd
      
  2. 如要產生新的記錄項目,請嘗試提取不存在或未由任何節點或叢集使用的映像檔。例如:

    # This command fails because the image doesn't exist
    crictl pull us-west1-docker.pkg.dev/gdc-project/samples/non-existent-image:latest
    

    這會強制 containerd 執行動作並產生詳細記錄。

  3. 等待映像檔提取或失敗,然後在名為 containerd_log.txt 的檔案中收集 containerd 記錄:

    journalctl -u containerd --no-pager --since TIME_PERIOD > containerd_log.txt
    

    TIME_PERIOD 換成指定記錄開始時間的值。請將含有空格的值括在雙引號內。 例如:"2 hours ago"

  4. 完成疑難排解後,請將記錄層級還原為預設值。如果啟用偵錯記錄功能,系統記錄可能會過於龐大、影響效能,甚至可能洩漏機密資訊。

    1. 開啟 /etc/containerd/config.toml 檔案,並將 level 的值改回預設記錄層級 ""

    2. 確認設定已成功更新:

      cat /etc/containerd/config.toml | grep level
      

      輸出內容應如下所示:

      level = ""
      
    3. 如要套用變更,請重新啟動 containerd:

      sudo systemctl restart containerd
      

      系統現在會恢復標準記錄設定。

叢集升級問題

升級 Google Distributed Cloud 叢集時,您可以監控進度,並檢查叢集和節點的狀態。

請參考下列指引,判斷升級作業是否正常進行,或是有問題。

監控升級進度

使用 kubectl describe cluster 指令,在升級程序中查看叢集狀態:

kubectl describe cluster CLUSTER_NAME \
    --namespace CLUSTER_NAMESPACE \
    --kubeconfig ADMIN_KUBECONFIG

替換下列值:

  • CLUSTER_NAME:叢集名稱。
  • CLUSTER_NAMESPACE:叢集的命名空間。
  • ADMIN_KUBECONFIG:管理員 kubeconfig 檔案。
    • 根據預設,管理員、混合式和獨立叢集會使用就地升級。如果您在 bmctl upgrade 指令中使用 --use-bootstrap=true 旗標,升級作業會使用啟動程序叢集。如要在使用啟動程序叢集時監控升級進度,請指定啟動程序叢集 kubeconfig 檔案的路徑 .kindkubeconfig。這個檔案位於工作區目錄中。

查看輸出內容的 Status 部分,其中會顯示叢集升級狀態的匯總資訊。如果叢集回報錯誤,請參閱下列各節,瞭解如何排解問題。

檢查節點是否已準備就緒

在升級程序期間,使用 kubectl get nodes 指令查看叢集中節點的狀態:

kubectl get nodes --kubeconfig KUBECONFIG

如要檢查節點是否已順利完成升級程序,請查看指令回應中的 VERSIONAGE 欄。VERSION 是叢集的 Kubernetes 版本。如要查看特定 Google Distributed Cloud 版本的 Kubernetes 版本,請參閱「版本管理」。

如果節點顯示 NOT READY,請嘗試連線至節點並檢查 kubelet 狀態:

systemctl status kubelet

您也可以查看 kubelet 記錄:

journalctl -u kubelet

查看 kubelet 狀態和記錄的輸出內容,找出指出節點問題的訊息。

查看要升級的節點

如要查看叢集中正在升級的節點,請使用 kubectl get baremetalmachines 指令:

kubectl get baremetalmachines --namespace CLUSTER_NAMESPACE \
    --kubeconfig ADMIN_KUBECONFIG

替換下列值:

  • CLUSTER_NAMESPACE:叢集的命名空間。
  • ADMIN_KUBECONFIG:管理員 kubeconfig 檔案。
    • 如果管理員、混合式或獨立升級使用啟動叢集,請指定啟動叢集 kubeconfig 檔案 (bmctl-workspace/.kindkubeconfig)。

以下輸出範例顯示,升級的節點與 DESIRED ABM VERSION 不同:ABM VERSION

NAME         CLUSTER    READY   INSTANCEID               MACHINE      ABM VERSION   DESIRED ABM VERSION
10.200.0.2   cluster1   true    baremetal://10.200.0.2   10.200.0.2   1.13.0        1.14.0
10.200.0.3   cluster1   true    baremetal://10.200.0.3   10.200.0.3   1.13.0        1.13.0

查看正在排空的節點

在升級過程中,系統會排空節點中的 Pod,並停用排程,直到節點成功升級為止。如要查看哪些節點正在排空,請使用 kubectl get nodes 指令:

kubectl get nodes --kubeconfig USER_CLUSTER_KUBECONFIG | grep "SchedulingDisabled"

USER_CLUSTER_KUBECONFIG 替換為使用者叢集 kubeconfig 檔案的路徑。

使用 grep 篩選 STATUS 資料欄,只顯示回報 SchedulingDisabled 的節點。這個狀態表示節點正在排空。

您也可以從管理員叢集檢查節點狀態:

kubectl get baremetalmachines -n CLUSTER_NAMESPACE \
  --kubeconfig ADMIN_KUBECONFIG

替換下列值:

  • CLUSTER_NAMESPACE:叢集的命名空間。
  • ADMIN_KUBECONFIG:管理員 kubeconfig 檔案。
    • 如果管理員、混合式或獨立升級使用啟動叢集,請指定啟動叢集 kubeconfig 檔案 (bmctl-workspace/.kindkubeconfig)。

正在排空的節點會在 MAINTENANCE 欄下方顯示狀態。

檢查節點長時間處於排空狀態的原因

使用上一節中的其中一種方法,透過 kubectl get nodes 指令找出要排空的節點。使用 kubectl get pods 指令並依這個節點名稱篩選,即可查看其他詳細資料:

kubectl get pods --all-namespaces -o wide --field-selector spec.nodeName=NODE_NAME

NODE_NAME 替換為要排空的節點名稱。輸出內容會傳回耗電速度緩慢或耗電異常的 Pod 清單。如果節點上的排空程序超過 20 分鐘,即使 Pod 卡住,升級作業仍會繼續進行。

從 1.29 版開始,節點排空程序會使用 Eviction API,並遵守 PodDisruptionBudgets (PDB)。

下列 PDB 設定可能會導致節點排空問題:

  • 由多個 PDB 管理的 Pod

  • PDB 靜態設定,例如:

    • maxUnavailable == 0
    • minUnavailable >= 副本總數

    由於副本總數是在較高層級的資源中定義 (例如 DeploymentReplicaSetStatefulSet),因此很難從 PDB 資源判斷。PDB 只會根據設定中的選取器比對 Pod。如要診斷靜態 PDB 設定是否造成問題,請查看 pdb.Status.ExpectPods <= pdb.Status.DesiredHealthy,並確認是否有任何允許發生這種情況的靜態設定。

執行階段違規事項 (例如 PDB 資源的計算 DisruptionsAllowed 值為 0) 也可能導致節點排空作業遭到封鎖。如果您已設定PodDisruptionBudget物件,且這些物件無法容許任何額外中斷,節點升級可能會在多次嘗試後,仍無法升級至控制層版本。為避免發生這種情況,建議您擴大 DeploymentHorizontalPodAutoscaler,讓節點在仍遵守 PodDisruptionBudget 設定的情況下排空。

如要查看所有不允許任何中斷的 PodDisruptionBudget 物件,請使用下列指令:

kubectl get poddisruptionbudget --all-namespaces \
    -o jsonpath='{range .items[?(@.status.disruptionsAllowed==0)]}{.metadata.name}/{.metadata.namespace}{"\n"}{end}'

檢查 Pod 狀況不佳的原因

如果 Pod 包含 upgrade-first-nodeupgrade-node 控制層 IP 位址,升級作業可能會失敗。這通常是因為靜態 Pod 不正常。

  1. 使用 crictl ps -a 指令檢查靜態 Pod,並找出任何當機的 Kubernetes 或 etcd Pod。如有任何失敗的 Pod,請查看 Pod 的記錄檔,瞭解 Pod 發生當機的原因。

    導致當機迴圈行為的可能原因包括:

    • 掛接至靜態 Pod 的檔案權限或擁有者不正確。
    • 無法連線至虛擬 IP 位址。
    • etcd」發生問題。
  2. 如果 crictl ps 指令無法運作或未傳回任何內容,請檢查 kubelet 和 containerd 狀態。使用 systemctl status SERVICEjournalctl -u SERVICE 指令查看記錄。

後續步驟

如需其他協助,請與 Cloud Customer Care 團隊聯絡。如要進一步瞭解支援資源,包括下列項目,請參閱「取得支援」: