구성 동기화 문제 해결

이 페이지에서는 구성 동기화 설치 문제 해결에 도움을 드립니다.

구성 동기화 환경이 항상 작동할 수 있도록 노력하고 있지만 설정 문제 해결이 필요한 상황이 발생할 수 있습니다. 이 가이드에서는 발생한 문제를 해결하는 데 도움이 될 수 있는 몇 가지 일반적인 메커니즘을 설명합니다.

일반 권장사항

nomos status를 활용하세요

Google은 nomos status 명령어로 대부분의 데이터를 쉽게 사용할 수 있도록 많은 노력을 기울이고 있습니다. nomos status는 구성 동기화 설치에서 발생하는 상황을 이해할 수 있도록 수집된 데이터 및 오류 정보를 제공합니다. 다음 정보는 nomos status로 제공됩니다.

  • 클러스터당 설치 상태
  • 동기화 오류(Git에서 읽기 및 변경사항 조정 모두)

고급 사용을 위한 kubectl get KRM 리소스

구성 동기화는 kubectl을 사용하여 개별적으로 쿼리하여 각 객체의 상태를 정확하게 이해할 수 있는 여러 커스텀 리소스로 구성됩니다.

구성 동기화가 관리하는 Kubernetes 리소스에 대해 알아야 할 몇 가지 주요 사항은 다음과 같습니다.

  • config-management-system: 구성 동기화의 모든 핵심 시스템 구성요소를 실행하는 데 사용하는 네임스페이스입니다.
  • configmanagement.gke.io/v1configsync.gke.io는 모든 커스텀 리소스에 사용하는 버전 프리픽스입니다.

다음 명령어를 실행하여 커스텀 리소스의 전체 목록을 가져올 수 있습니다.

kubectl api-resources | grep -E "configmanagement.gke.io|configsync.gke.io"

kubectl get RESOURCE -o yaml을 실행하여 개별 커스텀 리소스를 사용할 수 있습니다.

예를 들어 다음 명령어의 결과에서 RootSync 객체를 확인할 수 있습니다.

kubectl get rootsync -n config-management-system -o yaml

자세한 내용은 RootSync 및 RepoSync 객체 탐색을 참조하세요.

감사 로그 사용

감사 로그는 유용한 디버깅 도구입니다.

Cloud Console 또는 gcloud 명령줄 도구를 사용하여 구성 동기화를 설치한 경우 다음 단계에 따라 감사 로그를 사용하여 구성 동기화를 조사합니다.

Console

  1. GKE Connect/Hub API 감사 로그를 사용 설정합니다.

    1. Cloud Console에서 IAM 감사 로그 페이지로 이동합니다.

      감사 로그 페이지로 이동

    2. 표에서 GKE Connect/Hub API 체크박스를 선택합니다.

    3. 다음 체크박스를 선택합니다.

      • 관리자 읽기
      • 데이터 읽기
      • 데이터 쓰기
    4. 저장을 클릭합니다.

  2. 로그 탐색기 페이지로 이동합니다.

    로그 탐색기 페이지로 이동

  3. 쿼리 빌더 텍스트 상자에 다음 필터를 추가합니다.

    resource.type="audited_resource" resource.labels.service="gkehub.googleapis.com"
    
  4. 쿼리 실행을 클릭합니다.

  5. 쿼리 결과 섹션에서 이벤트에 대해 자세히 알아볼 항목을 선택합니다.

불충분한 CPU

kubectl get events의 출력에는 FailedScheduling 유형의 이벤트가 포함될 수 있습니다. 이벤트는 다음 예시와 같이 표시됩니다.

LAST SEEN   TYPE      REASON              OBJECT                                       MESSAGE
9s          Warning   FailedScheduling    pod/config-management-operator-74594dc8f6    0/1 nodes are available: 1 Insufficient cpu.

이 오류를 해결하려면 다음 옵션 중 하나를 선택합니다.

  • 기존 GKE 노드 풀에 노드 추가
  • 더 큰 노드로 노드 풀 만들기

유효하지만 잘못된 ConfigManagement 객체

YAML 또는 JSON 구문 오류가 아닌 ConfigManagement 객체의 문제로 인해 설치에 실패하면 ConfigManagement 객체가 클러스터에서 인스턴스화될 수는 있지만 올바르게 작동하지 않을 수도 있습니다. 이 경우 nomos status 명령어를 사용하여 ConfigManagement 객체의 오류를 확인할 수 있습니다.

문제가 없는 유효한 설치 상태는 PENDING 또는 SYNCED입니다.

유효하지 않은 설치 상태는 NOT CONFIGURED이며, 다음 오류 중 하나가 표시됩니다.

  • missing git-creds Secret
  • missing required syncRepo field
  • git-creds Secret is missing the key specified by secretType

문제를 해결하려면 구성 오류를 수정합니다. 오류 유형에 따라 ConfigManagement 매니페스트를 클러스터에 다시 적용해야 할 수도 있습니다.

git-creds 보안 비밀을 만드는 것을 잊어버린 경우에는 구성 동기화가 보안 비밀을 생성하는 즉시 이를 감지하므로 구성을 다시 적용할 필요가 없습니다.

ResourceGroup 필드가 계속 변경됨

클러스터에 동기화된 Git 저장소의 경우 모든 리소스의 조정 상태가 ResourceGroup이라는 리소스에 집계됩니다. 각 RootSync 또는 RepoSync 객체에 대해 클러스터에 적용된 리소스 집합을 캡처하고 해당 상태를 수집하기 위해 ResourceGroup이 생성됩니다.

경우에 따라 ResourceGroup이 ResourceGroup의 spec을 계속 업데이트하는 루프에 들어갈 수 있습니다. 이 경우 다음 문제를 발견할 수 있습니다.

  • ResourceGroup의 metadata.generation이 짧은 기간 내에 계속 증가합니다.
  • ResourceGroup spec이 계속 변경됩니다.
  • ResourceGroup spec에 클러스터에 동기화되는 리소스의 status.resourceStatuses가 포함되지 않습니다.

이 문제가 발견되면 Git 저장소의 일부 리소스가 클러스터에 적용되지 못했음을 의미합니다. 이 문제의 원인은 이러한 리소스를 적용하기 위해 필요한 권한이 없기 때문입니다.

RepoSync 리소스 상태를 가져와서 권한이 누락되었는지 확인할 수 있습니다.

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

NAMESPACE를 네임스페이스 저장소를 만든 네임스페이스로 바꿉니다.

nomos status을 사용할 수도 있습니다.

상태에 다음 메시지가 표시되면 NAMESPACE의 조정자가 리소스를 적용하는 데 필요한 권한이 없는 것입니다.

errors:
  - code: "2009"
    errorMessage: |-
      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"

      For more information, see https://g.co/cloud/acm-errors#knv2009

이 문제를 해결하려면 해당 네임스페이스에서 실패한 리소스를 관리하기 위해 ns-reconciler-NAMESPACE 서비스 계정에 권한을 부여하는 RoleBinding 구성을 선언해야 합니다. RoleBinding 추가 방법에 대한 세부정보는 네임스페이스 저장소에서 동기화 구성 섹션에 포함되어 있습니다.

Git 저장소에 있는 대량의 리소스

RepoSync 또는 RootSync 객체로 동기화되는 Git 저장소에 수천 개 이상의 리소스에 대한 구성이 포함된 경우, ResourceGroup의 etcd 객체 크기 제한이 초과될 수 있습니다. 이 경우 Git 저장소에서 리소스의 집계 상태를 확인할 수 없습니다. 집계 상태를 볼 수 없지만 저장소는 계속 동기화됩니다. RepoSync 또는 RootSync 객체에 오류가 표시되지 않으면 Git 저장소가 클러스터에 성공적으로 동기화된 것입니다.

ResourceGroup 리소스가 etcd 객체 크기 제한을 초과하는지 확인하려면 ResourceGroup 리소스 상태와 ResourceGroup 컨트롤러의 로그를 모두 확인해야 합니다.

  1. 다음 명령어를 사용하여 ResourceGroup 상태를 확인합니다.

    • RootSync를 확인하려면 다음 명령어를 실행합니다.
     kubectl get resourcegroup.kpt.dev root-sync -n config-management-system
    
    • RepoSync를 확인하려면 다음 명령어를 실행합니다.
    # For the RepoSync:
    kubectl get resourcegroup.kpt.dev repo-sync -n 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 저장소에서 리소스 수를 줄입니다. 예를 들어 하나의 RootSync 객체를 사용하여 모든 리소스를 동기화하는 대신 저장소를 분할하고 여러 RepoSync 객체에 하나의 RootSync 객체를 사용합니다.

Git 저장소에서 동기화 해제

새 커밋이 Git 저장소로 푸시되지만 클러스터의 구성 동기화 상태가 오랫동안 기존 커밋에 대해 Synced 상태이면(spec.git.period 이상) 다음을 수행해야 합니다. git-sync 컨테이너의 로그를 확인합니다.

# check git-sync logs for a root reconciler
kubectl logs -n config-management-system deployment/root-reconciler -c git-sync

# check git-sync logs for a namespace reconciler
kubectl logs -n config-management-system deployment/ns-reconciler-NAMESPACE -c git-sync

git-sync가 Git 저장소에서 동기화되지 않을 수 있지만 조정자가 이전에 동기화된 커밋에서 동기화를 계속합니다. 다음 예시 출력은 git-sync 문제가 있음을 보여줍니다.

"msg"="unexpected error syncing repo, will retry" "error"="Run(git fetch -f --tags --depth 1 origin develop): exit status 128: { stdout: "", stderr: "fatal: couldn't find remote ref develop\n" }"

이것은 Config Sync 버전 1.8.1 및 이전 버전의 알려진 문제입니다. 이를 해결하기 위해서는 로그에서 오류 메시지를 따라야 합니다. RootSync 또는 RepoSync 객체에서 Git 저장소 또는 spec.git 필드를 업데이트해야 할 수 있습니다.

이미 삭제된 RootSync/RepoSync에서 관리되던 리소스 업데이트/삭제 요청이 admission-webhook.configsync.gke.io에서 거부됨

RootSync 또는 RepoSync 객체를 삭제해도 구성 동기화 주석 및 라벨이 삭제되지 않습니다. 그리고 구성 동기화가 클러스터에 여전히 사용 설정된 상태이면 구성 동기화 허용 웹훅이 이러한 리소스의 수정 또는 삭제를 시도하는 요청을 거부합니다.

이러한 관리되는 리소스를 유지하려는 경우 Git 저장소에 선언된 모든 관리되는 리소스에서 configmanagement.gke.io/managed 주석을 disabled설정하여 먼저 이러한 리소스를 관리 해제할 수 있습니다. 그러면 Config Sync 주석 및 라벨이 관리되는 리소스에서 삭제되지만 해당 리소스가 삭제되지는 않습니다. 동기화가 완료되었으면 RootSync 또는 RepoSync 객체를 삭제할 수 있습니다.

이러한 관리되는 리소스를 삭제하려는 경우에는 비어 있는 Git 디렉터리에서 동기화되도록 RootSync 또는 RepoSync 객체를 수정하여 먼저 관리되는 리소스를 삭제할 수 있습니다. 동기화가 완료되었으면 RootSync 또는 RepoSync 객체를 삭제할 수 있습니다.

관리되는 리소스를 관리 해제하거나 삭제하기 전에 RootSync 또는 RepoSync 객체가 삭제된 경우 RootSync 또는 RepoSync 객체를 다시 추가하고, 관리되는 리소스를 관리 해제 또는 삭제한 후 RootSync 또는 RepoSync 객체를 다시 삭제할 수 있습니다.

오류 메시지 문제 해결

오류: 권한 거부됨

구성 동기화를 구성하려고 시도할 때 다음 예시와 비슷한 오류가 수신되면 GKE Hub 관리자 역할이 없기 때문일 수 있습니다.

Permission 'gkehub.features.create' denied on 'projects/PROJECT_ID/locations/global/features/configmanagement'

필요한 권한이 있는지 확인하려면 권한 준비를 확인하세요.

오류: 허용 웹훅이 요청을 거부함

구성 동기화에서 관리되는 필드에 변경사항을 적용하려고 시도할 때 다음 오류가 표시되면 변경사항 충돌이 발생했기 때문일 수 있습니다.

error: OBJECT could not be patched: admission webhook "v1.admission-webhook.configsync.gke.io"
denied the request: fields managed by Config Sync can not be modified

구성에서 필드를 선언하고 저장소가 클러스터에 동기화되면 구성 동기화가 해당 필드를 관리합니다. 이 필드에 시도하는 모든 변경사항이 충돌하는 변경사항입니다.

예를 들어 저장소에 environment:prod 라벨이 포함된 배포 구성이 있고 클러스터에서 라벨을 environment:dev로 변경하려고 시도하면 변경사항이 충돌하고 위의 오류 메시지가 표시됩니다. 하지만 배포에 tier:frontend와 같은 새 라벨을 추가하는 것은 충돌이 되지 않습니다.

구성 동기화가 객체에 대한 모든 변경사항을 무시하도록 하려면 객체 변형 무시에 설명된 주석을 추가할 수 있습니다.

오류: 허용 웹훅 요청 I/O 시간 초과

조정자가 클러스터에 구성을 적용하려고 할 때 다음 오류가 표시되는 경우:

KNV2009: Internal error occurred: failed calling webhook "v1.admission-webhook.configsync.gke.io": Post https://admission-webhook.config-management-system.svc:8676/admission-webhook?timeout=3s: dial tcp 10.1.1.186:8676: i/o timeout

방화벽에서 제어 영역 네트워크로의 허용 웹훅 포트 8676가 차단되었기 때문일 수 있습니다. 이 문제를 해결하려면 방화벽 규칙을 추가하여 구성 동기화 허용 웹훅이 드리프트 방지에 사용하는 포트 8676를 허용합니다.

오류: 허용 웹훅 연결이 거부됨

조정자가 클러스터에 구성을 적용하려고 할 때 다음 오류가 표시되는 경우:

KNV2009: Internal error occurred: failed calling webhook "v1.admission-webhook.configsync.gke.io": Post "https://admission-webhook.config-management-system.svc:8676/admission-webhook?timeout=3s": dial tcp 10.92.2.14:8676: connect: connection refused

이는 허용 웹훅이 아직 준비되지 않았음을 의미합니다. 구성 동기화를 부트스트랩할 때 발생할 수 있는 일시적인 오류입니다.

문제가 지속되면 허용 웹훅 배포를 살펴보고 pod가 예약될 수 있고 정상 상태인지 확인합니다.

kubectl describe deploy admission-webhook -n config-management-system

kubectl get pods -n config-management-system -l app=admission-webhook

오류: Git 보안 비밀을 마운트할 수 없음

git-sync 컨테이너가 보안 비밀을 사용하여 저장소와 동기화하려고 시도할 때 다음 오류가 발생할 수 있습니다.

KNV2004: unable to sync repo Error in the git-sync container: ERROR: can't configure SSH: can't access SSH key: stat /etc/git-secret/ssh: no such file or directory: lstat /repo/root/rev: no such file or directory

즉, Git 보안 비밀이 git-sync 컨테이너에 성공적으로 마운트되지 않았습니다. 이 문제는 Git 저장소 인증 유형을 none, gcenode, gcpserviceaccount에서 보안 비밀이 필요한 다른 유형으로 전환할 때 발생할 수 있습니다. 이 문제를 해결하려면 다음 명령어를 실행하여 조정자 관리자 및 조정자를 다시 시작합니다.

# Stop the reconciler-manager Pod. The reconciler-manager Deployment will spin
# up a new Pod which can pick up the latest `spec.git.auth`.
kubectl delete po -l app=reconciler-manager -n config-management-system

# Delete the reconciler Deployments. The reconciler-manager will recreate the
# reconciler Deployments with correct volume mount.
kubectl delete deployment -l app=reconciler -n config-management-system

reconciler 또는 git-sync 컨테이너가 OOMKilled됨

Anthos Config Management 버전 1.8.2 이상에서 kubectl을 사용하여 여러 저장소에서 동기화를 구성할 때는 루트 또는 네임스페이스 저장소의 CPU 또는 메모리 한도를 재정의할 수 있습니다. 이러한 값을 재정하려면 RootSync 또는 RepoSync 객체의 spec.override.resources 필드를 사용합니다.

다음 예시에서는 reconciler 컨테이너의 CPU 및 메모리 한도와 루트 조정자의 git-sync 컨테이너의 메모리 한도를 재정의하는 방법을 보여줍니다. git-syncreconciler 컨테이너만 재정의가 허용됩니다. 부분 재정의가 허용되며, 리소스 한도에 대한 재정의 값이 제공되지 않으면 기본 리소스 한도가 사용됩니다.

apiVersion: configsync.gke.io/v1beta1
kind: RootSync
metadata:
  name: root-sync
  namespace: config-management-system
spec:
  sourceFormat: "unstructured"
  override:
    resources:
    - containerName: "reconciler"
      cpuLimit: "888m"
      memoryLimit: "444Mi"
    - containerName: "git-sync"
      memoryLimit: "333Mi"
  git:
     ...

다음 명령어를 실행하여 새 리소스 한도가 적용되는지 확인합니다.

kubectl get deployment.apps/root-reconciler -n config-management-system -o yaml

네임스페이스 조정자의 리소스 한도도 이와 비슷하게 재정의할 수 있습니다.

KNV2004: git-sync 컨테이너의 저장소 오류 동기화 실패(remote did not send all necessary objects 오류와 함께 git fetch 실패)

구성 동기화는 Git 저장소의 부분 클론을 만듭니다. 일부 드문 경우에는 부분 클론에서 커밋을 찾지 못할 수 있으며, 가져올 Git 커밋 수를 늘려야 합니다.

Anthos Config Management 버전 1.8.2 이상에서는 RootSync 또는 RepoSync 객체에서 spec.override.gitSyncDepth 필드를 설정하여 가져올 Git 커밋 수를 설정할 수 있습니다.

  • 이 필드를 제공하지 않으면 구성 동기화가 이를 자동으로 구성합니다.
  • 구성 동기화는 이 필드가 0일 때 전체 클론을 수행하고 이 필드가 0보다 크면 부분 클론을 수행합니다.
  • 이 필드를 음수로 설정하는 것은 허용되지 않습니다.

다음은 가져올 Git 커밋 수를 88로 설정하는 예시입니다.

apiVersion: configsync.gke.io/v1beta1
kind: RootSync
metadata:
  name: root-sync
  namespace: config-management-system
spec:
  override:
    gitSyncDepth: 88
  git:
    ...

다음 명령어를 실행하여 변경사항이 적용되는지 확인합니다(root-reconciler-git-sync ConfigMap의 data 필드에서 GIT_SYNC_DEPTH88로 설정해야 함).

kubectl get cm root-reconciler-git-sync -n config-management-system -o yaml

마찬가지로 네임스페이스 조정자에서 가져올 Git 커밋의 수를 재정의할 수 있습니다.

오류: 조정자 배포를 업그레이드할 수 없음

구성 동기화를 버전 1.6.2와 1.7.0에서 버전 1.7.x와 1.8.x로 업그레이드할 때 조정자 배포의 이미지 버전이 업데이트되지 않을 수 있습니다. 이 문제는 배포 템플릿의 .spec.selector.labels 필드 변경으로 인해 발생합니다. 1.6.2에서 새로운 matchLabel이 추가된 후 1.7.0에서 삭제되었습니다. 라벨 선택기는 변경할 수 없으므로, 조정자 관리자가 조정자를 업그레이드할 수 없습니다.

조정자 관리자 로그를 살펴보면 오류를 확인할 수 있습니다.

kubectl logs -n config-management-system deployment/reconciler-manager -c reconciler-manager

다음은 로그의 오류 예시입니다.

Deployment.apps "root-reconciler" is invalid: spec.selector: Invalid value: v1.LabelSelector{MatchLabels:map[string]string{"app":"reconciler"}, MatchExpressions:[]v1.LabelSelectorRequirement(nil)}: field is immutable

문제를 해결하려면 현재 조정자를 삭제합니다.

kubectl delete deployment -n config-management-system -l app=reconciler

오류: 네임스페이스가 Terminating 단계에서 멈춤

Terminating 단계에서 멈추는 네임스페이스는 다음 조건을 갖습니다.

    message: 'Failed to delete all resource types, 1 remaining: admission webhook
      "v1.admission-webhook.configsync.gke.io" denied the request: system:serviceaccount:kube-system:namespace-controller
      is not authorized to delete managed resource "_configmap_bookstore_cm1"'
    reason: ContentDeletionFailed
    status: "True"
    type: NamespaceDeletionContentFailure

이 문제는 루트 저장소에서 네임스페이스를 삭제하려고 시도하지만 네임스페이스 아래의 일부 객체가 네임스페이스 조정자에서 여전히 관리되고 있는 경우에 발생합니다. 네임스페이스가 삭제되면 해당 서비스 계정이 system:serviceaccount:kube-system:namespace-controller네임스페이스 컨트롤러가 해당 네임스페이스에서 모든 객체를 삭제하려고 시도합니다. 하지만 구성 동기화 허용 웹훅은 루트 또는 네임스페이스 조정자만 이러한 객체를 삭제하도록 허용하고, 네임스페이스 컨트롤러가 이러한 객체를 삭제하는 것은 거부합니다.

해결 방법은 구성 동기화 허용 웹훅을 삭제하는 것입니다.

kubectl delete deployment.apps/admission-webhook -n config-management-system

Config Management Operator는 구성 동기화 허용 웹훅을 다시 만듭니다.

이 방법이 작동하지 않으면 구성 동기화를 다시 설치해야 합니다.

오류가 다시 발생하는 것을 방지하기 위해 네임스페이스를 삭제하기 전 네임스페이스 저장소가 삭제되었는지 확인해야 합니다. 네임스페이스 저장소 삭제 방법에 대한 안내는 여기를 참조하세요.

오류: ValidatingWebhookConfiguration에서 webhooks 필드를 찾을 수 없음

kubectl logs -n config-management-system -l app=admission-webhook 실행 시 구성 동기화 허용 웹훅 로그에서 다음 오류가 발생하는 경우 다음을 참조하세요.

cert-rotation "msg"="Unable to inject cert to webhook." "error"="`webhooks` field not found in ValidatingWebhookConfiguration" "gvk"={"Group":"admissionregistration.k8s.io","Version":"v1","Kind":"ValidatingWebhookConfiguration"} "name"="admission-webhook.configsync.gke.io"
controller-runtime/manager/controller/cert-rotator "msg"="Reconciler error" "error"="`webhooks` field not found in ValidatingWebhookConfiguration" "name"="admission-webhook-cert" "namespace"="config-management-system"

이는 root-reconciler가 클러스터에 리소스를 동기화하지 않았음을 의미합니다. 이는 root-reconciler가 아직 준비되지 않았거나 Git 저장소에서 동기화할 항목이 없기 때문일 수 있습니다(예: 동기화 디렉터리가 비어 있음). 문제가 계속되면 root-reconciler의 상태를 확인해야 합니다.

kubectl get pods -n config-management-system -l configsync.gke.io/reconciler=root-reconciler

root-reconciler가 비정상 종료되거나 OOMKilled 오류가 발생하면 리소스 한도를 늘려야 합니다.