kubectl 명령줄 도구 문제 해결


이 페이지에서는 Google Kubernetes Engine(GKE)에서 작업할 때 kubectl 명령줄 도구 문제를 해결하는 방법을 보여줍니다. 일반적인 도움말은 Kubernetes 문서의 kubectl 문제 해결을 참조하세요.

kubectl 명령줄 도구 명령어를 사용할 때 인증 및 승인 관련 오류가 발생하면 다음 섹션을 참조하세요.

GKE 클러스터에 연결할 때 HTTP 상태 코드 401 (Unauthorized)과 함께 인증 및 승인 오류가 발생할 수 있습니다. 이 문제는 로컬 환경의 GKE 클러스터에서 kubectl 명령어를 실행할 때 발생할 수 있습니다. 자세한 내용은 문제: 인증 및 승인 오류를 참조하세요.

gcloud container clusters get-credentials를 실행할 때 다음 오류가 표시될 수 있습니다.

ERROR: (gcloud.container.clusters.get-credentials) ResponseError: code=403, message=Request had insufficient authentication scopes.

이 오류는 cloud-platform 범위가 없는 Compute Engine VM에서 Kubernetes Engine API에 액세스하려고 할 때 발생합니다.

이 오류를 해결하려면 누락된 cloud-platform 범위를 부여합니다. Compute Engine VM 인스턴스의 범위를 변경하는 방법에 대한 자세한 내용은 Compute Engine 문서의 인스턴스의 서비스 계정 만들기 및 사용 설정을 참조하세요.

오류: 실행 가능한 gke-gcloud-auth-plugin을 찾을 수 없음

kubectl 명령어 또는 GKE와 상호작용하는 커스텀 클라이언트를 실행하려고 할 때 다음과 유사한 오류 메시지가 표시될 수 있습니다.

Unable to connect to the server: getting credentials: exec: executable gke-gcloud-auth-plugin not found

It looks like you are trying to use a client-go credential plugin that is not installed.

To learn more about this feature, consult the documentation available at:
      https://kubernetes.io/docs/reference/access-authn-authz/authentication/#client-go-credential-plugins

Visit cloud.google.com/kubernetes-engine/docs/how-to/cluster-access-for-kubectl#install_plugin to install gke-gcloud-auth-plugin.
Unable to connect to the server: getting credentials: exec: fork/exec /usr/lib/google-cloud-sdk/bin/gke-gcloud-auth-plugin: no such file or directory

이 문제를 해결하려면 필요한 플러그인 설치에 설명된 대로 gke-gcloud-auth-plugin을 설치합니다.

오류: 인증 제공업체를 찾을 수 없음

kubectl 또는 커스텀 Kubernetes 클라이언트가 Kubernetes client-go 버전 1.26 이상으로 빌드된 경우 다음 오류가 발생합니다.

no Auth Provider found for name "gcp"

이 문제를 해결하려면 다음 단계를 완료하시기 바랍니다.

  1. 필수 플러그인 설치에 설명된 대로 gke-gcloud-auth-plugin을 설치합니다.

  2. gcloud CLI를 최신 버전으로 업데이트합니다.

    gcloud components update
    
  3. kubeconfig 파일을 업데이트합니다.

    gcloud container clusters get-credentials CLUSTER_NAME \
        --region=COMPUTE_REGION
    

    다음을 바꿉니다.

    • CLUSTER_NAME: 클러스터의 이름입니다.
    • COMPUTE_REGION: 클러스터의 Compute Engine 리전입니다. 영역 클러스터의 경우 --zone=COMPUTE_ZONE을 사용합니다.

오류: gcp 인증 플러그인은 지원 중단되었습니다. 대신 gcloud를 사용하세요.

gke-gcloud-auth-plugin을 설치하고 GKE 클러스터에 kubectl 명령어를 실행한 후 다음 경고 메시지가 표시될 수 있습니다.

WARNING: the gcp auth plugin is deprecated in v1.22+, unavailable in v1.25+; use gcloud instead.

이 메시지는 클라이언트 버전이 1.26 이전이면 나타납니다.

이 문제를 해결하려면 대신 gke-gcloud-auth-plugin 인증 플러그인을 사용하도록 클라이언트에 지시합니다.

  1. 텍스트 편집기에서 셸 로그인 스크립트를 엽니다.

    vi ~/.bashrc
    vi ~/.zshrc

    PowerShell을 사용하는 경우 이 단계를 건너뜁니다.

  2. 다음 환경 변수를 설정합니다.

    export USE_GKE_GCLOUD_AUTH_PLUGIN=True
    
    export USE_GKE_GCLOUD_AUTH_PLUGIN=True
    
    [Environment]::SetEnvironmentVariable('USE_GKE_GCLOUD_AUTH_PLUGIN', True, 'Machine')
    
  3. 사용자 환경에서 변수를 적용합니다.

    source ~/.bashrc
    source ~/.zshrc
    

    터미널을 종료하고 새 터미널 세션을 엽니다.

  4. gcloud CLI 업데이트

    gcloud components update
    
  5. 클러스터를 인증합니다.

    gcloud container clusters get-credentials CLUSTER_NAME \
        --region=COMPUTE_REGION
    

    다음을 바꿉니다.

    • CLUSTER_NAME: 클러스터의 이름입니다.
    • COMPUTE_REGION: 클러스터의 Compute Engine 리전입니다. 영역 클러스터의 경우 --zone=COMPUTE_ZONE을 사용합니다.

문제: kubectl 명령어를 찾을 수 없음

kubectl 명령어를 찾을 수 없다는 메시지가 표시되면 kubectl 바이너리를 다시 설치하고 $PATH 환경 변수를 설정합니다.

  1. kubectl 바이너리를 설치합니다.

    gcloud components update kubectl
    
  2. 설치 프로그램에서 $PATH 환경 변수를 수정하라는 메시지가 표시되면 y를 입력하여 계속합니다. 이 변수를 수정하면 전체 경로를 입력하지 않고도 kubectl 명령어를 사용할 수 있습니다.

    또는 셸이 환경 변수를 저장하는 위치(예: ~/.bashrc(macOS에서는 ~/.bash_profile))에 다음 줄을 추가합니다.

    export PATH=$PATH:/usr/local/share/google/google-cloud-sdk/bin/
    
  3. 다음 명령어를 실행하여 업데이트된 파일을 로드합니다. 다음 예시는 .bashrc를 사용합니다.

    source ~/.bashrc
    

    macOS를 사용하는 경우 .bashrc 대신 ~/.bash_profile을 사용하세요.

문제: kubectl 명령어가 'connection refused' 오류 반환

kubectl 명령어가 "연결 거부됨" 오류를 반환하면 다음 명령어를 사용하여 클러스터 컨텍스트를 설정해야 합니다.

gcloud container clusters get-credentials CLUSTER_NAME

CLUSTER_NAME을 클러스터 이름으로 바꿉니다. 클러스터 이름을 모르겠으면 다음 명령어를 사용하여 클러스터를 나열합니다.

gcloud container clusters list

오류: kubectl 명령어의 시간 초과됨

클러스터를 만들고 클러스터에 kubectl 명령어를 실행하려 했지만 kubectl 명령어 시간 초과가 발생하는 경우 다음과 유사한 오류가 표시됩니다.

  • Unable to connect to the server: dial tcp IP_ADDRESS: connect: connection timed out
  • Unable to connect to the server: dial tcp IP_ADDRESS: i/o timeout.

이러한 오류는 kubectl이 클러스터 컨트롤 플레인과 통신할 수 없음을 나타냅니다.

이 문제를 해결하려면 클러스터가 설정된 컨텍스트를 확인 및 설정하고 클러스터에 대한 연결을 확인하세요.

  1. $HOME/.kube/config로 이동하거나 kubectl config view 명령어를 실행하여 구성 파일에 클러스터 컨텍스트 및 컨트롤 플레인의 외부 IP 주소가 포함되는지 확인합니다.

  2. 클러스터 사용자 인증 정보를 설정합니다.

    gcloud container clusters get-credentials CLUSTER_NAME \
        --location=COMPUTE_LOCATION \
        --project=PROJECT_ID
    

    다음을 바꿉니다.

    • CLUSTER_NAME: 클러스터의 이름입니다.
    • COMPUTE_LOCATION: Compute Engine 위치입니다.
    • PROJECT_ID: 클러스터가 생성된 프로젝트의 ID입니다.
  3. 클러스터가 비공개 GKE 클러스터인 경우 기존 승인된 네트워크 목록에 연결하려는 원본 머신의 발신 IP가 포함되어 있는지 확인합니다. 콘솔에서 또는 다음 명령어를 실행하여 기존 승인된 네트워크를 찾을 수 있습니다.

    gcloud container clusters describe CLUSTER_NAME \
        --location=COMPUTE_LOCATION \
        --project=PROJECT_ID \
        --format "flattened(masterAuthorizedNetworksConfig.cidrBlocks[])"
    

    머신의 발신 IP가 이전 명령어 출력에 표시된 승인된 네트워크 목록에 포함되지 않았으면 다음 단계 중 하나를 수행합니다.

오류: kubectl 명령어가 api 버전 협상 실패를 반환함

kubectl 명령어가 failed to negotiate an API version 오류를 반환하면 kubectl에 인증 사용자 인증 정보가 있는지 확인해야 합니다.

gcloud auth application-default login

문제: kubectl logs, attach, exec, port-forward 명령어가 응답하지 않음

kubectl logs, attach, exec 또는 port-forward 명령어에서 응답을 중지하면 일반적으로 API 서버가 노드와 통신할 수 없습니다.

먼저 클러스터에 노드가 있는지 확인합니다. 클러스터의 노드 수를 0으로 줄이면 명령어가 작동하지 않습니다. 이 문제를 해결하려면 적어도 노드가 하나가 되도록 클러스터의 크기를 조절합니다.

클러스터에 노드가 하나 이상 있으면 보안 통신을 사용 설정하기 위해 SSH 또는 Konnectivity 프록시 터널을 사용 중인지 확인합니다. 다음 섹션에서는 각 서비스와 관련된 문제 해결 단계에 대해 설명합니다.

SSH 문제 해결

SSH를 사용하는 경우 GKE는 Compute Engine 프로젝트 메타데이터에 SSH 공개 키 파일을 저장합니다. Google 제공 이미지를 사용하는 모든 Compute Engine VM은 VM의 승인된 사용자 목록에 추가할 SSH 키를 위해 프로젝트의 공통 메타데이터와 인스턴스의 메타데이터를 정기적으로 확인합니다. 또한 GKE는 컨트롤 플레인의 IP 주소에서 클러스터의 각 노드로 SSH 액세스를 허용하는 방화벽 규칙을 Compute Engine 네트워크에 추가합니다.

다음 설정으로 인해 SSH 통신에 문제가 발생할 수 있습니다.

  • 네트워크의 방화벽 규칙은 컨트롤 플레인에서 SSH 액세스를 허용하지 않습니다.

    모든 Compute Engine 네트워크는 모든 IP 주소에서 SSH 액세스를 허용하는(유효한 비공개 키 필요) default-allow-ssh라는 방화벽 규칙으로 생성됩니다. 또한 GKE는 특별히 클러스터의 컨트롤 플레인에서 클러스터의 노드로 SSH 액세스를 허용하는 gke-CLUSTER_NAME-RANDOM_CHARACTERS-ssh 형식의 SSH 규칙을 각 공개 클러스터에 삽입합니다.

    이러한 규칙 중 어느 규칙이라도 존재하지 않으면 컨트롤 플레인에서 SSH 터널을 열 수 없습니다.

    이것이 문제의 원인인지 확인하려면 구성에 해당 규칙이 포함되는지 확인합니다.

    이 문제를 해결하려면 모든 클러스터 노드에 있는 태그를 식별한 후 컨트롤 플레인의 IP 주소에서 해당 태그가 있는 VM에 대한 액세스를 허용하는 방화벽 규칙을 다시 추가하세요.

  • 프로젝트의 ssh-keys 공통 메타데이터 항목이 가득 찼습니다.

    ssh-keys라는 프로젝트의 메타데이터 항목이 최대 크기 제한에 가까워지면 GKE가 SSH 터널을 열기 위해 자체 SSH 키를 추가할 수 없습니다.

    이 문제가 맞는지 확인하려면 ssh-keys 목록의 길이를 확인합니다. 선택적으로 --project 플래그를 포함해서 다음 명령어를 실행하여 프로젝트의 메타데이터를 볼 수 있습니다.

    gcloud compute project-info describe [--project=PROJECT_ID]
    

    이 문제를 해결하려면 더 이상 필요 없는 일부 SSH 키를 삭제합니다.

  • 클러스터의 VM에서 ssh-keys 키로 메타데이터 필드를 설정했습니다.

    VM의 노드 에이전트는 프로젝트 전체 SSH 키보다 인스턴스별 ssh-keys를 선호합니다. 따라서 특별히 클러스터 노드에 SSH 키를 설정한 경우, 프로젝트 메타데이터에 있는 컨트롤 플레인의 SSH 키가 노드에 사용되지 않습니다.

    이 문제가 맞는지 확인하려면 gcloud compute instances describe VM_NAME을 실행하고 메타데이터에서 ssh-keys 필드를 확인합니다.

    이 문제를 해결하려면 인스턴스 메타데이터에서 인스턴스당 SSH 키를 삭제합니다.

Konnectivity 프록시 문제 해결

다음 시스템 배포를 확인하여 클러스터에 Konnectivity 프록시가 사용되는지 확인할 수 있습니다.

kubectl get deployments konnectivity-agent --namespace kube-system

다음 설정으로 인해 Konnectivity 프록시에 문제가 발생할 수 있습니다.

  • 네트워크의 방화벽 규칙은 컨트롤 플레인에 대해 Konnectivity 에이전트 액세스를 허용하지 않습니다.

    클러스터를 만들면 Konnectivity 에이전트 포드가 컨트롤 플레인에 대해 연결을 설정하고 포트 8132에서 유지보수합니다. kubectl 명령어 중 하나를 실행하면 API 서버가 이 연결을 사용해서 클러스터와 통신합니다.

    네트워크의 방화벽 규칙에 이그레스 거부 규칙이 포함된 경우 에이전트 연결을 방해할 수 있습니다.

    이 문제가 맞는지 확인하려면 네트워크 방화벽 규칙을 보고 이그레스 거부 규칙이 포함되어 있는지 확인합니다.

    이 문제를 해결하려면 포트 8132에서 클러스터 컨트롤 플레인에 대한 이그레스 트래픽을 허용하세요. (비교를 위해 API 서버에는 443이 사용됩니다.)

  • 클러스터의 네트워크 정책에 따라 kube-system 네임스페이스에서 workload 네임스페이스로 인그레스가 차단됩니다.

    이러한 기능은 클러스터의 정상 작동에 필요하지 않습니다. 클러스터의 네트워크를 모든 외부 액세스로부터 잠그려고 하면 이러한 기능이 작동하지 않습니다.

    이 문제인지 확인하려면 다음 명령어를 실행하여 영향을 받는 네임스페이스에서 네트워크 정책을 찾습니다.

    kubectl get networkpolicy --namespace AFFECTED_NAMESPACE
    

    이 문제를 해결하려면 네트워크 정책의 spec.ingress 필드에 다음을 추가합니다.

    - from:
      - namespaceSelector:
          matchLabels:
            kubernetes.io/metadata.name: kube-system
        podSelector:
          matchLabels:
            k8s-app: konnectivity-agent
    

다음 단계

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