本頁說明如何解決將設定檔同步至叢集時發生的問題。
排解 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 控制器的記錄:
檢查 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 資源仍在調解。檢查 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
如要解決這個問題,請嘗試下列步驟:
- 請確保至少有一個資源是由 Config Sync 管理,避免設定所有資源都具有
configmanagement.gke.io/managed: disabled
註解的同步。 - 完成資源的初始同步作業後,再新增
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
物件使用參照自訂 ClusterRole
或 Role
的 RoleBinding
物件,您可能會收到來自 Reconciler Deployment 的下列錯誤訊息:
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 探索就會失敗,導致 Config Sync 和多個其他 Kubernetes 元件發生錯誤。許多常見的 APIService 後端並非高可用性,因此只要更新後端或將後端重新排程至另一個節點,就可能發生這種情況。
單一副本的 APIService 後端範例包括 metrics-server
和 custom-metrics-stackdriver-adapter
。部分 APIService 後端一律會傳回空白清單結果,例如 custom-metrics-stackdriver-adapter
。另一個常見的 API 探索失敗原因是不正常的 Webhook。
在 Kubernetes 1.28 版之後,如果啟用「匯總探索」功能,不正常的 APIService 後端就不會再導致未處理的錯誤。而是顯示該 APIService 處理的資源群組沒有資源。只要來源中未指定不健康的資源,同步作業就能繼續進行。
延遲自我修復
自我修復功能會監控代管資源、偵測與可靠資料來源的差異,並還原差異。
嘗試同步時,系統會暫停自我修復功能。這表示自我修復可能會延遲,特別是如果發生同步錯誤,導致協調器無法完成作業。如要重新啟用自我修復功能,請修正所有回報的同步處理錯誤。
Kubernetes API 要求數量過多
Config Sync 採用多執行個體策略,可擴充及隔離房客和錯誤網域。因此,每個 RootSync
和 RepoSync
都會取得自己的協調器例項。除了在每次變更來源時進行同步處理,每個協調器執行個體也會定期同步處理,做為自我修復行為的一部分,藉此還原主動漂移修正作業遺漏的任何變更。新增 RootSync
或 RepoSync
物件時,調解器會將資源同步至 Kubernetes,導致 API 要求數量線性增加。因此,如果您有許多 RootSync
和 RepoSync
物件,有時可能會對 Kubernetes API 造成顯著的流量負載。
Config Sync 會使用伺服器端套用執行同步作業。這會以單一 PATCH 要求取代一般的 GET 和 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
用戶端套用功能建立的物件時,系統會取消設定以用戶端套用功能設定但未在來源中宣告的任何欄位。
如要保留這些欄位,請在最初採用物件時,使用來源中的完全相同欄位,或使用伺服器端套用建立物件。
後續步驟
如果問題仍未解決,請查看您的問題是否為已知問題。
如果無法在文件中找到問題的解決方案,請參閱「取得支援」一文,瞭解如何取得進一步協助,包括下列主題的建議:
- 與 Cloud 客戶服務聯絡,建立支援案件。
- 在 StackOverflow 上提問,向社群尋求支援。如果您使用 kpt 或 Kustomize,請使用
kpt
或kustomize
標記搜尋類似問題。 - 使用 GitHub 上的公開 Issue Tracker 回報錯誤或提出功能要求。