이 페이지에서는 클러스터에 구성을 동기화할 때 발생하는 문제를 해결하는 방법을 보여줍니다.
KNV 2009 오류 문제 해결
KNV2009
오류는 구성 동기화가 일부 구성을 클러스터에 동기화할 수 없음을 나타냅니다. 다음 섹션에서는 가장 일반적인 원인과 해결 방법을 설명합니다.
특정 리소스에 대한 작업이 금지됨
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
로 설정하면 됩니다. 이렇게 하면 구성 동기화가 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
이 오류는 종속 항목 객체가 기본 조정 제한 시간인 5분 이내에 조정되지 않았음을 의미합니다. config.kubernetes.io/depends-on
주석의 경우 구성 동기화가 원하는 순서로만 객체를 적용하기 때문에 구성 동기화가 종속 객체를 적용할 수 없습니다. spec.override.reconcileTimeout
을 설정하여 기본 조정 제한 시간을 더 긴 시간으로 재정의할 수 있습니다.
초기 동기화 시도가 완료된 후 종속 항목이 조정될 수도 있습니다. 이 경우 다음 동기화 재시도 시 종속 항목이 조정된 것으로 감지되어 종속 항목 적용이 차단 해제됩니다. 이 경우 오류가 잠시 보고된 후 삭제될 수 있습니다. 조정 제한 시간을 연장하면 오류가 간헐적으로 보고되는 것을 방지할 수 있습니다.
nil인 인벤토리 정보
조정자가 클러스터에 구성을 적용하려고 할 때 다음 오류가 발생하면 인벤토리에 리소스가 없거나 매니페스트에 관리되지 않는 주석이 있을 수 있습니다.
KNV2009: inventory info is nil\n\nFor more information, see https://g.co/cloud/acm-errors#knv2009
이 문제를 해결하려면 다음을 단계를 시도해 보세요.
- 구성 동기화가 하나 이상의 리소스를 관리하도록 하여 모든 리소스에
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
이 문제는 구성 동기화가 자체 인벤토리 구성을 관리하기 때문에 발생합니다. 이 문제를 해결하려면 정보 소스에서 인벤토리 구성을 삭제하세요.
변경 불가능한 필드를 변경할 수 없음
정보 소스의 값을 변경하여 구성의 변경 불가 필드를 변경할 수는 없습니다. 이러한 변경을 시도하면 다음과 유사한 오류가 발생합니다.
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):
변경할 수 없는 필드를 변경해야 하는 경우 정보 소스에서 객체를 삭제하고 구성 동기화에서 클러스터에서 객체를 삭제할 때까지 기다린 다음 업데이트된 정보로 정보 소스에서 객체를 다시 만듭니다.
상태 폴링 실패
RepoSync
객체를 사용하여 구성 동기화가 네임스페이스의 리소스를 관리하도록 승인할 수 있습니다. 이 유형의 RepoSync
객체가 맞춤 ClusterRole
또는 Role
을 참조하는 RoleBinding
객체를 사용하는 경우 조정자 배포에서 다음과 같은 오류 메시지가 표시될 수 있습니다.
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
구성 동기화는 Kubernetes API 검색을 사용하여 클러스터에서 지원되는 리소스를 조회합니다. 이렇게 하면 구성 동기화에서 소스에 지정된 리소스 유형을 확인하고 클러스터에서 이러한 리소스의 변경사항을 확인할 수 있습니다.
Kubernetes 버전 1.28 이전에는 APIService 백엔드가 비정상적이거나 빈 목록 결과를 반환할 때마다 API 검색이 실패하여 구성 동기화 및 기타 여러 Kubernetes 구성요소에 오류가 발생했습니다. 일반적인 APIService 백엔드의 대부분은 가용성이 높지 않기 때문에 백엔드를 업데이트하거나 다른 노드로 일정을 변경하면 이러한 상황이 비교적 자주 발생할 수 있습니다.
단일 복제본이 있는 APIService 백엔드의 예시로는 metrics-server
및 custom-metrics-stackdriver-adapter
가 있습니다. 일부 APIService 백엔드는 항상 custom-metrics-stackdriver-adapter
와 같이 빈 목록 결과를 반환합니다. API 검색 실패의 또 다른 일반적인 원인은 비정상적인 Webhook입니다.
집계된 검색 기능이 사용 설정된 Kubernetes 버전 1.28부터는 비정상적인 APIService 백엔드로 인해 더 이상 미처리 오류가 발생하지 않습니다. 대신 해당 APIService에서 처리하는 리소스 그룹에 리소스가 없는 것으로 표시됩니다. 이렇게 하면 소스에서 비정상적인 리소스가 지정되지 않는 한 동기화가 계속됩니다.
지연된 자가 복구
자가 복구는 관리형 리소스를 감시하고 정보 소스에서 드리프트를 감지하며 이러한 드리프트를 되돌립니다.
동기화 중에는 자동 복구가 일시중지됩니다. 이 동작으로 인해 특히 조정자가 완료되는 것을 방지하는 동기화 오류가 있는 경우 자가 복구가 지연될 수 있습니다. 자가 복구를 다시 사용 설정하려면 보고된 모든 동기화 오류를 수정하세요.
많은 수의 Kubernetes API 요청
구성 동기화는 멀티 인스턴스 전략을 사용하여 테넌트 및 오류 도메인을 확장하고 격리합니다. 이 때문에 각 RootSync
및 RepoSync
는 자체 조정자 인스턴스를 가져옵니다. 소스가 변경될 때마다 동기화하는 것 외에도 각 조정자 인스턴스는 자체 복구 동작의 일환으로 주기적으로 동기화하여 활성 드리프트 해결에서 누락된 변경사항을 되돌립니다. RootSync
또는 RepoSync
객체를 추가하면 리소스를 Kubernetes에 동기화하는 조정자가 실행하는 API 요청 수가 선형적으로 증가합니다. 따라서 RootSync
및 RepoSync
객체가 많은 경우 Kubernetes API에 상당한 트래픽 부하가 발생할 수 있습니다.
구성 동기화는 동기화를 실행하기 위해 서버 측 적용을 사용합니다. 이렇게 하면 일반 GET 및 PATCH 요청 흐름이 단일 PATCH 요청으로 대체되므로 총 API 호출 수는 줄고 PATCH 호출 수는 늘어납니다. 이렇게 하면 소스의 리소스 그룹 버전이 클러스터의 기본 리소스 그룹 버전과 일치하지 않더라도 변경사항에 오류가 없게 됩니다. 그러나 소스가 변경되지 않았거나 원하는 상태에서 드리프트 되더라도 감사 로그에 PATCH 요청이 표시될 수 있습니다. 이는 정상적인 동작이지만 놀라울 수 있습니다.
동기화에 오류가 발생하면 동기화가 성공할 때까지 다시 시도됩니다. 하지만 사람의 상호작용이 필요한 경우 구성 동기화에서 잠시 동안 오류가 발생하고 재시도되어 Kubernetes API에 대한 요청 수가 늘어날 수 있습니다. 재시도는 지수적으로 줄어들지만 여러 개의 RootSync
또는 RepoSync
객체가 동시에 동기화되지 않으면 Kubernetes API에 상당한 트래픽 부하가 발생할 수 있습니다.
이러한 문제를 완화하려면 다음 옵션 중 하나를 시도해 보세요.
- 구성 오류가 쌓이지 않도록 빠르게 수정합니다.
- 여러 개의
RootSync
또는RepoSync
객체를 결합하여 Kubernetes API 요청을 실행하는 조정자 수를 줄입니다.
파이널라이저에 의해 KubeVirt 제거 차단됨
KubeVirt는 여러 파이널라이저를 사용하는 Kubernetes 패키지이며, 삭제를 쉽게 하기 위해 정확한 삭제 순서가 필요합니다. KubeVirt 객체가 잘못된 순서로 삭제되는 경우 다른 KubeVirt 객체를 삭제하면 무기한 중단되거나 응답이 중지될 수 있습니다.
KubeVirt를 제거하려고 했지만 차단된 경우 안내에 따라 수동으로 KubeVirt를 삭제하세요.
이후에 이 문제가 발생하지 않도록 하려면 리소스 객체 간에 종속 항목을 선언하여 종속 항목 역순으로 삭제되도록 하세요.
파이널라이저에 의해 객체 삭제 차단됨
Kubernetes 파이널라이저는 특정 컨트롤러가 삭제를 수행할 때까지 객체 삭제를 허용하지 않도록 Kubernetes에 지시하는 메타데이터 항목입니다. 이렇게 하면 삭제 조건이 충족되지 않거나 해당 리소스의 삭제를 실행하는 컨트롤러가 비정상적이거나 삭제된 경우 동기화 또는 조정이 실패할 수 있습니다.
이 문제를 완화하려면 아직 완료되지 않은 리소스와 정리를 실행해야 하는 컨트롤러를 파악합니다.
컨트롤러가 비정상적인 경우 근본 원인을 해결하면 리소스 정리가 완료되어 객체 삭제가 차단 해제됩니다.
컨트롤러가 정상이면 컨트롤러는 정리가 중단된 이유를 설명하기 위해 삭제 중인 객체에 상태 조건을 적용해야 합니다. 그렇지 않으면 컨트롤러 로그에서 근본 원인을 나타내는 항목이 있는지 확인합니다.
객체 삭제가 중단되는 것은 객체가 잘못된 순서로 삭제되었음을 나타내는 경우가 많습니다. 향후 이러한 종류의 문제가 발생하지 않도록 하려면 리소스 객체 간에 종속 항목을 선언하여 종속 항목 역순으로 삭제되도록 하세요.
ResourceGroup 필드가 계속 변경됨
동기화를 시도하면 인벤토리가 업데이트되어 리소스 상태가 대기 중으로 변경됩니다. 동기화에 실패하면 인벤토리가 업데이트되어 리소스 상태가 실패로 변경됩니다. 실패 후 동기화를 다시 시도하면 이 패턴이 반복되어 인벤토리가 주기적으로 업데이트됩니다. 이로 인해 업데이트할 때마다 ResourceGroup resourceVersion
이 증가하고 동기화 상태가 앞뒤로 전환됩니다. 이는 정상적인 동작이지만 놀라울 수 있습니다.
동기화 실패는 여러 문제로 인해 발생할 수 있습니다. 가장 일반적인 원인 중 하나는 소스에 지정된 리소스를 관리할 권한이 부족한 것입니다. 이 오류를 해결하려면 적절한 RoleBindings 또는 ClusterRoleBinding을 추가하여 동기화에 실패한 리소스를 관리할 수 있는 RepoSync
또는 RootSync
조정자 권한을 부여합니다.
구성 동기화에서 소스에 지정되지 않은 필드를 삭제하거나 되돌리지 않음
구성 동기화는 서버 측 적용을 사용하여 소스의 매니페스트를 Kubernetes에 적용합니다. 이는 다른 컨트롤러가 metadata
및 spec
필드를 관리할 수 있도록 하는 데 필요합니다. 이러한 예로는 배포의 복제본 수를 업데이트하는 수평형 포드 자동 확장 처리가 있습니다. 따라서 구성 동기화는 소스 매니페스트에 지정된 필드만 관리합니다. 이로 인해 기존 리소스 객체를 채택할 때 소스에 지정되지 않은 필드는 변경되지 않으므로 병합된 구성이 무효 또는 잘못될 수 있습니다.
리소스를 채택할 때 이 문제를 방지하려면 처음에 채택할 때 소스에서 정확히 동일한 필드를 사용한 다음 동기화 후에 소스의 필드를 변경하여 구성 동기화에서 이전에 적용한 필드를 올바르게 삭제하고 소스의 새 필드로 교체하도록 합니다. 이 문제를 방지하는 또 다른 방법은 먼저 클러스터에서 리소스를 삭제하고 구성 동기화가 새 버전을 적용하도록 허용하는 것입니다.
구성 동기화가 객체를 채택할 때 kubectl
클라이언트 측 적용의 필드를 유지하지 않음
구성 동기화는 서버 측 적용을 사용하므로 구성 동기화에서 원래 kubectl
클라이언트 측 적용으로 만든 객체를 채택하면 클라이언트 측 적용으로 설정되었지만 소스에서 선언되지 않은 모든 필드가 설정 해제됩니다.
이러한 필드를 유지하려면 객체를 처음 채택할 때 소스에서 정확히 동일한 필드를 사용하거나 서버 측 적용을 사용하여 객체를 만드세요.
다음 단계
문제가 계속되면 이 문제가 알려진 문제인지 확인합니다.
문서에서 문제 해결 방법을 찾을 수 없으면 지원 받기를 참조하여 다음 주제에 대한 조언을 포함한 추가 도움을 요청하세요.
- Cloud Customer Care에 문의하여 지원 케이스를 엽니다.
- StackOverflow에서 질문하여 커뮤니티의 지원을 받습니다.
kpt 또는 Kustomize를 사용하는 경우
kpt
또는kustomize
태그를 사용하여 유사한 문제를 검색합니다. - GitHub의 공개 Issue Tracker를 사용하여 버그나 기능 요청을 엽니다.