클러스터 만들기 또는 업그레이드 문제 해결

이 페이지에서는 Google Distributed Cloud 클러스터 설치 또는 업그레이드와 관련된 문제를 해결하는 방법을 설명합니다.

추가 지원이 필요하면 Cloud Customer Care에 문의하세요.

설치 문제

다음 섹션은 Google Distributed Cloud 설치와 관련된 문제를 해결하는 데 도움이 될 수 있습니다.

일시적인 오류 메시지

Google Distributed Cloud의 설치 프로세스는 지속적인 조정 루프입니다. 따라서 설치하는 동안 로그에 일시적인 오류 메시지가 표시될 수 있습니다.

설치가 성공적으로 완료되면 이러한 오류는 무시해도 됩니다. 다음은 일반적인 일시적 오류 로그 메시지의 목록입니다.

  Internal error occurred: failed calling webhook "webhook.cert-manager.io": Post
  https://cert-manager-webhook.cert-manager.svc:443/mutate?timeout=10s:
  dial tcp IP_ADDRESS:443: connect: connection refused
  Internal error occurred: failed calling webhook "vcluster.kb.io": Post
  https://webhook-service.kube-system.svc:443/validate-baremetal-cluster-gke-io-v1-cluster?timeout=30s:
  dial tcp IP_ADDRESS:443: connect: connection refused
  Failed to register cluster with GKE Hub; gcloud output: error running command
  'gcloud container fleet memberships register CLUSTER_NAME  --verbosity=error --quiet':
  error: exit status 1, stderr: 'ERROR: (gcloud.container.hub.memberships.register)
  Failed to check if the user is a cluster-admin: Unable to connect to the server: EOF
  Get
  https://127.0.0.1:34483/apis/infrastructure.baremetal.cluster.gke.io/v1/namespaces/cluster-
  cluster1/baremetalmachines: dial tcp 127.0.0.1:34483: connect: connection refused"
  Create Kind Cluster "msg"="apply run failed" "error"="unable to recognize \"/tmp/kout088683152\": no matches for kind \"NetworkLogging\" in version \"networking.gke.io/v1alpha1\""
  Create Kind Cluster "msg"="apply run failed" "error"="unable to recognize \"/tmp/kout869681888\": no matches for kind \"Provider\" in version \"clusterctl.cluster.x-k8s.io/v1alpha3\""

Google Cloud 서비스 계정 키가 만료된 경우 bmctl에서 다음 오류 메시지가 표시됩니다.

Error validating cluster config: 3 errors occurred:
        * GKEConnect check failed: Get https://gkehub.googleapis.com/v1beta1/projects/project/locations/global/memberships/admin: oauth2: cannot fetch token: 400 Bad Request
Response: {"error":"invalid_grant","error_description":"Invalid JWT Signature."}
        * ClusterOperations check failed: Post https://cloudresourcemanager.googleapis.com/v1/projects/project:testIamPermissions?alt=json&prettyPrint=false: oauth2: cannot fetch token: 400 Bad Request
Response: {"error":"invalid_grant","error_description":"Invalid JWT Signature."}
        * GCR pull permission for bucket: artifacts.anthos-baremetal-release.appspot.com failed: Get https://storage.googleapis.com/storage/v1/b/artifacts.anthos-baremetal-release.appspot.com/iam/testPermissions?alt=json&permissions=storage.objects.get&permissions=storage.objects.list&prettyPrint=false: oauth2: cannot fetch token: 400 Bad Request
Response: {"error":"invalid_grant","error_description":"Invalid JWT Signature."}

새 서비스 계정 키를 생성해야 합니다.

부트스트랩 클러스터를 사용하여 문제 디버깅

Google Distributed Cloud에서 자체 관리형(관리자, 하이브리드 또는 독립형) 클러스터를 만드는 경우 클러스터를 만드는데 필요한 Kubernetes 컨트롤러를 일시적으로 호스트하도록 Docker의 Kubernetes(kind) 클러스터를 배포합니다. 이러한 임시 클러스터를 부트스트랩 클러스터라고 합니다. 사용자 클러스터는 부트스트랩 클러스터를 사용하지 않고 관리 관리자 또는 하이브리드 클러스터를 통해 생성되고 업그레이드됩니다.

설치하려고 할 때 kind 클러스터가 이미 배포에 있으면 Google Distributed Cloud에서 기존 kind 클러스터를 삭제합니다. 설치 또는 업그레이드가 성공한 후에만 삭제가 수행됩니다. 성공한 후에도 기존 kind 클러스터를 보존하려면 bmctl--keep-bootstrap-cluster 플래그를 사용합니다.

Google Distributed Cloud는 WORKSPACE_DIR/.kindkubeconfig 아래에 부트스트랩 클러스터 구성 파일을 만듭니다. 클러스터 만들기 및 업그레이드 중에만 부트스트랩 클러스터에 연결할 수 있습니다.

이미지를 가져오려면 부트스트랩 클러스터가 Docker 저장소에 액세스해야 합니다. 비공개 레지스트리를 사용하지 않는 한 레지스트리가 기본적으로 Container Registry로 지정됩니다. 클러스터를 만드는 동안 bmctl이 다음 파일을 만듭니다.

  • bmctl-workspace/config.json: 레지스트리 액세스를 위한 Google Cloud 서비스 계정을 포함합니다. 클러스터 구성 파일의 gcrKeyPath 필드에서 사용자 인증 정보를 가져옵니다.

  • bmctl-workspace/config.toml: kind 클러스터의 containerd 구성을 포함합니다.

부트스트랩 클러스터 로그 검사

부트스트랩 클러스터를 디버깅하려면 다음 단계를 수행합니다.

  • 클러스터 만들기 및 업그레이드 중에 부트스트랩 클러스터에 연결합니다.
  • 부트스트랩 클러스터의 로그를 가져옵니다.

다음 폴더에서 bmctl을 실행하기 위해 사용하는 머신에서 로그를 찾을 수 있습니다.

  • bmctl-workspace/CLUSTER_NAME/log/create-cluster-TIMESTAMP/bootstrap-cluster/
  • bmctl-workspace/CLUSTER_NAME/log/upgrade-cluster-TIMESTAMP/bootstrap-cluster/

CLUSTER_NAMETIMESTAMP를 클러스터 이름과 해당 시스템 시간으로 바꿉니다.

부트스트랩 클러스터에서 직접 로그를 가져오려면 클러스터 만들기 및 업그레이드 동안 다음 명령어를 실행할 수 있습니다.

docker exec -it bmctl-control-plane bash

이 명령어는 부트스트랩 클러스터에서 실행되는 bmctl 제어영역 컨테이너 내에서 터미널을 엽니다.

kubeletcontainerd 로그를 검사하려면 다음 명령어를 사용하고 출력에서 오류 또는 경고를 찾습니다.

journalctl -u kubelet
journalctl -u containerd

클러스터 업그레이드 문제

Google Distributed Cloud 클러스터를 업그레이드하면 진행 상황을 모니터링하고 클러스터와 노드의 상태를 확인할 수 있습니다.

다음 지침은 업그레이드가 정상적으로 계속 진행되는지 또는 문제가 있는지 확인하는 데 도움이 될 수 있습니다.

업그레이드 진행 상태 모니터링

업그레이드 프로세스 중에 클러스터의 상태를 보려면 kubectl describe cluster 명령어를 사용합니다.

kubectl describe cluster CLUSTER_NAME \
    --namespace CLUSTER_NAMESPACE \
    --kubeconfig ADMIN_KUBECONFIG

다음 값을 바꿉니다.

  • CLUSTER_NAME: 클러스터 이름입니다.
  • CLUSTER_NAMESPACE: 클러스터의 네임스페이스입니다.
  • ADMIN_KUBECONFIG: 관리자 kubeconfig 파일입니다.
    • 기본적으로 관리자, 하이브리드, 독립형 클러스터는 인플레이스 업그레이드를 사용합니다. bmctl upgrade 명령어로 --use-bootstrap=true 플래그를 사용하면 업그레이드 작업에서 부트스트랩 클러스터를 사용합니다. 부트스트랩 클러스터가 사용될 때 업그레이드 진행 상황을 모니터링하려면 부트스트랩 클러스터 kubeconfig 파일(.kindkubeconfig)의 경로를 지정합니다. 이 파일은 작업공간 디렉터리에 있습니다.

출력에서 Status 섹션을 업그레이드하여 클러스터 업그레이드 상태의 집계를 확인합니다. 클러스터에서 오류를 보고하는 경우 다음 섹션을 수행하여 문제가 있는 문제를 해결합니다.

노드가 준비되었는지 확인

업그레이드 프로세스를 수행하는 동안 kubectl get nodes 명령어를 사용하여 클러스터의 노드 상태를 확인합니다.

kubectl get nodes --kubeconfig KUBECONFIG

노드가 업그레이드 프로세스를 성공적으로 완료했는지 확인하려면 명령어 응답의 VERSIONAGE 열을 확인합니다. VERSION는 클러스터의 Kubernetes 버전입니다. 지정된 Google Distributed Cloud 버전의 Kubernetes 버전을 보려면 버전 기록을 참조하세요.

노드에 NOT READY가 표시되면 노드를 연결하고 kubelet 상태를 확인합니다.

systemctl status kubelet

kubelet 로그를 검토할 수도 있습니다.

journalctl -u kubelet

kubelet 상태 출력과 노드에 문제가 발생한 이유를 나타내는 메시지에 대한 로그를 검토합니다.

업그레이드하는 노드 확인

클러스터의 어느 노드를 업그레이드 중인지 확인하려면 kubectl get baremetalmachines 명령어를 사용합니다.

kubectl get baremetalmachines --namespace CLUSTER_NAMESPACE \
    --kubeconfig ADMIN_KUBECONFIG

다음 값을 바꿉니다.

  • CLUSTER_NAMESPACE: 클러스터의 네임스페이스입니다.
  • ADMIN_KUBECONFIG: 관리자 kubeconfig 파일입니다.
    • 관리자, 하이브리드 또는 독립형 업그레이드에 부트스트랩 클러스터를 사용하는 경우 부트스트랩 클러스터 kubeconfig 파일(bmctl-workspace/.kindkubeconfig)을 지정합니다.

다음 출력 예시는 업그레이드 중인 노드가 DESIRED ABM VERSION과 다른 ABM VERSION임을 보여줍니다.

NAME         CLUSTER    READY   INSTANCEID               MACHINE      ABM VERSION   DESIRED ABM VERSION
10.200.0.2   cluster1   true    baremetal://10.200.0.2   10.200.0.2   1.13.0        1.14.0
10.200.0.3   cluster1   true    baremetal://10.200.0.3   10.200.0.3   1.13.0        1.13.0

드레이닝을 진행 중인 노드 확인

업그레이드 프로세스 중에는 노드에서 포드가 드레이닝되고 노드가 성공적으로 업그레이드될 때까지 예약이 사용 중지됩니다. 드레이닝되는 노드를 확인하려면 kubectl get nodes 명령어를 사용합니다.

kubectl get nodes --kubeconfig USER_CLUSTER_KUBECONFIG | grep "SchedulingDisabled"

USER_CLUSTER_KUBECONFIG를 사용자 클러스터 kubeconfig 파일의 경로로 바꿉니다.

STATUS 열은 SchedulingDisabled를 보고하는 노드만 표시하도록 grep을 사용하여 필터링됩니다. 이 상태는 노드가 드레이닝되고 있음을 나타냅니다.

관리자 클러스터에서 노드 상태를 확인할 수도 있습니다.

kubectl get baremetalmachines -n CLUSTER_NAMESPACE \
  --kubeconfig ADMIN_KUBECONFIG

다음 값을 바꿉니다.

  • CLUSTER_NAMESPACE: 클러스터의 네임스페이스입니다.
  • ADMIN_KUBECONFIG: 관리자 kubeconfig 파일입니다.
    • 관리자, 하이브리드 또는 독립형 업그레이드에 부트스트랩 클러스터를 사용하는 경우 부트스트랩 클러스터 kubeconfig 파일(bmctl-workspace/.kindkubeconfig)을 지정합니다.

드레이닝되는 노드에는 MAINTENANCE 열 아래의 상태가 표시됩니다.

노드가 오랫동안 드레이닝 상태에 있는 이유 확인

이전 섹션의 방법 중 하나를 사용하여 kubectl get nodes 명령어를 사용하여 드레이닝되는 노드를 식별합니다. kubectl get pods 명령어를 사용하고 이 노드 이름을 필터링하여 추가 세부정보를 확인합니다.

kubectl get pods --all-namespaces -o wide --field-selector spec.nodeName=NODE_NAME

NODE_NAME을 드레이닝하는 노드의 이름으로 바꿉니다. 출력에서 중단되었거나 드레이닝이 느린 포드 목록이 반환됩니다. 노드의 드레이닝 프로세스가 20분 넘게 걸리면 포드가 중단된 상태에서도 업그레이드가 진행됩니다.

출시 버전 1.29부터 노드 드레이닝 프로세스에서 PodDisruptionBudgets(PDB)를 준수하는 제거 API를 사용합니다.

다음 PDB 설정은 노드 드레이닝 문제를 일으킬 수 있습니다.

  • 여러 PDB에서 관리되는 포드

  • 다음과 같은 PDB 정적 구성:

    • maxUnavailable == 0
    • minUnavailable >= 총 복제본

    Deployment, ReplicaSet 또는 StatefulSet와 같은 상위 수준 리소스에 정의되기 때문에 PDB 리소스에서 총 복제본 수를 확인하기 어렵습니다. PDB는 해당 구성에서 선택기를 기반으로만 포드에 일치합니다. 정적 PDB 구성으로 인해 문제가 발생하는지 진단하기 위한 좋은 방법은 pdb.Status.ExpectPods <= pdb.Status.DesiredHealthy인지 먼저 확인하고, 이러한 상황을 허용하는 언급된 정적 구성 중 하나가 있는지 확인하는 것입니다.

0인 PDB 리소스의 계산된 DisruptionsAllowed 값과 같은 런타임 위반은 노드 드레이닝을 차단할 수도 있습니다. 추가 중단을 허용할 수 없는 PodDisruptionBudget 객체를 구성한 경우, 반복된 시도 후에도 노드 업그레이드가 제어 영역 버전으로 업그레이드되지 않을 수 있습니다. 이러한 실패를 방지하려면 PodDisruptionBudget 구성을 지키면서 노드 드레이닝을 허용하도록 Deployment 또는 HorizontalPodAutoscaler를 수직 확장하는 것이 좋습니다.

중단을 허용하지 않는 모든 PodDisruptionBudget 객체를 보려면 다음 명령어를 사용합니다.

kubectl get poddisruptionbudget --all-namespaces \
    -o jsonpath='{range .items[?(@.status.disruptionsAllowed==0)]}{.metadata.name}/{.metadata.namespace}{"\n"}{end}'

포드가 비정상적인 이유 확인

포드에 upgrade-first-node 또는 upgrade-node 제어 영역 IP 주소가 포함된 경우 업그레이드가 실패할 수 있습니다. 이 동작은 일반적으로 정적 포드가 정상이 아니기 때문에 발생합니다.

  1. crictl ps -a 명령어로 정적 포드를 확인하고 비정상 종료되는 Kubernetes 또는 etcd 포드를 찾습니다. 실패한 포드가 있으면 포드에 대한 로그를 검토하여 비정상 종료 이유를 확인합니다.

    비정상 종료 루프 동작의 가능한 원인은 다음과 같습니다.

    • 정적 포드에 마운트된 파일의 권한이나 소유자가 올바르지 않습니다.
    • 가상 IP 주소에 대한 연결이 작동하지 않습니다.
    • etcd 관련 문제입니다.
  2. crictl ps 명령어가 작동하지 않거나 아무것도 반환하지 않으면 kubeletcontainerd 상태를 확인합니다. systemctl status SERVICEjournalctl -u SERVICE 명령어를 사용하여 로그를 확인합니다.

다음 단계