클러스터에 구성 동기화 문제 해결

이 페이지에서는 클러스터에 구성을 동기화할 때 발생하는 문제를 해결하는 방법을 보여줍니다.

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 또는 gcloud alpha anthos config sync에서 관리형 리소스 상태를 볼 수 없습니다.

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

이 오류는 종속 항목 객체가 기본 조정 제한 시간인 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

이 문제를 해결하려면 다음을 단계를 시도해 보세요.

  1. 구성 동기화가 하나 이상의 리소스를 관리하도록 하여 모든 리소스에 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

이 문제는 구성 동기화가 자체 인벤토리 구성을 관리하기 때문에 발생합니다. 이 문제를 해결하려면 정보 소스에서 인벤토리 구성을 삭제하세요.

변경 불가능한 필드를 변경할 수 없음

정보 소스의 값을 변경하여 구성에서 변경할 수 없는 필드를 변경할 수 없습니다. 이러한 변경을 시도하면 다음과 비슷한 오류가 발생합니다.

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):

변경할 수 없는 필드를 업데이트해야 하는 경우 클러스터에서 객체를 수동으로 삭제합니다. 그러면 구성 동기화는 새 필드 값으로 객체를 다시 만들 수 있습니다.

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-servercustom-metrics-stackdriver-adapter가 있습니다. 일부 APIService 백엔드는 항상 custom-metrics-stackdriver-adapter와 같이 빈 목록 결과를 반환합니다. API 검색 실패의 또 다른 일반적인 원인은 비정상 웹훅입니다.

Kubernetes 버전 1.28 이후에는 집계 검색 기능이 사용 설정된 상태에서 비정상 APIService 백엔드가 더 이상 처리되지 않은 오류를 일으키지 않습니다. 대신 해당 APIService에서 처리하는 리소스 그룹에는 리소스가 없는 것으로 표시됩니다. 이렇게 하면 소스에 비정상 리소스가 지정되지 않는 한 동기화가 계속됩니다.

자가 복구 지연

자가 복구는 관리형 리소스를 감시하고 정보 소스에서 드리프트를 감지하며 이러한 드리프트를 되돌립니다.

동기화를 시도하는 동안 자가 복구가 일시중지됩니다. 이 동작으로 인해 특히 조정자가 완료되는 것을 방지하는 동기화 오류가 있는 경우 자가 복구가 지연될 수 있습니다. 자가 복구를 다시 사용 설정하려면 보고된 모든 동기화 오류를 수정하세요.

많은 수의 Kubernetes API 요청

구성 동기화는 멀티 인스턴스 전략을 사용하여 테넌트 및 오류 도메인을 확장하고 격리합니다. 이 때문에 각 RootSyncRepoSync는 자체 조정자 인스턴스를 가져옵니다. 소스가 변경될 때마다 동기화하는 것 외에도 각 조정자 인스턴스는 자가 복구 동작의 일부로 주기적으로 동기화되어, 활성 드리프트 해결로 인해 누락된 변경사항을 되돌릴 수 있습니다. RootSync 또는 RepoSync 객체를 추가하면 Kubernetes에 리소스를 동기화하는 조정자가 수행하는 API 요청 수가 선형적으로 증가합니다. 따라서 RootSyncRepoSync 객체가 많으면 Kubernetes API에 상당한 트래픽 부하가 발생할 수 있습니다.

동기화를 수행하기 위해 구성 동기화는 서버 측 적용을 사용합니다. 이렇게 하면 일반적인 GET 및 PATCH 요청 흐름이 단일 PATCH 요청으로 대체되어 총 API 호출 수가 줄어들지만 PATCH 호출 수가 증가합니다. 이렇게 하면 소스의 리소스 그룹 버전이 클러스터의 기본 리소스 그룹 버전과 일치하지 않더라도 변경사항에 오류가 없게 됩니다. 그러나 소스가 변경되지 않았거나 원하는 상태에서 드리프트 되더라도 감사 로그에 PATCH 요청이 표시될 수 있습니다. 이는 정상이지만 놀라울 수 있습니다.

동기화 중 오류가 발생하면 성공할 때까지 재시도됩니다. 하지만 사람의 상호작용이 필요한 경우 구성 동기화에서 잠시 동안 오류가 발생하고 재시도되어 Kubernetes API에 대한 요청 수가 늘어날 수 있습니다. 재시도가 기하급수적으로 백오프되지만 여러 RootSync 또는 RepoSync 객체가 동시에 동기화되지 않을 경우 Kubernetes API에 상당한 트래픽 로드가 발생할 수 있습니다.

이러한 문제를 완화하려면 다음 옵션 중 하나를 시도해 보세요.

  • 구성 오류가 쌓이지 않도록 빠르게 수정합니다.
  • Kubernetes API 요청을 수행하는 조정자 수를 줄이기 위해 여러 RootSync 또는 RepoSync 객체를 결합합니다.

파이널라이저에 의해 KubeVirt 제거 차단됨

KubeVirt는 여러 파이널라이저를 사용하는 Kubernetes 패키지이며, 삭제를 쉽게 하기 위해 정확한 삭제 순서가 필요합니다. KubeVirt 객체가 잘못된 순서로 삭제되는 경우 다른 KubeVirt 객체를 삭제하면 무기한 중단되거나 응답이 중지될 수 있습니다.

KubeVirt를 제거하려고 했지만 차단된 경우 수동으로 KubeVirt 삭제 안내를 따릅니다.

이후에 이 문제가 발생하지 않도록 하려면 리소스 객체 간에 종속 항목을 선언하여 종속 항목 역순으로 삭제되도록 하세요.

파이널라이저에 의해 객체 삭제 차단됨

Kubernetes 파이널라이저는 특정 컨트롤러가 삭제를 수행할 때까지 객체 삭제를 허용하지 않도록 Kubernetes에 지시하는 메타데이터 항목입니다. 삭제 조건이 충족되지 않거나 리소스 삭제를 수행하는 컨트롤러가 비정상이거나 삭제된 경우 동기화 또는 조정이 실패할 수 있습니다.

이 문제를 완화하려면 완료 중인 리소스와 삭제 작업을 수행해야 하는 컨트롤러를 식별합니다.

컨트롤러가 비정상인 경우 근본 원인을 해결하면 리소스 삭제가 완료되어 객체 삭제가 차단 해제됩니다.

컨트롤러가 정상인 경우 컨트롤러는 삭제가 중단된 이유를 설명하기 위해 삭제될 객체에 상태 조건을 적용해야 합니다. 그렇지 않으면 컨트롤러 로그에서 근본 원인의 표시를 확인합니다.

객체 삭제가 중단되면 객체가 잘못된 순서로 삭제되었음을 나타내는 경우가 많습니다. 향후 이러한 종류의 문제를 방지하려면 리소스 객체 간에 종속 항목을 선언하여 종속 항목 역순으로 삭제되도록 합니다.

ResourceGroup 필드가 계속 변경됨

동기화를 시도하면 리소스 상태가 대기 중으로 변경되도록 인벤토리가 업데이트됩니다. 동기화가 실패하면 인벤토리가 업데이트되어 리소스 상태를 실패로 변경합니다. 실패 후 동기화가 재시도되면 이 패턴이 반복되므로 인벤토리가 주기적으로 업데이트됩니다. 그러면 업데이트할 때마다 ResourceGroup resourceVersion이 증가하고 동기화 상태가 앞뒤로 바뀝니다. 이는 정상이지만 놀라울 수 있습니다.

동기화 실패는 여러 문제로 인해 발생할 수 있습니다. 가장 일반적인 상황 중 하나는 소스에 지정된 리소스를 관리할 수 있는 권한이 부족한 것입니다. 이 오류를 해결하려면 적절한 RoleBindings 또는 ClusterRoleBinding을 추가하여 동기화에 실패한 리소스를 관리할 수 있는 RepoSync 또는 RootSync 조정자 권한을 부여합니다.

서버 측 적용에서 소스에 지정되지 않은 필드를 삭제하거나 되돌리지 않음

구성 동기화는 서버 측 적용을 사용하여 소스의 매니페스트를 Kubernetes에 적용합니다. 이는 다른 컨트롤러가 metadataspec 필드를 관리하도록 허용하기 위해 필요합니다. 이에 대한 한 가지 예시로 배포의 복제본 수를 업데이트하는 수평형 포드 자동 확장 처리가 있습니다. 이로 인해 구성 동기화는 소스 매니페스트에 지정된 필드만 관리합니다. 이로 인해 기존 리소스 객체를 채택할 때 소스에 지정되지 않은 모든 필드가 변경되지 않아 병합된 구성이 무효화되거나 잘못될 수 있습니다.

리소스를 채택할 때 이 문제를 방지하려면 처음에 채택할 때 소스에서 정확히 동일한 필드를 사용한 다음 동기화 후에 소스의 필드를 변경하여 구성 동기화에서 이전에 적용한 필드를 올바르게 삭제하고 소스의 새 필드로 교체하도록 합니다. 이 문제를 방지하는 또 다른 방법은 클러스터에서 리소스를 먼저 삭제하고 구성 동기화가 새 버전을 적용하도록 허용하는 것입니다.

다음 단계