Solução de problemas de segurança do cluster


Nesta página, mostramos como resolver problemas relacionados a configurações de segurança nos clusters do Autopilot e do Standard do Google Kubernetes Engine (GKE).

RBAC e IAM

Contas do IAM autenticadas não realizam ações no cluster

O problema a seguir ocorre quando você tenta executar uma ação no cluster, mas o GKE não consegue encontrar uma política de RBAC que autorize a ação. O GKE tenta encontrar uma política do IAM que conceda a mesma permissão. Se isso falhar, você encontrará uma mensagem de erro semelhante a esta:

Error from server (Forbidden): roles.rbac.authorization.k8s.io is forbidden:
User "example-account@example-project.iam.gserviceaccount.com" cannot list resource "roles" in
API group "rbac.authorization.k8s.io" in the namespace "kube-system": requires
one of ["container.roles.list"] permission(s).

Para resolver esse problema, use uma política de RBAC a fim de conceder as permissões para a tentativa de ação. Por exemplo, para resolver o problema no exemplo anterior, conceda um papel que tenha a permissão list em objetos roles no namespace kube-system. Para instruções, consulte Autorizar ações em clusters usando o controle de acesso baseado em papéis.

Identidade da carga de trabalho

O pod não pode se autenticar no Google Cloud

Se não for possível autenticar seu aplicativo no Google Cloud, confira se as seguintes configurações estão corretas:

  1. Verifique se você ativou a API Service Account Credentials do IAM no projeto que contém o cluster do GKE.

    Ativar a API IAM Credentials

  2. Garanta que a Identidade da carga de trabalho esteja ativada no cluster. Para isso, verifique se ela tem um pool definido de Identidade da carga de trabalho:

    gcloud container clusters describe CLUSTER_NAME \
        --format="value(workloadIdentityConfig.workloadPool)"
    

    Se você ainda não tiver especificado uma zona ou região padrão para gcloud, talvez seja necessário especificar uma sinalização --region ou --zone ao executar este comando.

  3. Verifique se o servidor de metadados do GKE está configurado no pool de nós em que o aplicativo está em execução:

    gcloud container node-pools describe NODEPOOL_NAME \
        --cluster=CLUSTER_NAME \
        --format="value(config.workloadMetadataConfig.mode)"
    
  4. Confira se a conta de serviço do Kubernetes está anotada corretamente:

    kubectl describe serviceaccount \
        --namespace NAMESPACE KSA_NAME
    

    A saída contém uma anotação semelhante a esta:

    iam.gke.io/gcp-service-account: GSA_NAME@PROJECT_ID.iam.gserviceaccount.com
    
  5. Verifique se a conta de serviço do Google está configurada corretamente:

    gcloud iam service-accounts get-iam-policy \
        GSA_NAME@GSA_PROJECT.iam.gserviceaccount.com
    

    A saída contém uma vinculação semelhante a esta:

    - members:
      - serviceAccount:PROJECT_ID.svc.id.goog[NAMESPACE/KSA_NAME]
      role: roles/iam.workloadIdentityUser
    
  6. Se você tiver uma política de rede de cluster, permita que a saída seja permitida para 127.0.0.1/32 na porta 988 para clusters que executam versões do GKE anteriores a 1.21.0-gke.1.000 ou 169.254.169.252/32 na porta 988 para clusters que executam o GKE versão 1.21.0-gke.1000 e posterior Para clusters que executam o GKE Dataplane V2, verifique se você permitiu a saída para 169.254.169.254/32 na porta 80.

    kubectl describe networkpolicy NETWORK_POLICY_NAME
    

Erros de tempo limite na inicialização do pod

O servidor de metadados do GKE precisa de alguns segundos para começar a aceitar solicitações em um novo pod. Portanto, as tentativas de autenticação que usam a Identidade da carga de trabalho nos primeiros segundos da vida de um pod podem falhar em aplicativos e nas bibliotecas de cliente do Google Cloud configuradas com um tempo limite curto.

Se você encontrar erros de tempo limite, tente o seguinte:

  • Atualize as bibliotecas de cliente do Google Cloud usadas pelas suas cargas de trabalho.
  • Altere o código do aplicativo para aguardar alguns segundos e tente novamente.
  • Implante um initContainer que aguarde até que o servidor de metadados do GKE esteja pronto antes de executar o contêiner principal do pod.

    Por exemplo, o seguinte manifesto é para um pod com initContainer:

    apiVersion: v1
    kind: Pod
    metadata:
      name: pod-with-initcontainer
    spec:
      serviceAccountName: KSA_NAME
      initContainers:
      - image:  gcr.io/google.com/cloudsdktool/cloud-sdk:alpine
        name: workload-identity-initcontainer
        command:
        - '/bin/bash'
        - '-c'
        - |
          curl -sS -H 'Metadata-Flavor: Google' 'http://169.254.169.254/computeMetadata/v1/instance/service-accounts/default/token' --retry 30 --retry-connrefused --retry-max-time 60 --connect-timeout 3 --fail --retry-all-errors > /dev/null && exit 0 || echo 'Retry limit exceeded. Failed to wait for metadata server to be available. Check if the gke-metadata-server Pod in the kube-system namespace is healthy.' >&2; exit 1
      containers:
      - image: gcr.io/your-project/your-image
        name: your-main-application-container
    

A identidade da carga de trabalho falha devido à indisponibilidade do plano de controle

O servidor de metadados não pode retornar a identidade da carga de trabalho quando o plano de controle do cluster não está disponível. As chamadas para o servidor de metadados retornam o código de status 500.

A entrada de registro pode ser semelhante a esta no Explorador de registros:

dial tcp 35.232.136.58:443: connect: connection refused

Isso levará à indisponibilidade esperada da Identidade da carga de trabalho.

O plano de controle pode estar indisponível em clusters zonais na manutenção do cluster, como rotação de IPs, upgrade de VMs do plano de controle ou redimensionamento de clusters ou pools de nós. Saiba mais sobre como escolher um plano de controle regional ou zonal para saber mais sobre a disponibilidade do plano de controle. Mudar para o cluster regional eliminará esse problema.

Falha na identidade da carga de trabalho

Se o servidor de metadados do GKE for bloqueado por qualquer motivo, a identidade da carga de trabalho falhará.

Se você estiver usando o Istio, adicione a seguinte anotação no nível do aplicativo a todas as cargas de trabalho que usam a Identidade da carga de trabalho:

"traffic.sidecar.istio.io/excludeOutboundIPRanges=169.254.169.254/32"

Se preferir, altere a chave global.proxy.excludeIPRanges Istio ConfigMap para fazer o mesmo.

O pod gke-metadata-server está falhando

O pod DaemonSet do sistema gke-metadata-server facilita a Identidade da carga de trabalho nos nós. O pod usa recursos de memória proporcionais ao número de contas de serviço do Kubernetes no cluster.

O problema a seguir ocorre quando o uso de recursos do pod gke-metadata-server excede os limites. O kubelet remove o pod com um erro de memória insuficiente. Você poderá ter esse problema se o cluster tiver mais de 3.000 contas de serviço do Kubernetes.

Para identificar o problema, faça o seguinte:

  1. Encontre pods gke-metadata-server com falha no namespace kube-system:

    kubectl get pods -n=kube-system | grep CrashLoopBackOff
    

    O resultado será assim:

    NAMESPACE     NAME                        READY     STATUS             RESTARTS   AGE
    kube-system   gke-metadata-server-8sm2l   0/1       CrashLoopBackOff   194        16h
    kube-system   gke-metadata-server-hfs6l   0/1       CrashLoopBackOff   1369       111d
    kube-system   gke-metadata-server-hvtzn   0/1       CrashLoopBackOff   669        111d
    kube-system   gke-metadata-server-swhbb   0/1       CrashLoopBackOff   30         136m
    kube-system   gke-metadata-server-x4bl4   0/1       CrashLoopBackOff   7          15m
    
  2. Descreva o pod com falha para confirmar que a causa foi uma remoção de falta de memória:

    kubectl describe pod POD_NAME --namespace=kube-system | grep OOMKilled
    

Para restaurar a funcionalidade do servidor de metadados do GKE, reduza o número de contas de serviço no cluster para menos de 3 mil.

Falha ao ativar a Identidade da carga de trabalho com a mensagem de erro de falha no DeployPatch

O GKE usa o agente de serviço do Kubernetes Engine gerenciado pelo Google Cloud para facilitar a Identidade da carga de trabalho nos clusters. O Google Cloud concede automaticamente a esse agente de serviço o papel de agente de serviço do Kubernetes Engine (roles/container.serviceAgent) no projeto quando você ativa a API Google Kubernetes Engine.

Se você tentar ativar a Identidade da carga de trabalho nos clusters de um projeto em que o agente de serviço não tem o papel de agente de serviço do Kubernetes Engine, a operação falhará com uma mensagem de erro semelhante a esta:

Error waiting for updating GKE cluster workload identity config: DeployPatch failed

Para resolver esse problema, tente o seguinte:

  1. Verifique se o agente de serviço existe no projeto e se ele está configurado corretamente:

    gcloud projects get-iam-policy PROJECT_ID \
        --flatten=bindings \
        --filter=bindings.role=roles/container.serviceAgent \
        --format="value[delimiter='\\n'](bindings.members)"
    

    Substitua o PROJECT_ID pelo ID do projeto do Google Cloud.

    Se o agente de serviço estiver configurado corretamente, a saída mostrará a identidade completa dele:

    serviceAccount:service-PROJECT_NUMBER@container-engine-robot.iam.gserviceaccount.com
    

    Se a saída não mostrar o agente de serviço, conceda a ele o papel de agente de serviço do Kubernetes Engine.

  2. Confira o número do projeto do Google Cloud:

    gcloud projects describe PROJECT_ID \
        --format="value(projectNumber)"
    

    O resultado será assim:

    123456789012
    
  3. Conceda ao agente de serviço o seguinte papel:

    gcloud projects add-iam-policy-binding PROJECT_ID \
        --member=serviceAccount:service-PROJECT_NUMBER@container-engine-robot.iam.gserviceaccount.com \
        --role=roles/container.serviceAgent \
        --condition=None
    

    Substitua PROJECT_NUMBER pelo número do projeto do Google Cloud.

Tente ativar novamente a Identidade da carga de trabalho.