Resolva problemas com a ferramenta de linhas de comando kubectl


Esta página mostra como resolver problemas com a ferramenta de linha de comandos kubectl quando trabalha no Google Kubernetes Engine (GKE).

Para informações relacionadas, consulte os seguintes recursos:

Erros de autenticação e autorização

Se estiver a ter erros relacionados com a autenticação e a autorização quando usa os comandos da ferramenta de linha de comandos kubectl, leia as secções seguintes para obter aconselhamento.

Erro: 401 (não autorizado)

Quando se liga a clusters do GKE, pode receber um erro de autenticação e autorização com o código de estado HTTP 401 (Unauthorized). Este problema pode ocorrer quando tenta executar um comando kubectl no cluster do GKE a partir de um ambiente local. Para saber mais, consulte o artigo Problema: erros de autenticação e autorização.

Erro: âmbitos de autenticação insuficientes

Quando executa gcloud container clusters get-credentials, pode receber o seguinte erro:

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

Este erro ocorre porque está a tentar aceder à API GKE a partir de uma VM do Compute Engine que não tem o âmbito cloud-platform.

Para resolver este erro, conceda o âmbito cloud-platform em falta. Para ver instruções sobre como alterar os âmbitos na sua instância de VM do Compute Engine, consulte o artigo Criar e ativar contas de serviço para instâncias na documentação do Compute Engine.

Erro: não foi encontrado o executável gke-gcloud-auth-plugin

Podem ocorrer mensagens de erro semelhantes às seguintes ao tentar executar comandos kubectl ou clientes personalizados que interagem com o 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

Para resolver o problema, instale o gke-gcloud-auth-plugin conforme descrito em Instale os plug-ins necessários.

Erro: nenhum fornecedor de autenticação encontrado

O seguinte erro ocorre se o kubectl ou os clientes personalizados do Kubernetes tiverem sido criados com a versão 1.26 ou posterior do Kubernetes:client-go

no Auth Provider found for name "gcp"

Para resolver este problema, conclua os seguintes passos:

  1. Instale o gke-gcloud-auth-plugin conforme descrito em Instale os plugins necessários.

  2. Atualize para a versão mais recente da CLI gcloud:

    gcloud components update
    
  3. Atualize o ficheiro kubeconfig:

    gcloud container clusters get-credentials CLUSTER_NAME \
        --location=CONTROL_PLANE_LOCATION
    

    Substitua o seguinte:

    • CLUSTER_NAME: o nome do cluster.
    • CONTROL_PLANE_LOCATION: a localização do Compute Engine do plano de controlo do seu cluster. Indique uma região para clusters regionais ou uma zona para clusters zonais.

Erro: o plug-in de autenticação da GCP foi descontinuado. Use o gcloud em alternativa

Pode ver a seguinte mensagem de aviso depois de instalar o gke-gcloud-auth-plugin e executar um comando kubectl num cluster do GKE:

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

Esta mensagem é apresentada se a versão do cliente for anterior à 1.26.

Para resolver este problema, diga ao seu cliente para usar o gke-gcloud-auth-pluginplug-in de autenticação em alternativa:

  1. Abra o script de início de sessão da shell num editor de texto:

    Bash

    vi ~/.bashrc

    Zsh

    vi ~/.zshrc

    Se estiver a usar o PowerShell, ignore este passo.

  2. Defina a seguinte variável de ambiente:

    Bash

    export USE_GKE_GCLOUD_AUTH_PLUGIN=True
    

    Zsh

    export USE_GKE_GCLOUD_AUTH_PLUGIN=True
    

    PowerShell

    [Environment]::SetEnvironmentVariable('USE_GKE_GCLOUD_AUTH_PLUGIN', True, 'Machine')
    
  3. Aplique a variável no seu ambiente:

    Bash

    source ~/.bashrc

    Zsh

    source ~/.zshrc
    

    PowerShell

    Saia do terminal e abra uma nova sessão do terminal.

  4. Atualize a CLI gcloud:

    gcloud components update
    
  5. Autentique-se no cluster:

    gcloud container clusters get-credentials CLUSTER_NAME \
        --location=CONTROL_PLANE_LOCATION
    

    Substitua o seguinte:

    • CLUSTER_NAME: o nome do cluster.
    • CONTROL_PLANE_LOCATION: a localização do Compute Engine do plano de controlo do seu cluster. Indique uma região para clusters regionais ou uma zona para clusters zonais.

Problema: o comando kubectl não foi encontrado

Se receber uma mensagem a indicar que o comando kubectl não foi encontrado, reinstale o ficheiro binário kubectl e defina a variável de ambiente $PATH:

  1. Instale o ficheiro binário kubectl:

    gcloud components update kubectl
    
  2. Quando o instalador lhe pedir para modificar a variável de ambiente $PATH, introduza y para continuar. A modificação desta variável permite-lhe usar comandos kubectl sem escrever o respetivo caminho completo.

    Em alternativa, adicione a seguinte linha onde quer que a sua shell armazene as variáveis de ambiente, como ~/.bashrc (ou ~/.bash_profile no macOS):

    export PATH=$PATH:/usr/local/share/google/google-cloud-sdk/bin/
    
  3. Execute o seguinte comando para carregar o ficheiro atualizado. O exemplo seguinte usa .bashrc:

    source ~/.bashrc
    

    Se estiver a usar o macOS, use ~/.bash_profile em vez de .bashrc.

Problema: os comandos kubectl devolvem o erro "connection refused"

Se os comandos kubectl devolverem um erro "connection refused", tem de definir o contexto do cluster com o seguinte comando:

gcloud container clusters get-credentials CLUSTER_NAME \
       --location=CONTROL_PLANE_LOCATION

Substitua o seguinte:

  • CLUSTER_NAME: o nome do cluster.
  • CONTROL_PLANE_LOCATION: a localização do Compute Engine do plano de controlo do seu cluster. Indique uma região para clusters regionais ou uma zona para clusters zonais.

Se não tiver a certeza do que introduzir para o nome ou a localização do cluster, use o seguinte comando para listar os seus clusters:

gcloud container clusters list

Erro: o comando kubectl excedeu o tempo limite

Se criou um cluster e tentou executar um comando kubectl no cluster, mas o comando kubectl excede o tempo limite, é apresentado um erro semelhante ao seguinte:

  • 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.

Estes erros indicam que kubectl não consegue comunicar com o plano de controlo do cluster.

Para resolver este problema, valide e defina o contexto onde o cluster está definido e garanta a conetividade ao cluster:

  1. Aceda a $HOME/.kube/config ou execute o comando kubectl config view para verificar se o ficheiro de configuração contém o contexto do cluster e o endereço IP externo do plano de controlo.

  2. Defina as credenciais do cluster:

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

    Substitua o seguinte:

    • CLUSTER_NAME: o nome do cluster.
    • CONTROL_PLANE_LOCATION: a localização do Compute Engine do plano de controlo do seu cluster. Indique uma região para clusters regionais ou uma zona para clusters zonais.
    • PROJECT_ID: o ID do projeto no qual o cluster foi criado.
  3. Se ativou redes autorizadas no cluster, certifique-se de que a respetiva lista de redes autorizadas existentes inclui o IP de saída da máquina a partir da qual está a tentar estabelecer ligação. Pode encontrar as suas redes autorizadas existentes na consola ou executando o seguinte comando:

    gcloud container clusters describe CLUSTER_NAME \
        --location=CONTROL_PLANE_LOCATION \
        --project=PROJECT_ID \
        --format "flattened(controlPlaneEndpointsConfig.ipEndpointsConfig.authorizedNetwork
    sConfig.cidrBlocks[])"
    

    Se o IP de saída do computador não estiver incluído na lista de redes autorizadas a partir do resultado do comando anterior, conclua um dos seguintes passos:

Erro: os comandos kubectl devolvem uma falha ao negociar uma versão da API

Se os comandos kubectl devolverem um erro failed to negotiate an API version, tem de garantir que o kubectl tem credenciais de autenticação:

gcloud auth application-default login

Problema: o comando kubectl logs, attach, exec ou port-forward deixa de responder

Se os comandos kubectl logs, attach, exec ou port-forward deixarem de responder, normalmente, o servidor da API não consegue comunicar com os nós.

Primeiro, verifique se o cluster tem nós. Se reduziu o número de nós no cluster para zero, os comandos não funcionam. Para resolver este problema, redimensione o cluster de modo a ter, pelo menos, um nó.

Se o cluster tiver, pelo menos, um nó, verifique se está a usar túneis SSH ou do proxy Konnectivity para ativar a comunicação segura. As secções seguintes abordam os passos de resolução de problemas específicos de cada serviço:

Resolva problemas de SSH

Se estiver a usar o SSH, o GKE guarda um ficheiro de chave pública SSH nos metadados do seu projeto do Compute Engine. Todas as VMs do Compute Engine que usam imagens fornecidas pela Google verificam regularmente os metadados comuns do projeto e os metadados da instância para encontrar chaves SSH a adicionar à lista de utilizadores autorizados da VM. O GKE também adiciona uma regra de firewall à sua rede do Compute Engine para permitir o acesso SSH a partir do endereço IP do plano de controlo a cada nó no cluster.

As seguintes definições podem causar problemas com a comunicação SSH:

  • As regras da firewall da sua rede não permitem o acesso SSH a partir do plano de controlo.

    Todas as redes do Compute Engine são criadas com uma regra de firewall denominada default-allow-ssh que permite o acesso SSH a partir de todos os endereços IP (requerendo uma chave privada válida). O GKE também insere uma regra SSH para cada cluster público do formulário gke-CLUSTER_NAME-RANDOM_CHARACTERS-ssh que permite o acesso SSH especificamente do plano de controlo do cluster aos nós do cluster.

    Se nenhuma destas regras existir, o plano de controlo não pode abrir túneis SSH.

    Para verificar se esta é a causa do problema, verifique se a sua configuração tem estas regras.

    Para resolver este problema, identifique a etiqueta que está em todos os nós do cluster e, em seguida, adicione novamente uma regra de firewall que permita o acesso a VMs com essa etiqueta a partir do endereço IP do plano de controlo.

  • A entrada de metadados comuns do seu projeto para ssh-keys está completa.

    Se a entrada de metadados do projeto com o nome ssh-keys estiver perto do respetivo limite de tamanho máximo, o GKE não consegue adicionar a respetiva chave SSH para abrir túneis SSH.

    Para verificar se é este o problema, verifique o comprimento da lista de ssh-keys. Pode ver os metadados do seu projeto executando o seguinte comando e, opcionalmente, incluindo a flag --project:

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

    Para resolver este problema, elimine algumas das chaves SSH que já não são necessárias.

  • Definiu um campo de metadados com a chave ssh-keys nas VMs no cluster.

    O agente de nó nas VMs prefere chaves SSH por instância a chaves SSH ao nível do projeto. Por isso, se tiver definido chaves SSH especificamente nos nós do cluster, os nós não respeitam a chave SSH do plano de controlo nos metadados do projeto.

    Para verificar se é este o problema, execute gcloud compute instances describe VM_NAME e procure um campo ssh-keys nos metadados.

    Para resolver este problema, elimine as chaves SSH por instância dos metadados da instância.

Resolva problemas do proxy de conetividade

Pode determinar se o seu cluster usa o proxy Konnectivity verificando a seguinte implementação do sistema:

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

Se o seu cluster usar o proxy de conetividade, o resultado é semelhante ao seguinte:

NAME                 READY   UP-TO-DATE   AVAILABLE   AGE
konnectivity-agent   3/3     3            3           18d

Depois de verificar que está a usar o proxy Konnectivity, certifique-se de que os agentes Konnectivity têm o acesso à firewall necessário e que as políticas de rede estão configuradas corretamente.

Permita o acesso necessário à firewall

Verifique se as regras da firewall da sua rede permitem o acesso às seguintes portas:

  • Porta do plano de controlo: na criação do cluster, os agentes de Konnectivity estabelecem ligações ao plano de controlo na porta 8132. Quando executa um comando, o servidor da API usa esta ligação para comunicar com o cluster.kubectl Certifique-se de que permite o tráfego de saída para o plano de controlo do cluster na porta 8132 (para comparação, o servidor da API usa a porta 443). Se tiver regras que negam o acesso de saída, pode ter de modificar as regras ou criar exceções.
  • kubelet porta: uma vez que os agentes Konnectivity são pods do sistema implementados nos nós do cluster, certifique-se de que as regras de firewall permitem os seguintes tipos de tráfego:

    • Tráfego de entrada para as suas cargas de trabalho na porta 10250 a partir dos intervalos de pods.
    • Tráfego de saída dos seus intervalos de pods.

    Se as regras de firewall não permitirem este tipo de tráfego, modifique as regras.

Ajuste a política de rede

O proxy de conetividade pode ter problemas se a política de rede do seu cluster fizer uma das seguintes ações:

  • Bloqueia a entrada do espaço de nomes kube-system para o espaço de nomes workload
  • Bloqueia a saída para o plano de controlo do cluster na porta 8132

Quando a entrada é bloqueada pela política de rede dos pods de carga de trabalho, os registos konnectivity-agent incluem uma mensagem de erro semelhante à seguinte:

"error dialing backend" error="dial tcp POD_IP_ADDRESS:PORT: i/o timeout"

Na mensagem de erro, POD_IP_ADDRESS é o endereço IP do pod de carga de trabalho.

Quando a saída é bloqueada pela política de rede, os registos konnectivity-agent incluem uma mensagem de erro semelhante à seguinte:

"cannot connect once" err="rpc error: code = Unavailable desc = connection error: desc = "transport: Error while dialing: dial tcp CP_IP_ADDRESS:8132: i/o timeout

No erro, CP_IP_ADDRESS é o endereço IP do plano de controlo do cluster.

Estas funcionalidades não são necessárias para o funcionamento correto do cluster. Se preferir manter a rede do cluster bloqueada a todo o acesso externo, tenha em atenção que funcionalidades como estas não funcionam.

Para verificar se as regras de entrada ou saída da política de rede são a causa do problema, encontre as políticas de rede no espaço de nomes afetado executando o seguinte comando:

kubectl get networkpolicy --namespace AFFECTED_NAMESPACE

Para resolver o problema com a política de entrada, adicione o seguinte ao campo spec.ingress das políticas de rede:

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

Para resolver o problema com a política de saída, adicione o seguinte ao campo spec.egress das políticas de rede:

egress:
- to:
  - ipBlock:
      cidr: CP_IP_ADDRESS/32
  ports:
  - protocol: TCP
    port: 8132

Se a sua política de rede usar uma combinação de regras de entrada e saída, considere ajustar ambas.

Ajuste o agente de ocultação de IP

O plano de controlo do cluster aceita o tráfego dos agentes de Konnectivity se o endereço IP de origem estiver nos intervalos de endereços IP dos pods. Se modificar a configuração do ip-masq-agent para mascarar o endereço IP de origem do tráfego para o plano de controlo do cluster, os agentes de conetividade podem ter erros de conetividade.

Para resolver o problema e ajudar a garantir que o tráfego dos agentes de Konnectivity para o painel de controlo do cluster não é mascarado para o endereço IP do nó, adicione o endereço IP do painel de controlo à lista nonMasqueradeCIDRs no ip-masq-agent ConfigMap:

nonMasqueradeCIDRs:
- CONTROL_PLANE_IP_ADDRESS/32

Para mais informações acerca desta configuração, consulte o artigo Agente de ocultação de IP.

Erro: os comandos kubectl falham com o erro de agente indisponível

Quando executa comandos kubectl que precisam de estabelecer ligação do plano de controlo do GKE a um pod, por exemplo, kubectl exec, kubectl logs ou kubectl port-forward, o comando pode falhar com mensagens de erro semelhantes às seguintes:

Error from server: error dialing backend: No agent available
failed to call webhook: Post "https://WEBHOOK_SERVICE.WEBHOOK_NAMESPACE.svc:PORT/PATH?timeout=10s": No agent available
v1beta1.metrics.k8s.io failed with: failing or missing response from https://NODE_IP:10250/apis/metrics.k8s.io/v1beta1: Get "https://NODE_IP:10250/apis/metrics.k8s.io/v1beta1": No agent available

Estes erros indicam um problema com a Konnectivity, o túnel de comunicação seguro entre o plano de controlo do GKE e os nós do cluster. Em particular, significa que o konnectivity-server no plano de controlo não consegue estabelecer ligação a nenhum pod konnectivity-agent saudável no espaço de nomes kube-system.

Para resolver este problema, experimente as seguintes soluções:

  1. Verifique o estado dos konnectivity-agentpods:

    1. Verifique se os konnectivity-agent Pods estão em execução:

      kubectl get pods -n kube-system -l k8s-app=konnectivity-agent
      

      O resultado é semelhante ao seguinte:

      NAME                                   READY   STATUS    RESTARTS  AGE
      konnectivity-agent-abc123def4-xsy1a    2/2     Running   0         31d
      konnectivity-agent-abc123def4-yza2b    2/2     Running   0         31d
      konnectivity-agent-abc123def4-zxb3c    2/2     Running   0         31d
      

      Reveja o valor na coluna Status. Se os pods tiverem o estado Running, reveja os registos para verificar se existem problemas de ligação. Caso contrário, investigue por que motivo os pods não estão a ser executados.

    2. Reveja os registos para ver se existem problemas de ligação. Se os Pods tiverem o estado Running, verifique os registos para ver se existem problemas de ligação. Uma vez que o comando kubectl logs depende da Konnectivity, use o Explorador de registos na consola:Google Cloud

      1. Na Google Cloud consola, aceda ao Explorador de registos.

        Aceda ao Explorador de registos

      2. No painel de consultas, introduza a seguinte consulta.

        resource.type="k8s_container"
        resource.labels.cluster_name="CLUSTER_NAME"
        resource.labels.namespace_name="kube-system"
        labels."k8s-pod/k8s-app"="konnectivity-agent"
        resource.labels.container_name="konnectivity-agent"
        

        Substitua CLUSTER_NAME pelo nome do seu cluster.

      3. Clique em Executar consulta.

      4. Reveja o resultado. Quando revê os konnectivity-agent registos, procure erros que indiquem o motivo pelo qual o agente não consegue estabelecer ligação. Os erros de autenticação ou autorização apontam frequentemente para um webhook mal configurado que bloqueia as críticas. Normalmente, os erros "Ligação recusada" ou "Limite de tempo excedido" significam que uma regra de firewall ou uma política de rede está a bloquear o tráfego para o plano de controlo na porta TCP 8132 ou está a bloquear o tráfego entre o agente de Konnectivity e outros nós. Os erros de certificado sugerem que uma firewall ou um proxy está a inspecionar e a interferir com o tráfego TLS encriptado.

    3. Investigue por que motivo os pods não estão a ser executados. Se os pods tiverem o estado Pending ou outro estado de não execução, investigue a causa. O konnectivity-agent é executado como uma implementação e não como um DaemonSet. Uma vez que é executado como uma implementação, os pods do agente só precisam de ser executados num subconjunto de nós. No entanto, se esse subconjunto específico de nós estiver indisponível, todo o serviço pode falhar.

      Seguem-se algumas causas comuns de um pod que não está em execução:

      • Falhas de nós personalizadas que impedem o agendamento de um pod.
      • Recursos do nó insuficientes (CPU ou memória).
      • Políticas de autorização binária restritivas que bloqueiam imagens do sistema do GKE.

      Para obter mais detalhes sobre o motivo pelo qual um pod específico não está a ser executado, use o comando kubectl describe:

      kubectl describe pod POD_NAME -n kube-system
      

      Substitua POD_NAME pelo nome do pod que não está em execução.

  2. Investigue os seus webhooks de admissão para garantir que nenhum está a bloquear pedidos da API TokenReview. O konnectivity-agent baseia-se em tokens de contas de serviço, pelo que a interferência com as revisões de tokens pode impedir a ligação dos agentes. Se a causa for um webhook, o Konnectivity não pode ser recuperado até que o webhook com falhas seja removido ou reparado.

  3. Certifique-se de que as regras da firewall permitem o tráfego de saída TCP dos seus nós do GKE para o endereço IP do plano de controlo na porta 8132. Esta ligação é necessária para que a app konnectivity-agent alcance o serviço Konnectivity. Para mais informações, consulte o artigo Permita o acesso necessário à firewall.

  4. Certifique-se de que não existem regras da política de rede que restrinjam o tráfego essencial do Konnectivity. As regras da política de rede devem permitir o tráfego intra-cluster (de pod para pod) no espaço de nomes kube-system e o tráfego de saída dos pods konnectivity-agent para o plano de controlo do GKE.

O que se segue?