排解將設定同步至叢集的問題

解決 Config Sync 的設定同步問題,有助於確保叢集與中央可靠資料來源保持一致。同步失敗時,部署作業可能會停滯,叢集設定也可能偏離宣告狀態。您可以診斷並修正常見的 KNV2009 同步處理錯誤,例如缺少角色式存取控管 (RBAC) 權限、ResourceGroup 物件超出 etcd 大小限制,以及 Webhook 延遲,以還原自動化協調。

排解 KNV 2009 錯誤

KNV2009 錯誤表示 Config Sync 無法將部分設定同步至叢集。以下各節將說明一些最常見的原因和解決方法。

禁止對特定資源執行作業

由於您需要授予 RepoSync 物件其 RBAC,因此可能缺少套用資源所需的權限。

您可以取得 RepoSync 資源狀態,確認是否缺少權限:

kubectl get reposync repo-sync -n NAMESPACE -o yaml

將 NAMESPACE 替換為您建立命名空間存放區的命名空間。

您也可以使用 nomos status 指令。

如果狀態中顯示下列訊息,表示 NAMESPACE 中的協調器缺少套用資源所需的權限:

KNV2009: deployments.apps "nginx-deployment" is forbidden: User "system:serviceaccount:config-management-system:ns-reconciler-default" cannot get resource "deployments" in API group "apps" in the namespace "default"

如要修正這個問題,您必須宣告 RoleBinding 設定,授予協調器服務帳戶權限,以便管理該命名空間中失敗的資源。如要進一步瞭解如何新增 RoleBinding,請參閱「設定從多個存放區同步」。

如果您使用 spec.override.roleRefs 變更授予 RootSync 物件的角色,這個問題也可能影響 RootSync 物件。如未設定這個欄位,RootSync 物件預設會獲得 cluster-admin 角色。

ResourceGroup 物件超過 etcd 物件大小限制

如果協調器嘗試將設定套用至叢集時,您收到下列錯誤訊息,表示 ResourceGroup 物件超過 etcd 物件大小限制:

KNV2009: too many declared resources causing ResourceGroup.kpt.dev, config-management-system/root-sync failed to be applied: task failed (action: "Inventory", name: "inventory-add-0"): Request entity too large: limit is 3145728. To fix, split the resources into multiple repositories.

建議您將 Git 存放區分割成多個存放區。如果物件過大且變更未保留,導致您無法拆分 Git 存放區,可以設定 RootSync 或 RepoSync,暫時停用將物件狀態寫入 ResourceGroup 的功能,藉此緩解問題。方法是將 RootSync 或 RepoSync 物件的 .spec.override.statusMode 欄位設為 disabled。這樣一來,Config Sync 就會停止更新 ResourceGroup 物件中的代管資源狀態。這項操作會縮減 ResourceGroup 物件的大小。不過,您無法透過 nomos status 查看代管資源的狀態。

如果 RootSync 或 RepoSync 物件未顯示任何錯誤,表示可靠資料來源中的物件已同步至叢集。如要檢查 ResourceGroup 資源是否超出 etcd 物件大小限制,請檢查 ResourceGroup 資源狀態和 ResourceGroup 控制器的記錄:

  1. 檢查 ResourceGroup 狀態:

    • 如要檢查 RootSync 物件,請執行下列指令:

      kubectl get resourcegroup root-sync -n config-management-system
      
    • 如要檢查 RepoSync 物件,請執行下列指令:

      kubectl get resourcegroup repo-sync -n NAMESPACE
      

      將 NAMESPACE 替換為您建立命名空間存放區的命名空間。

    輸出內容大致如下:

    NAME        RECONCILING   STALLED   AGE
    root-sync   True          False     35m
    

    如果 RECONCILING 欄中的值為 True,表示 ResourceGroup 資源仍在協調中。

  2. 查看 ResourceGroup 控制器的記錄:

    kubectl logs deployment resource-group-controller-manager -c manager -n resource-group-system
    

    如果輸出內容中顯示類似下列範例的錯誤,表示 ResourceGroup 資源過大,超出 etcd 物件大小限制:

    "error":"etcdserver: request is too large"
    

為避免 ResourceGroup 過大,請減少 Git 存放區中的資源數量。您可以將一個根存放區分割成多個根存放區。

依附元件套用協調逾時

如果您同步處理的物件具有依附元件,當協調器嘗試將含有 config.kubernetes.io/depends-on 註解的物件套用至叢集時,可能會收到類似下列範例的錯誤訊息:

KNV2009: skipped apply of Pod, bookstore/pod4: dependency apply reconcile timeout: bookstore_pod3__Pod  For more information, see https://g.co/cloud/acm-errors#knv2009

這項錯誤表示依附元件物件未在預設的協調逾時時間 (五分鐘) 內協調。Config Sync 無法套用依附物件,因為使用 config.kubernetes.io/depends-on 註解時,Config Sync 只會按照您指定的順序套用物件。您可以設定 spec.override.reconcileTimeout,將預設協調逾時時間覆寫為更長的時間。

此外,在初始同步處理作業完成後,相依關係也可能會協調。在這種情況下,系統應會在下次嘗試同步時,偵測到依附元件已協調,並解除任何依附元件的套用。發生這種情況時,系統可能會短暫回報錯誤,然後移除。延長協調逾時時間,可能有助於避免間歇性回報錯誤。

商品目錄資訊為空值

如果協調器嘗試將設定套用至叢集時,您收到下列錯誤訊息,可能是因為清單中沒有資源,或資訊清單含有未受管理的註解:

KNV2009: inventory info is nil\n\nFor more information, see https://g.co/cloud/acm-errors#knv2009

如要解決這個問題,請嘗試下列步驟:

  1. 請確保至少有一項資源由 Config Sync 管理,避免設定所有資源都具有 configmanagement.gke.io/managed: disabled 註解的同步作業。
  2. 請務必先完成不含 configmanagement.gke.io/managed: disabled 註解的資源初始同步作業,再新增該註解。

多個商品目錄物件範本

如果協調器嘗試將設定套用至叢集時,您收到下列錯誤訊息,則可能是可靠資料來源 (例如 Git 存放區) 中有 kpt 產生的清查設定:

KNV2009: Package has multiple inventory object templates.  The package should have one and only one inventory object template.   For more information, see https://g.co/cloud/acm-errors#knv2009

這是因為 Config Sync 會管理自己的庫存設定。如要解決這個問題,請刪除可靠資料來源中的商品目錄設定。

無法變更不可變更的欄位

您無法透過變更可靠資料來源中的值,來變更設定中的任何不可變更欄位。如果嘗試進行這類變更,會發生類似以下的錯誤:

KNV2009: failed to apply RESOURCE: admission webhook "deny-immutable-field-updates.cnrm.cloud.google.com" denied the request: cannot make changes to immutable field(s):

如要變更不可變動的欄位,請從可靠資料來源刪除物件,等待 Config Sync 從叢集刪除物件,然後在可靠資料來源中重新建立物件,並套用更新。

無法輪詢狀態

您可以使用 RepoSync 物件,授權 Config Sync 管理命名空間中的資源。如果這類 RepoSync 物件使用的 RoleBinding 物件參照自訂 ClusterRole 或 Role,您可能會收到下列來自協調器部署作業的錯誤訊息:

KNV2009: polling for status failed: unknown

如要解決這個問題,請確認 ClusterRole 和 Role 物件對 RepoSync 物件管理的每項資源,至少具備下列權限:

  • list
  • watch
  • get
  • patch
  • delete
  • create

如要瞭解如何新增這些權限,請參閱「建立 RoleBinding」。

API 探索失敗

如果看到類似下列的錯誤訊息,可能是發生 API 探索錯誤:

KNV2002: API discovery failed: APIServer error: unable to retrieve the complete list of server APIs: external.metrics.k8s.io/v1beta1: received empty response for: external.metrics.k8s.io/v1beta1

Config Sync 會使用 Kubernetes API 探索,查詢叢集支援哪些資源。Config Sync 就能驗證來源中指定的資源類型,並監控叢集中的資源是否有變更。

在 Kubernetes 1.28 版之前,只要 APIService 後端健康狀態不佳或傳回空白清單結果,API Discovery 就會失敗,導致 Config Sync 和多個其他 Kubernetes 元件發生錯誤。許多常見的 APIService 後端不具備高可用性,因此只要更新後端或將後端重新排程至其他節點,就可能經常發生這種情況。

具有單一副本的 APIService 後端範例包括 metrics-server 和 custom-metrics-stackdriver-adapter。部分 APIService 後端一律會傳回空白清單結果,例如 custom-metrics-stackdriver-adapter。另一個常見原因是 Webhook 異常。

在 Kubernetes 1.28 版之後,啟用匯總探索功能後,健康狀態不良的 APIService 後端不會再導致未處理的錯誤。而是顯示該 APIService 處理的資源群組沒有資源。只要來源中未指定健康狀態不良的資源,同步作業就會繼續進行。

延遲自我修復

自我修復功能會監控代管資源、偵測與可靠資料來源的偏差,並還原該偏差。

嘗試同步時,自我修復功能會暫停。這項行為代表自我修復功能可能會延遲,尤其是同步處理錯誤導致協調器無法完成作業時。如要重新啟用自我修復功能,請修正所有回報的同步處理錯誤。

Kubernetes API 要求數量過多

Config Sync 採用多實體策略,可擴充及隔離租戶和容錯網域。因此,每個 RootSync 和 RepoSync 都會取得自己的協調器執行個體。除了每次來源變更時進行同步處理外,每個協調器執行個體也會定期同步處理,做為自我修復行為的一部分,以還原主動偏差修復作業遺漏的任何變更。新增 RootSync 或 RepoSync 物件時,協調器將資源同步至 Kubernetes 的 API 要求數量會線性增加。因此,如果您有許多 RootSync 和 RepoSync 物件,有時可能會對 Kubernetes API 造成大量流量負載。

Config Sync 會使用伺服器端套用執行同步作業。這會將一般的 GET 和 PATCH 要求流程替換為單一 PATCH 要求,減少 API 呼叫總數,但增加 PATCH 呼叫次數。即使來源中的資源群組版本與叢集上的預設資源群組版本不符,也能確保所做的變更正確無誤。不過,即使來源沒有任何變更,或與所需狀態沒有偏差,稽核記錄中仍可能顯示 PATCH 要求。這是正常現象,但可能會令人意外。

如果同步處理作業發生錯誤,系統會重試,直到成功為止。不過,如果這項操作需要人工介入,Config Sync 可能會發生錯誤並重試一段時間,導致向 Kubernetes API 發出的要求數量增加。重試次數會以指數方式遞減,但如果許多 RootSync 或 RepoSync 物件同時無法同步,可能會對 Kubernetes API 造成大量流量負載。

如要解決這些問題,請嘗試下列其中一種做法:

  • 快速修正設定錯誤,避免問題累積。
  • 合併多個 RootSync 或 RepoSync 物件,減少發出 Kubernetes API 要求的協調器數量。

KubeVirt 解除安裝作業遭終止器封鎖

KubeVirt 是 Kubernetes 套件,會使用多個終止器,因此需要精確的刪除順序,才能順利清理。如果 KubeVirt 物件的刪除順序有誤,其他 KubeVirt 物件的刪除作業可能會停滯或無限期停止回應。

如果您嘗試解除安裝 KubeVirt,但遭到封鎖,請按照操作說明手動刪除 KubeVirt。

為避免日後發生這個問題,請宣告資源物件之間的依附元件,確保系統按照依附元件的反向順序刪除資源物件。

物件刪除作業遭終止器封鎖

Kubernetes 終止器是中繼資料項目,可指示 Kubernetes 在特定控制器執行清理作業之前,不允許移除物件。如果未滿足清除條件,或執行該資源清除作業的控制器健康狀態不佳或已刪除,就可能導致同步或協調失敗。

如要緩解這個問題,請找出仍在完成中的資源,以及應執行清理作業的控制器。

如果控制器健康狀態不佳,只要修正根本原因,資源清理作業應可完成,物件也能順利移除。

如果控制器運作正常,應該會對要刪除的物件套用狀態條件,說明清除作業停滯的原因。如果沒有,請查看控制器記錄,找出根本原因。

物件卡在刪除狀態,通常表示物件刪除順序有誤。為避免日後發生這類問題,請宣告資源物件之間的依附關係,確保系統依反向依附關係順序刪除資源物件。

ResourceGroup 欄位持續變更

嘗試同步時,系統會更新商品目錄,將資源狀態變更為「待處理」。同步失敗時,系統會更新目錄,將資源狀態變更為失敗。同步失敗後重試時,這個模式會重複,導致商品目錄定期更新。這會導致 ResourceGroup resourceVersion 隨著每次更新而增加,且同步處理狀態會來回切換。這是正常現象,但可能會讓人感到意外。

同步失敗的原因有很多。最常見的原因之一,是權限不足,無法管理來源中指定的資源。如要修正這項錯誤,請新增適當的 RoleBinding 或 ClusterRoleBinding,授予 RepoSync 或 RootSync 調和器權限,以便管理無法同步處理的資源。

Config Sync 不會移除或還原來源中未指定的欄位

Config Sync 會使用伺服器端套用,將來源的資訊清單套用至 Kubernetes。必須執行這項操作,其他控制器才能管理 metadata 和 spec 欄位。例如,水平自動調度 Pod 資源會更新 Deployment 中的副本數量。因此,Config Sync 只會管理來源資訊清單中指定的欄位。這會產生副作用:採用現有資源物件時,來源中未指定的任何欄位都不會變更,有時會導致合併的設定無效或不正確。

如要在採用資源時避免這個問題,請在最初採用時使用來源中完全相同的欄位,並在同步處理後變更來源中的欄位,讓 Config Sync 正確移除先前套用的欄位,並以來源中的新欄位取代。另一個避免這個問題的方法是先從叢集刪除資源,然後允許 Config Sync 套用新版本。

Config Sync 採用物件時,不會保留 kubectl 用戶端套用作業的欄位

Config Sync 採用伺服器端套用機制,因此當 Config Sync 採用原本以 kubectl 用戶端套用機制建立的物件時,會取消設定任何以用戶端套用機制設定,但未在來源中宣告的欄位。

如要保留這些欄位,請在最初採用物件時,使用來源中完全相同的欄位,或使用伺服器端套用建立物件。

後續步驟

  • 如果問題仍未解決,請查看是否為已知問題。

如果無法在說明文件中找到問題的解決方法, 請參閱下列資源,瞭解如何取得進一步協助: