This is the multi-page printable view of this section. Click here to print.

Return to the regular view of this page.

Solução de problemas em Clusters

Depurando problemas comuns em clusters.

Esta documentação é sobre solução de problemas em clusters; assumimos que você já descartou sua aplicação como a causa raiz do problema que está enfrentando. Consulte o guia de solução de problemas em aplicações para dicas sobre depuração de aplicações. Você também pode visitar o documento de visão geral de solução de problemas para mais informações.

Para solução de problemas do kubectl, consulte Solução de problemas do kubectl.

Listando seu cluster

A primeira coisa a depurar no seu cluster é se todos os seus nós estão registrados corretamente.

Execute o seguinte comando:

kubectl get nodes

E verifique se todos os nós que você espera ver estão presentes e se todos estão no estado Ready.

Para obter informações detalhadas sobre a integridade geral do seu cluster, você pode executar:

kubectl cluster-info dump

Exemplo: depurando um nó indisponível/inacessível

Às vezes, durante a depuração, pode ser útil verificar o status de um nó -- por exemplo, porque você notou um comportamento estranho de um Pod que está executando no nó, ou para descobrir por que um Pod não será alocado no nó. Assim como com os Pods, você pode usar kubectl describe node e kubectl get node -o yaml para recuperar informações detalhadas sobre os nós. Por exemplo, aqui está o que você verá se um nó estiver indisponível (desconectado da rede, ou o kubelet morre e não reinicia, etc.). Observe os eventos que mostram que o nó está NotReady, e também observe que os pods não estão mais em execução (eles são removidos após cinco minutos de status NotReady).

kubectl get nodes
NAME                     STATUS       ROLES     AGE     VERSION
kube-worker-1            NotReady     <none>    1h      v1.23.3
kubernetes-node-bols     Ready        <none>    1h      v1.23.3
kubernetes-node-st6x     Ready        <none>    1h      v1.23.3
kubernetes-node-unaj     Ready        <none>    1h      v1.23.3
kubectl describe node kube-worker-1
Name:               kube-worker-1
Roles:              <none>
Labels:             beta.kubernetes.io/arch=amd64
                    beta.kubernetes.io/os=linux
                    kubernetes.io/arch=amd64
                    kubernetes.io/hostname=kube-worker-1
                    kubernetes.io/os=linux
                    node.alpha.kubernetes.io/ttl: 0
                    volumes.kubernetes.io/controller-managed-attach-detach: true
CreationTimestamp:  Thu, 17 Feb 2022 16:46:30 -0500
Taints:             node.kubernetes.io/unreachable:NoExecute
                    node.kubernetes.io/unreachable:NoSchedule
Unschedulable:      false
Lease:
  HolderIdentity:  kube-worker-1
  AcquireTime:     <unset>
  RenewTime:       Thu, 17 Feb 2022 17:13:09 -0500
Conditions:
  Type                 Status    LastHeartbeatTime                 LastTransitionTime                Reason              Message
  ----                 ------    -----------------                 ------------------                ------              -------
  NetworkUnavailable   False     Thu, 17 Feb 2022 17:09:13 -0500   Thu, 17 Feb 2022 17:09:13 -0500   WeaveIsUp           Weave pod has set this
  MemoryPressure       Unknown   Thu, 17 Feb 2022 17:12:40 -0500   Thu, 17 Feb 2022 17:13:52 -0500   NodeStatusUnknown   Kubelet stopped posting node status.
  DiskPressure         Unknown   Thu, 17 Feb 2022 17:12:40 -0500   Thu, 17 Feb 2022 17:13:52 -0500   NodeStatusUnknown   Kubelet stopped posting node status.
  PIDPressure          Unknown   Thu, 17 Feb 2022 17:12:40 -0500   Thu, 17 Feb 2022 17:13:52 -0500   NodeStatusUnknown   Kubelet stopped posting node status.
  Ready                Unknown   Thu, 17 Feb 2022 17:12:40 -0500   Thu, 17 Feb 2022 17:13:52 -0500   NodeStatusUnknown   Kubelet stopped posting node status.
Addresses:
  InternalIP:  192.168.0.113
  Hostname:    kube-worker-1
Capacity:
  cpu:                2
  ephemeral-storage:  15372232Ki
  hugepages-2Mi:      0
  memory:             2025188Ki
  pods:               110
Allocatable:
  cpu:                2
  ephemeral-storage:  14167048988
  hugepages-2Mi:      0
  memory:             1922788Ki
  pods:               110
System Info:
  Machine ID:                 9384e2927f544209b5d7b67474bbf92b
  System UUID:                aa829ca9-73d7-064d-9019-df07404ad448
  Boot ID:                    5a295a03-aaca-4340-af20-1327fa5dab5c
  Kernel Version:             5.13.0-28-generic
  OS Image:                   Ubuntu 21.10
  Operating System:           linux
  Architecture:               amd64
  Container Runtime Version:  containerd://1.5.9
  Kubelet Version:            v1.23.3
  Kube-Proxy Version:         v1.23.3
Non-terminated Pods:          (4 in total)
  Namespace                   Name                                 CPU Requests  CPU Limits  Memory Requests  Memory Limits  Age
  ---------                   ----                                 ------------  ----------  ---------------  -------------  ---
  default                     nginx-deployment-67d4bdd6f5-cx2nz    500m (25%)    500m (25%)  128Mi (6%)       128Mi (6%)     23m
  default                     nginx-deployment-67d4bdd6f5-w6kd7    500m (25%)    500m (25%)  128Mi (6%)       128Mi (6%)     23m
  kube-system                 kube-proxy-dnxbz                     0 (0%)        0 (0%)      0 (0%)           0 (0%)         28m
  kube-system                 weave-net-gjxxp                      100m (5%)     0 (0%)      200Mi (10%)      0 (0%)         28m
Allocated resources:
  (Total limits may be over 100 percent, i.e., overcommitted.)
  Resource           Requests     Limits
  --------           --------     ------
  cpu                1100m (55%)  1 (50%)
  memory             456Mi (24%)  256Mi (13%)
  ephemeral-storage  0 (0%)       0 (0%)
  hugepages-2Mi      0 (0%)       0 (0%)
Events:
...
kubectl get node kube-worker-1 -o yaml
apiVersion: v1
kind: Node
metadata:
  annotations:
    node.alpha.kubernetes.io/ttl: "0"
    volumes.kubernetes.io/controller-managed-attach-detach: "true"
  creationTimestamp: "2022-02-17T21:46:30Z"
  labels:
    beta.kubernetes.io/arch: amd64
    beta.kubernetes.io/os: linux
    kubernetes.io/arch: amd64
    kubernetes.io/hostname: kube-worker-1
    kubernetes.io/os: linux
  name: kube-worker-1
  resourceVersion: "4026"
  uid: 98efe7cb-2978-4a0b-842a-1a7bf12c05f8
spec: {}
status:
  addresses:
  - address: 192.168.0.113
    type: InternalIP
  - address: kube-worker-1
    type: Hostname
  allocatable:
    cpu: "2"
    ephemeral-storage: "14167048988"
    hugepages-2Mi: "0"
    memory: 1922788Ki
    pods: "110"
  capacity:
    cpu: "2"
    ephemeral-storage: 15372232Ki
    hugepages-2Mi: "0"
    memory: 2025188Ki
    pods: "110"
  conditions:
  - lastHeartbeatTime: "2022-02-17T22:20:32Z"
    lastTransitionTime: "2022-02-17T22:20:32Z"
    message: Weave pod has set this
    reason: WeaveIsUp
    status: "False"
    type: NetworkUnavailable
  - lastHeartbeatTime: "2022-02-17T22:20:15Z"
    lastTransitionTime: "2022-02-17T22:13:25Z"
    message: kubelet has sufficient memory available
    reason: KubeletHasSufficientMemory
    status: "False"
    type: MemoryPressure
  - lastHeartbeatTime: "2022-02-17T22:20:15Z"
    lastTransitionTime: "2022-02-17T22:13:25Z"
    message: kubelet has no disk pressure
    reason: KubeletHasNoDiskPressure
    status: "False"
    type: DiskPressure
  - lastHeartbeatTime: "2022-02-17T22:20:15Z"
    lastTransitionTime: "2022-02-17T22:13:25Z"
    message: kubelet has sufficient PID available
    reason: KubeletHasSufficientPID
    status: "False"
    type: PIDPressure
  - lastHeartbeatTime: "2022-02-17T22:20:15Z"
    lastTransitionTime: "2022-02-17T22:15:15Z"
    message: kubelet is posting ready status
    reason: KubeletReady
    status: "True"
    type: Ready
  daemonEndpoints:
    kubeletEndpoint:
      Port: 10250
  nodeInfo:
    architecture: amd64
    bootID: 22333234-7a6b-44d4-9ce1-67e31dc7e369
    containerRuntimeVersion: containerd://1.5.9
    kernelVersion: 5.13.0-28-generic
    kubeProxyVersion: v1.23.3
    kubeletVersion: v1.23.3
    machineID: 9384e2927f544209b5d7b67474bbf92b
    operatingSystem: linux
    osImage: Ubuntu 21.10
    systemUUID: aa829ca9-73d7-064d-9019-df07404ad448

Examinando logs

Por enquanto, investigar mais profundamente o cluster requer fazer login nas máquinas relevantes. Veja abaixo as localizações dos arquivos de log relevantes. Em sistemas baseados em systemd, você pode precisar usar journalctl ao invés de examinar arquivos de log.

Nós da camada de gerenciamento

  • /var/log/kube-apiserver.log - Servidor de API, responsável por servir a API
  • /var/log/kube-scheduler.log - Agendador, responsável por tomar decisões de alocação
  • /var/log/kube-controller-manager.log - um componente que executa a maioria dos controladores embutidos do Kubernetes, com a notável exceção da alocação (o kube-scheduler lida com a alocação).

Nós de carga de trabalho

  • /var/log/kubelet.log - logs do kubelet, responsável por executar contêineres no nó
  • /var/log/kube-proxy.log - logs do kube-proxy, que é responsável por direcionar tráfego para endpoints de Service

Modos de falha do cluster

Esta é uma lista incompleta de coisas que podem dar errado e como ajustar a configuração do seu cluster para mitigar os problemas.

Causas contribuintes

  • Desligamento de VM(s)
  • Partição de rede dentro do cluster, ou entre cluster e usuários
  • Falhas no software do Kubernetes
  • Perda de dados ou indisponibilidade de armazenamento persistente (por exemplo, volume GCE PD ou AWS EBS)
  • Erro do operador, por exemplo, software do Kubernetes ou software de aplicação mal configurados

Cenários específicos

  • Desligamento de VM do servidor de API ou falha do servidor de API
    • Resultados
      • incapaz de parar, atualizar ou iniciar novos pods, services, replication controller
      • pods e services existentes devem continuar funcionando normalmente, a menos que dependam da API do Kubernetes
  • Armazenamento de apoio do servidor de API perdido
    • Resultados
      • o componente kube-apiserver falha ao iniciar com sucesso e se tornar íntegro
      • kubelets não conseguirão alcançá-lo, mas continuarão a executar os mesmos pods e fornecer o mesmo proxy de serviço
      • recuperação manual ou recriação do estado do servidor de API necessária antes que o servidor de API seja reiniciado
  • Desligamento ou falha de VM dos serviços de apoio (controlador de nó, gerenciador de replication controller, agendador, etc)
    • atualmente eles estão localizados junto com o servidor de API, e sua indisponibilidade tem consequências similares ao servidor de API
    • no futuro, estes serão replicados também e podem não estar localizados juntos
    • eles não têm seu próprio estado persistente
  • Nó individual (VM ou máquina física) desliga
    • Resultados
      • pods nesse nó param de executar
  • Partição de rede
    • Resultados
      • partição A pensa que os nós na partição B estão inativos; partição B pensa que o servidor de API está inativo. (Assumindo que a VM principal fique na partição A.)
  • Falha de software do Kubelet
    • Resultados
      • kubelet com falha não consegue iniciar novos pods no nó
      • kubelet pode deletar os pods ou não
      • nó marcado como não íntegro
      • replication controllers iniciam novos pods em outros lugares
  • Erro do operador do cluster
    • Resultados
      • perda de pods, services, etc
      • perda do armazenamento de apoio do servidor de API
      • usuários incapazes de ler a API
      • etc.

Mitigações

  • Ação: Use a funcionalidade de reinicialização automática de VM do provedor IaaS para VMs IaaS

    • Mitiga: Desligamento de VM do servidor de API ou falha do servidor de API
    • Mitiga: Desligamento de VM de serviços de apoio ou falhas
  • Ação: Use armazenamento confiável de provedores IaaS (por exemplo, GCE PD ou volume AWS EBS) para VMs com servidor de API + etcd

    • Mitiga: Armazenamento de apoio do servidor de API perdido
  • Ação: Use configuração de alta disponibilidade

    • Mitiga: Desligamento de nó da camada de gerenciamento ou falha de componentes da camada de gerenciamento (agendador, servidor de API, controller-manager)
      • Tolerará uma ou mais falhas simultâneas de nó ou componente
    • Mitiga: Armazenamento de apoio do servidor de API (ou seja, diretório de dados do etcd) perdido
      • Assume configuração de etcd HA (alta disponibilidade)
  • Ação: Fazer snapshot de PDs/volumes EBS do servidor de API periodicamente

    • Mitiga: Armazenamento de apoio do servidor de API perdido
    • Mitiga: Alguns casos de erro do operador
    • Mitiga: Alguns casos de falha de software do Kubernetes
  • Ação: usar replication controller e services na frente dos pods

    • Mitiga: Desligamento de nó
    • Mitiga: Falha de software do Kubelet
  • Ação: aplicações (contêineres) projetadas para tolerar reinicializações inesperadas

    • Mitiga: Desligamento de nó
    • Mitiga: Falha de software do Kubelet

Próximos passos

1 - Solução de Problemas no kubectl

Esta documentação é sobre investigar e diagnosticar problemas relacionados ao kubectl. Se você encontrar problemas ao acessar o kubectl ou ao conectar-se ao seu cluster, este documento descreve vários cenários comuns e possíveis soluções para ajudar a identificar e resolver a causa provável.

Antes de você começar

  • Você precisa ter um cluster Kubernetes.
  • Você também precisa ter o kubectl instalado - veja instale as ferramentas

Verificar a configuração do kubectl

Certifique-se de que você instalou e configurou o kubectl corretamente em sua máquina local. Verifique a versão do kubectl para garantir que esteja atualizada e compatível com seu cluster.

Verifique a versão do kubectl:

kubectl version

Você verá uma saída similar:

Client Version: version.Info{Major:"1", Minor:"27", GitVersion:"v1.27.4",GitCommit:"fa3d7990104d7c1f16943a67f11b154b71f6a132", GitTreeState:"clean",BuildDate:"2023-07-19T12:20:54Z", GoVersion:"go1.20.6", Compiler:"gc", Platform:"linux/amd64"}
Kustomize Version: v5.0.1
Server Version: version.Info{Major:"1", Minor:"27", GitVersion:"v1.27.3",GitCommit:"25b4e43193bcda6c7328a6d147b1fb73a33f1598", GitTreeState:"clean",BuildDate:"2023-06-14T09:47:40Z", GoVersion:"go1.20.5", Compiler:"gc", Platform:"linux/amd64"}

Se você vir Unable to connect to the server: dial tcp <server-ip>:8443: i/o timeout, ao invés de Server Version, você precisa solucionar problemas de conectividade do kubectl com seu cluster.

Certifique-se de que você instalou o kubectl seguindo a documentação oficial para instalar o kubectl, e que você configurou adequadamente a variável de ambiente $PATH.

Verificar kubeconfig

O kubectl requer um arquivo kubeconfig para conectar-se a um cluster Kubernetes. O arquivo kubeconfig geralmente está localizado no diretório ~/.kube/config. Certifique-se de que você tem um arquivo kubeconfig válido. Se você não tiver um arquivo kubeconfig, você pode obtê-lo do seu administrador do Kubernetes, ou pode copiá-lo do diretório /etc/kubernetes/admin.conf da camada de gerenciamento do seu Kubernetes. Se você implantou seu cluster Kubernetes em uma plataforma de nuvem e perdeu seu arquivo kubeconfig, você pode recriá-lo usando as ferramentas do seu provedor de nuvem. Consulte a documentação do provedor de nuvem para recriar um arquivo kubeconfig.

Verifique se a variável de ambiente $KUBECONFIG está configurada corretamente. Você pode definir a variável de ambiente $KUBECONFIG ou usar o parâmetro --kubeconfig com o kubectl para especificar o diretório de um arquivo kubeconfig.

Verificar conectividade VPN

Se você está usando uma Rede Privada Virtual (VPN) para acessar seu cluster Kubernetes, certifique-se de que sua conexão VPN está ativa e estável. Às vezes, desconexões da VPN podem levar a problemas de conexão com o cluster. Reconecte-se à VPN e tente acessar o cluster novamente.

Autenticação e autorização

Se você está usando autenticação baseada em token e o kubectl está retornando um erro relacionado ao token de autenticação ou endereço do servidor de autenticação, valide se o token de autenticação do Kubernetes e o endereço do servidor de autenticação estão configurados adequadamente.

Se o kubectl está retornando um erro relacionado à autorização, certifique-se de que você está usando as credenciais de usuário válidas. E que você tem a permissão para acessar o recurso que você solicitou.

Verificar contextos

O Kubernetes suporta múltiplos clusters e contextos. Certifique-se de que você está usando o contexto correto para interagir com seu cluster.

Listar contextos disponíveis:

kubectl config get-contexts

Alternar para o contexto apropriado:

kubectl config use-context <context-name>

Servidor de API e balanceador de carga

O servidor kube-apiserver é o componente central de um cluster Kubernetes. Se o servidor de API ou o balanceador de carga que executa na frente dos seus servidores de API não estiver acessível ou não estiver respondendo, você não conseguirá interagir com o cluster.

Verifique se o host do servidor de API está acessível usando o comando ping. Verifique a conectividade de rede e firewall do cluster. Se você estiver usando um provedor de nuvem para implantar o cluster, verifique o status de verificação de saúde do seu provedor de nuvem para o servidor de API do cluster.

Verifique o status do balanceador de carga (se usado) para garantir que esteja íntegro e encaminhando tráfego para o servidor de API.

Problemas de TLS

  • Ferramentas adicionais necessárias - base64 e openssl versão 3.0 ou superior.

O servidor de API do Kubernetes serve apenas requisições HTTPS por padrão. Nesse caso, problemas de TLS podem ocorrer por várias razões, como expiração de certificado ou validade da cadeia de confiança.

Você pode encontrar o certificado TLS no arquivo kubeconfig, localizado no diretório ~/.kube/config. O atributo certificate-authority contém o certificado CA e o atributo client-certificate contém o certificado do cliente.

Verificar a expiração destes certificados:

kubectl config view --flatten --output 'jsonpath={.clusters[0].cluster.certificate-authority-data}' | base64 -d | openssl x509 -noout -dates

saída:

notBefore=Feb 13 05:57:47 2024 GMT
notAfter=Feb 10 06:02:47 2034 GMT
kubectl config view --flatten --output 'jsonpath={.users[0].user.client-certificate-data}'| base64 -d | openssl x509 -noout -dates

saída:

notBefore=Feb 13 05:57:47 2024 GMT
notAfter=Feb 12 06:02:50 2025 GMT

Verificar ferramentas auxiliares do kubectl

Algumas ferramentas auxiliares de autenticação do kubectl fornecem acesso fácil aos clusters Kubernetes. Se você usou tais ferramentas auxiliares e está enfrentando problemas de conectividade, certifique-se de que as configurações necessárias ainda estão presentes.

Verificar configuração do kubectl para detalhes de autenticação:

kubectl config view

Se você usou anteriormente uma ferramenta auxiliar (por exemplo, kubectl-oidc-login), certifique-se de que ela ainda esteja instalada e configurada corretamente.

2 - Ferramentas para Monitorar Recursos

Para escalonar uma aplicação e fornecer um serviço confiável, você precisa entender como a aplicação se comporta quando é implantada. Você pode examinar o desempenho da aplicação em um cluster Kubernetes examinando os contêineres, pods, services, e as características do cluster geral. O Kubernetes fornece informações detalhadas sobre o uso de recursos de uma aplicação em cada um desses níveis. Essas informações permitem que você avalie o desempenho da sua aplicação e onde os gargalos podem ser removidos para melhorar o desempenho geral.

No Kubernetes, o monitoramento de aplicações não depende de uma única solução de monitoramento. Em clusters novos, você pode usar pipelines de métricas de recursos ou métricas completas para coletar estatísticas de monitoramento.

Pipeline de métricas de recursos

O pipeline de métricas de recursos fornece um conjunto limitado de métricas relacionadas aos componentes do cluster, como o controlador Horizontal Pod Autoscaler, bem como o utilitário kubectl top. Essas métricas são coletadas pelo metrics-server leve, de curto prazo e em memória, e são expostas via API metrics.k8s.io.

O metrics-server descobre todos os nós no cluster e consulta o kubelet de cada nó para uso de CPU e memória. O kubelet atua como uma ponte entre a camada de gerenciamento do Kubernetes e os nós de carga de trabalho, gerenciando os pods e contêineres executando em uma máquina. O kubelet traduz cada pod em seus contêineres integrantes e busca estatísticas de uso de contêineres individuais do agente de execução de contêiner através da interface do agente de execução de contêiner. Se você usa um agente de execução de contêiner que utiliza cgroups e namespaces do Linux para implementar contêineres, e o agente de execução de contêiner não publica estatísticas de uso, então o kubelet pode consultar essas estatísticas diretamente (usando código do cAdvisor). Não importa como essas estatísticas chegam, o kubelet então expõe as estatísticas agregadas de uso de recursos do pod através da API de Métricas de Recursos do metrics-server. Esta API é servida em /metrics/resource/v1beta1 nas portas autenticadas e somente leitura do kubelet.

Pipeline de métricas completas

Um pipeline de métricas completas oferece acesso a métricas mais ricas. O Kubernetes pode responder a essas métricas automaticamente escalonando ou adaptando o cluster baseado no seu estado atual, usando mecanismos como o Horizontal Pod Autoscaler. O pipeline de monitoramento busca métricas do kubelet e então as expõe ao Kubernetes através de um adaptador que implemente a API custom.metrics.k8s.io ou external.metrics.k8s.io.

O Kubernetes é projetado para funcionar com OpenMetrics, que é um dos Projetos de Monitoramento CNCF de Observabilidade e Análise, construído sobre e estendendo cuidadosamente o formato de exposição do Prometheus de maneiras quase 100% retrocompatíveis.

Se você der uma olhada no CNCF Landscape, você pode ver vários projetos de monitoramento que podem funcionar com o Kubernetes coletando dados de métricas e usando isso para ajudá-lo a observar seu cluster. Cabe a você selecionar a ferramenta ou ferramentas que atendam às suas necessidades. O landscape da CNCF para observabilidade e análise inclui uma mistura de software de código aberto, software-como-serviço pago e outros produtos comerciais.

Quando você projeta e implementa um pipeline de métricas completas, você pode tornar esses dados de monitoramento disponíveis de volta ao Kubernetes. Por exemplo, um HorizontalPodAutoscaler pode usar as métricas processadas para determinar quantos Pods executar para um componente da sua carga de trabalho.

A integração de um pipeline de métricas completas na sua implementação do Kubernetes está fora do escopo da documentação do Kubernetes devido ao escopo muito amplo de possíveis soluções.

A escolha da plataforma de monitoramento depende fortemente das suas necessidades, orçamento e recursos técnicos. O Kubernetes não recomenda nenhum pipeline de métricas específico; muitas opções estão disponíveis. Seu sistema de monitoramento deve ser capaz de lidar com o padrão de transmissão de métricas OpenMetrics e precisa ser escolhido para se adequar melhor ao design geral e implantação da sua plataforma de infraestrutura.

Próximos passos

Aprenda sobre ferramentas adicionais de depuração, incluindo:

3 - Pipeline de métricas de recursos

Para o Kubernetes, a API de Métricas oferece um conjunto básico de métricas para dar suporte ao escalonamento automático e casos de uso similares. Esta API disponibiliza informações sobre o uso de recursos para nó e pod, incluindo métricas para CPU e memória. Se você implantar a API de Métricas em seu cluster, os clientes da API do Kubernetes podem então consultar essas informações, e você pode usar os mecanismos de controle de acesso do Kubernetes para gerenciar permissões ao fazê-lo.

O HorizontalPodAutoscaler (HPA) e o VerticalPodAutoscaler (VPA) usam dados da API de métricas para ajustar réplicas e recursos de cargas de trabalho para atender à demanda do cliente.

Você também pode visualizar as métricas de recursos usando o comando kubectl top.

A Figura 1 ilustra a arquitetura do pipeline de métricas de recursos.

flowchart RL subgraph cluster[Cluster] direction RL S[

] A[Metrics-
Server] subgraph B[Nós] direction TB D[cAdvisor] --> C[kubelet] E[Agente de execução
do contêiner] --> D E1[Agente de execução
do contêiner] --> D P[dados do pod] -.- C end L[Servidor
de API] W[HPA] C ---->|métricas de recursos
no nível do nó| A -->|API de
métricas| L --> W end L ---> K[kubectl
top] classDef box fill:#fff,stroke:#000,stroke-width:1px,color:#000; class W,B,P,K,cluster,D,E,E1 box classDef spacewhite fill:#ffffff,stroke:#fff,stroke-width:0px,color:#000 class S spacewhite classDef k8s fill:#326ce5,stroke:#fff,stroke-width:1px,color:#fff; class A,L,C k8s

Figura 1. Pipeline de Métricas de Recursos

Os componentes da arquitetura, da direita para a esquerda na figura, consistem no seguinte:

  • cAdvisor: Daemon para coletar, agregar e expor métricas de contêiner incluído no Kubelet.

  • kubelet: Agente do nó para gerenciar recursos de contêiner. As métricas de recursos são acessíveis usando os endpoints da API do kubelet /metrics/resource e /stats.

  • métricas de recursos no nível do nó: API fornecida pelo kubelet para descobrir e recuperar estatísticas resumidas por nó disponíveis através do endpoint /metrics/resource.

  • metrics-server: Componente complemento do cluster que coleta e agrega métricas de recursos extraídas de cada kubelet. O servidor de API serve a API de Métricas para uso pelo HPA, VPA e pelo comando kubectl top. O Metrics Server é uma implementação de referência da API de Métricas.

  • API de Métricas: API do Kubernetes que oferece suporte ao acesso à CPU e memória usadas para escalonamento automático de cargas de trabalho. Para fazer isso funcionar em seu cluster, você precisa de um servidor de extensão de API que forneça a API de Métricas.

API de Métricas

ESTADO DA FUNCIONALIDADE: Kubernetes 1.8 [beta]

O metrics-server implementa a API de Métricas. Esta API permite que você acesse o uso de CPU e memória para os nós e pods em seu cluster. Seu papel principal é fornecer métricas de uso de recursos para os componentes de escalonamento automático do K8s.

Aqui está um exemplo da solicitação da API de Métricas para um nó minikube direcionada através do jq para facilitar a leitura:

kubectl get --raw "/apis/metrics.k8s.io/v1beta1/nodes/minikube" | jq '.'

Aqui está a mesma chamada para a API usando curl:

curl http://localhost:8080/apis/metrics.k8s.io/v1beta1/nodes/minikube

Resposta de exemplo:

{
  "kind": "NodeMetrics",
  "apiVersion": "metrics.k8s.io/v1beta1",
  "metadata": {
    "name": "minikube",
    "selfLink": "/apis/metrics.k8s.io/v1beta1/nodes/minikube",
    "creationTimestamp": "2022-01-27T18:48:43Z"
  },
  "timestamp": "2022-01-27T18:48:33Z",
  "window": "30s",
  "usage": {
    "cpu": "487558164n",
    "memory": "732212Ki"
  }
}

Aqui está um exemplo da solicitação da API de Métricas para um pod kube-scheduler-minikube contido no namespace kube-system e direcionada através do jq para facilitar a leitura:

kubectl get --raw "/apis/metrics.k8s.io/v1beta1/namespaces/kube-system/pods/kube-scheduler-minikube" | jq '.'

Aqui está a mesma chamada para a API usando curl:

curl http://localhost:8080/apis/metrics.k8s.io/v1beta1/namespaces/kube-system/pods/kube-scheduler-minikube

Resposta de exemplo:

{
  "kind": "PodMetrics",
  "apiVersion": "metrics.k8s.io/v1beta1",
  "metadata": {
    "name": "kube-scheduler-minikube",
    "namespace": "kube-system",
    "selfLink": "/apis/metrics.k8s.io/v1beta1/namespaces/kube-system/pods/kube-scheduler-minikube",
    "creationTimestamp": "2022-01-27T19:25:00Z"
  },
  "timestamp": "2022-01-27T19:24:31Z",
  "window": "30s",
  "containers": [
    {
      "name": "kube-scheduler",
      "usage": {
        "cpu": "9559630n",
        "memory": "22244Ki"
      }
    }
  ]
}

A API de Métricas é definida no repositório k8s.io/metrics. Você deve habilitar a camada de agregação de API e registrar um APIService para a API metrics.k8s.io.

Para saber mais sobre a API de Métricas, consulte o design da API de métricas de recursos, o repositório do metrics-server e a API de métricas de recursos.

Medindo o uso de recursos

CPU

A CPU é reportada como o uso médio do núcleo medido em unidades de cpu. Uma cpu, no Kubernetes, é equivalente a 1 vCPU/Núcleo para provedores de nuvem, e 1 hyper-thread em processadores Intel de servidor dedicado.

Este valor é derivado obtendo uma taxa sobre um contador cumulativo de CPU fornecido pelo kernel (em kernels Linux e Windows). A janela de tempo usada para calcular a CPU é mostrada no campo window na API de Métricas.

Para saber mais sobre como o Kubernetes aloca e mede recursos de CPU, consulte significado da CPU.

Memória

A memória é reportada como o conjunto de trabalho, medido em bytes, no instante em que a métrica foi coletada.

Em um mundo ideal, o "conjunto de trabalho" é a quantidade de memória em uso que não pode ser liberada sob pressão de memória. No entanto, o cálculo do conjunto de trabalho varia por sistema operacional do host, e geralmente faz uso pesado de heurísticas para produzir uma estimativa.

O modelo do Kubernetes para o conjunto de trabalho de um contêiner espera que o agente de execução do contêiner conte a memória anônima associada ao contêiner em questão. A métrica do conjunto de trabalho também inclui tipicamente alguma memória em cache (baseada em arquivo), porque o sistema operacional do host nem sempre pode recuperar páginas.

Para saber mais sobre como o Kubernetes aloca e mede recursos de memória, consulte significado da memória.

Metrics Server

O metrics-server obtém métricas de recursos dos kubelets e as expõe no servidor de API do Kubernetes através da API de Métricas para uso pelo HPA e VPA. Você também pode visualizar essas métricas usando o comando kubectl top.

O metrics-server usa a API do Kubernetes para rastrear nós e pods em seu cluster. O metrics-server consulta cada nó via HTTP para obter métricas. O metrics-server também constrói uma visão interna dos metadados do pod e mantém um cache da integridade do pod. Essa informação de integridade do pod em cache está disponível através da API de extensão que o metrics-server disponibiliza.

Por exemplo, com uma consulta HPA, o metrics-server precisa identificar quais pods atendem aos seletores de rótulos na implantação.

O metrics-server chama a API do kubelet para coletar métricas de cada nó. Dependendo da versão do metrics-server ele usa:

  • Endpoint de recurso de métricas /metrics/resource na versão v0.6.0+ ou
  • Endpoint da API de resumo /stats/summary em versões mais antigas

Próximos passos

Para saber mais sobre o metrics-server, consulte o repositório do metrics-server.

Você também pode consultar o seguinte:

Para saber sobre como o kubelet serve métricas do nó e como você pode acessá-las através da API do Kubernetes, leia Dados de Métricas do Nó.