Como acessar os recursos do pod do Kubernetes

Como acessar os recursos do pod do KubernetesA recompensa por Tohad

Ao começar a usar o Kubernetes, é comum esquecer a configuração dos recursos do contêiner. Neste ponto, basta garantir que a imagem Docker funcione e possa ser implantada no cluster Kubernetes.

Mais tarde, porém, o aplicativo precisará ser implantado em um cluster de produção junto com outros aplicativos. Para fazer isso, você precisa alocar recursos para o contêiner e certificar-se de que haja recursos suficientes para colocar o aplicativo em funcionamento e que outros aplicativos em execução não terão problemas.

Equipe Kubernetes aaS de Mail.ru traduziu um artigo sobre recursos de contêiner (CPU e MEM), solicitações e limitações de recursos. Você aprenderá os benefícios dessas configurações e o que acontece se não defini-las.

Recursos de computação

Temos dois tipos de recursos com as seguintes unidades:

  • Unidade central de processamento (CPU) - núcleos;
  • Memória (MEM) - bytes.

Os recursos são especificados para cada contêiner. No seguinte arquivo Pod YAML, você verá uma seção de recursos que contém os recursos solicitados e limitados:

  • Recursos de pod solicitados = soma dos recursos solicitados de todos os contêineres;
  • Limite de recursos do pod = soma de todos os limites de recursos do pod.

apiVersion: v1
kind: Pod
metadata:
  name: backend-pod-name
  labels:
    application: backend
spec:
  containers:
    — name: main-container
      image: my-backend
      tag: v1
      ports:
      — containerPort: 8080
      resources:
        requests:
          cpu: 0.2 # REQUESTED CPU: 200m cores
          memory: "1Gi" # REQUESTED MEM: 1Gi
        limits:
          cpu: 1 # MAX CPU USAGE: 1 core
          memory: "1Gi" # MAX MEM USAGE:  1Gi
    — name: other-container
      image: other-app
      tag: v1
      ports:
      — containerPort: 8000
      resources:
        requests:
          cpu: "200m" # REQUESTED CPU: 200m cores
          memory: "0.5Gi" # REQUESTED MEM: 0.5Gi
        limits:
          cpu: 1 # MAX CPU USAGE: 1 core
          memory: "1Gi" # MAX MEM USAGE:  1Gi

Exemplo de recursos solicitados e limitados

Campo resources.requested da especificação Pod é um dos elementos usados ​​para encontrar o nó desejado. Você já pode planejar a implantação do pod para ele. Como você encontra um nó adequado?

O Kubernetes consiste em vários componentes, incluindo um nó mestre ou nó mestre (Plano de Controle do Kubernetes). O nó mestre possui vários processos: kube-apiserver, kube-controller-manager e kube-scheduler.

O processo kube-scheduler é responsável por revisar os pods recém-criados e encontrar possíveis nós de trabalho que correspondam a todas as solicitações de pod, incluindo o número de recursos solicitados. A lista de nós encontrados pelo kube-scheduler é classificada. O pod é agendado no nó com as pontuações mais altas.

Como acessar os recursos do pod do KubernetesOnde o Pod roxo será colocado?

Na imagem você pode ver que o kube-scheduler deve agendar um novo pod roxo. O cluster Kubernetes contém dois nós: A e B. Como você pode ver, o kube-scheduler não pode agendar um pod no nó A - os recursos disponíveis (não solicitados) não correspondem às solicitações do pod roxo. Portanto, o 1 GB de memória solicitado pelo Pod roxo não caberá no nó A, pois a memória disponível é de 0,5 GB. Mas o nó B possui recursos suficientes. Como resultado, o kube-scheduler decide que o destino do pod roxo é o nó B.

Agora sabemos como os recursos solicitados afetam a escolha do nó para executar o Pod. Mas qual é o impacto dos recursos marginais?

O limite de recursos é um limite que a CPU/MEM não pode ultrapassar. No entanto, o recurso da CPU é flexível, portanto, os contêineres que atingirem os limites da CPU não causarão a saída do pod. Em vez disso, a aceleração da CPU será iniciada. Se o limite de uso do MEM for atingido, o contêiner será interrompido devido ao OOM-Killer e reiniciado se permitido pela configuração RestartPolicy.

Recursos solicitados e máximos em detalhes

Como acessar os recursos do pod do KubernetesComunicação de recursos entre Docker e Kubernetes

A melhor maneira de explicar como funcionam as solicitações e limites de recursos é apresentar o relacionamento entre Kubernetes e Docker. Na imagem acima você pode ver como os campos do Kubernetes e os sinalizadores de inicialização do Docker estão relacionados.

Memória: solicitação e limitação

containers:
...
 resources:
   requests:
     memory: "0.5Gi"
   limits:
     memory: "1Gi"

Conforme mencionado acima, a memória é medida em bytes. Baseado em Documentação do Kubernetes, podemos especificar a memória como um número. Geralmente é um número inteiro, por exemplo 2678 - ou seja, 2678 bytes. Você também pode usar sufixos G и Gi, o principal é lembrar que não são equivalentes. O primeiro é decimal e o segundo é binário. Como o exemplo mencionado na documentação do k8s: 128974848, 129e6, 129M, 123Mi - são praticamente equivalentes.

Opção Kubernetes limits.memory corresponde à bandeira --memory do Docker. No caso de request.memory Não há seta para o Docker porque o Docker não usa este campo. Você pode perguntar: isso é mesmo necessário? Sim, preciso. Como eu disse antes, o campo é importante para o Kubernetes. Com base nas informações dele, o kube-scheduler decide em qual nó agendar o pod.

O que acontece se você definir memória insuficiente para uma solicitação?

Se o contêiner atingiu os limites da memória solicitada, o Pod é colocado em um grupo de Pods que para quando não há memória suficiente no nó.

O que acontece se você definir o limite de memória muito baixo?

Se o contêiner exceder o limite de memória, ele será encerrado devido ao OOM-Killed. E reiniciará, se possível, com base em RestartPolicy, onde o valor padrão é Always.

O que acontece se você não especificar a memória solicitada?

O Kubernetes pegará o valor limite e o definirá como valor padrão.

O que pode acontecer se você não especificar um limite de memória?

O contêiner não tem restrições; ele pode usar tanta memória quanto quiser. Se ele começar a usar toda a memória disponível do nó, o OOM irá matá-lo. O contêiner será então reiniciado, se possível, com base em RestartPolicy.

O que acontece se você não especificar limites de memória?

Este é o pior cenário: o escalonador não sabe quantos recursos o contêiner necessita e isso pode causar sérios problemas no nó. Nesse caso, seria bom ter limites padrão no namespace (definidos por LimitRange). Não há limites padrão – o Pod não tem limites, ele pode usar tanta memória quanto quiser.

Se a memória solicitada for maior do que o nó pode oferecer, o Pod não será agendado. É importante lembrar que Requests.memory - não é o valor mínimo. Esta é uma descrição da quantidade de memória suficiente para manter o contêiner funcionando continuamente.

Geralmente é recomendado definir o mesmo valor para request.memory и limit.memory. Isso garante que o Kubernetes não agendará um pod em um nó que tenha memória suficiente para executá-lo, mas não o suficiente para executá-lo. Lembre-se: o planejamento do pod do Kubernetes leva em consideração apenas requests.memoryE limits.memory não leva em conta.

CPU: solicitação e limite

containers:
...
 resources:
   requests:
     cpu: 1
   limits:
     cpu: "1200m"

Com uma CPU tudo é um pouco mais complicado. Voltando à imagem do relacionamento entre Kubernetes e Docker, você pode ver que request.cpu соответствует --cpu-sharesEnquanto que limit.cpu corresponde à bandeira cpus no Docker.

A CPU solicitada pelo Kubernetes é multiplicada por 1024, a proporção de ciclos de CPU. Se você quiser solicitar 1 núcleo completo, você deve adicionar cpu: 1como mostrado acima.

Solicitar um kernel completo (proporção = 1024) não significa que seu contêiner o receberá. Se sua máquina host tiver apenas um núcleo e você estiver executando mais de um contêiner, todos os contêineres deverão compartilhar a CPU disponível entre eles. Como isso acontece? Vejamos a foto.

Como acessar os recursos do pod do Kubernetes
Solicitação de CPU - Sistema de núcleo único

Vamos imaginar que você tenha um sistema host de núcleo único executando contêineres. Mamãe (Kubernetes) fez uma torta (CPU) e quer dividi-la entre os filhos (contêineres). Três crianças querem uma torta inteira (proporção = 1024), outra criança quer meia torta (512). Mamãe quer ser justa e faz um cálculo simples.

# Сколько пирогов хотят дети?
# 3 ребенка хотят по целому пирогу и еще один хочет половину пирога
cakesNumberKidsWant = (3 * 1) + (1 * 0.5) = 3.5
# Выражение получается так:
3 (ребенка/контейнера) * 1 (целый пирог/полное ядро) + 1 (ребенок/контейнер) * 0.5 (половина пирога/половина ядра)
# Сколько пирогов испечено?
availableCakesNumber = 1
# Сколько пирога (максимально) дети реально могут получить?
newMaxRequest = 1 / 3.5 =~ 28%

Com base no cálculo, três crianças receberão 28% da mensalidade, e não a integralidade. O quarto filho receberá 14% do grão inteiro, não metade. Mas as coisas serão diferentes se você tiver um sistema multinúcleo.

Como acessar os recursos do pod do Kubernetes
Solicitação de CPU - Sistema Multi-Core (4)

Na imagem acima você pode ver que três crianças querem uma torta inteira e uma quer a metade. Como a mãe fez quatro tortas, cada filho receberá quantas quiser. Em um sistema multinúcleo, os recursos do processador são distribuídos por todos os núcleos de processador disponíveis. Se um contêiner estiver limitado a menos de um núcleo de CPU completo, ele ainda poderá usá-lo em 100%.

Os cálculos acima são simplificados para entender como a CPU é distribuída entre os contêineres. É claro que, além dos próprios contêineres, existem outros processos que também utilizam recursos da CPU. Quando os processos em um contêiner estão ociosos, outros podem usar seus recursos. CPU: "200m" соответствует CPU: 0,2, o que significa aproximadamente 20% de um núcleo.

Agora vamos falar sobre limit.cpu. A CPU que o Kubernetes limita é multiplicada por 100. O resultado é a quantidade de tempo que o contêiner pode usar a cada 100 µs (cpu-period).

limit.cpu corresponde à bandeira do Docker --cpus. Esta é uma nova combinação do antigo --cpu-period и --cpu-quota. Ao defini-lo, indicamos quantos recursos de CPU disponíveis o contêiner pode usar ao máximo antes do início da limitação:

  • CPU - combinação cpu-period и cpu-quota. cpus = 1.5 equivalente à configuração cpu-period = 100000 и cpu-quota = 150000;
  • Período de CPU - período Agendador CFS da CPU, padrão 100 microssegundos;
  • cota CPU - número de microssegundos dentro cpu-period, que é delimitado pelo contêiner.

O que acontece se você instalar CPU solicitada insuficiente?

Se o contêiner precisar de mais do que foi instalado, ele roubará CPU de outros processos.

O que acontece se você definir o limite da CPU muito baixo?

Como o recurso da CPU é ajustável, a aceleração será ativada.

O que acontece se você não especificar uma solicitação de CPU?

Tal como acontece com a memória, o valor da solicitação é igual ao limite.

O que acontece se você não especificar um limite de CPU?

O contêiner usará a quantidade de CPU necessária. Se uma política de CPU padrão (LimitRange) for definida no namespace, esse limite também será usado para o contêiner.

O que acontece se você não especificar uma solicitação ou um limite de CPU?

Tal como acontece com a memória, este é o pior cenário. O agendador não sabe quantos recursos seu contêiner precisa e isso pode causar sérios problemas no nó. Para evitar isso, você precisa definir limites padrão para namespaces (LimitRange).

Lembre-se: se você solicitar mais CPU do que os nós podem fornecer, o Pod não será agendado. Requests.cpu - não o valor mínimo, mas um valor suficiente para iniciar o Pod e funcionar sem falhas. Caso o aplicativo não realize cálculos complexos, a melhor opção é instalar request.cpu <= 1 e lance quantas réplicas forem necessárias.

Quantidade ideal de recursos solicitados ou limite de recursos

Aprendemos sobre a limitação dos recursos computacionais. Agora é hora de responder à pergunta: “Quantos recursos meu Pod necessita para executar o aplicativo sem problemas? Qual é a quantidade ideal?

Infelizmente, não há respostas claras para essas perguntas. Se você não sabe como seu aplicativo funciona ou quanta CPU ou memória ele precisa, a melhor opção é fornecer ao aplicativo muita memória e CPU e depois executar testes de desempenho.

Além dos testes de desempenho, monitore o comportamento da aplicação no monitoramento por uma semana. Se os gráficos indicarem que seu aplicativo está consumindo menos recursos do que você solicitou, você poderá reduzir a quantidade de CPU ou memória solicitada.

Como exemplo veja isto Painel Grafana. Ele exibe a diferença entre os recursos solicitados ou o limite de recursos e o uso atual dos recursos.

Conclusão

Solicitar e limitar recursos ajuda a manter seu cluster Kubernetes íntegro. A configuração adequada dos limites minimiza custos e mantém os aplicativos em execução o tempo todo.

Resumindo, há algumas coisas a ter em mente:

  1. Os recursos solicitados são uma configuração levada em consideração no momento da inicialização (quando o Kubernetes planeja hospedar o aplicativo). Por outro lado, limitar recursos é importante em tempo de execução – quando o aplicativo já está em execução no nó.
  2. Comparada à memória, a CPU é um recurso regulamentado. Se não houver CPU suficiente, seu pod não será desligado e o mecanismo de aceleração será ativado.
  3. Os recursos solicitados e o limite de recursos não são valores mínimos e máximos! Ao definir os recursos solicitados, você garante que a aplicação funcionará sem problemas.
  4. Uma boa prática é definir a solicitação de memória igual ao limite de memória.
  5. Ok, instalação solicitada CPU <=1, se o aplicativo não realizar cálculos complexos.
  6. Se você solicitar mais recursos do que os disponíveis em um nó, o pod nunca será programado para esse nó.
  7. Para determinar a quantidade correta de recursos/limites de recursos solicitados, use testes de carga e monitoramento.

Espero que este artigo ajude você a compreender o conceito básico de limitação de recursos. E você poderá aplicar esse conhecimento em seu trabalho.

Boa sorte!

O que mais ler:

  1. Observabilidade SRE: Namespaces e Estrutura Métrica.
  2. Mais de 90 ferramentas úteis para Kubernetes: implantação, gerenciamento, monitoramento, segurança e muito mais.
  3. Nosso canal em torno do Kubernetes no Telegram.

Fonte: habr.com

Adicionar um comentário