Geralmente, há sempre a necessidade de fornecer um pool dedicado de recursos a algum aplicativo para seu funcionamento correto e estável. Mas e se vários aplicativos estiverem rodando nas mesmas capacidades? Como garantir o mínimo de recursos necessários para cada um deles? De que forma é possível limitar o consumo de recursos? Como distribuir a carga entre os nós de maneira eficiente? Como garantir o funcionamento do mecanismo de escalabilidade horizontal em caso de aumento da carga sobre os aplicativos?

Devemos começar pelo entendimento dos principais tipos de recursos que existem no sistema — que são, claro, o tempo de CPU e a memória RAM. Nos manifestos do k8s, esses tipos de recursos são medidos nas seguintes unidades:
- CPU — em núcleos
- RAM — em bytes
Além disso, para cada recurso, há a possibilidade de definir dois tipos de requisitos — requests e limits. Requests — descreve os requisitos mínimos em relação aos recursos livres do nó para executar o contêiner (e o pod como um todo), enquanto limits estabelece uma restrição rígida aos recursos disponíveis para o contêiner.
É importante entender que no manifesto não é necessário definir explicitamente ambos os tipos, e o comportamento será o seguinte:
- Se apenas limits do recurso for definido explicitamente, então requests para esse recurso automaticamente assume o valor igual a limits (o que pode ser verificado ao invocar describe da entidade). Ou seja, na prática, o funcionamento do contêiner será limitado à mesma quantidade de recursos que ele requer para sua execução.
- Se para o recurso apenas requests for definido explicitamente, então não há limitações superiores para esse recurso — ou seja, o contêiner é limitado apenas pelos recursos do próprio nó.
Também existe a possibilidade de configurar a gestão de recursos não apenas no nível de um contêiner específico, mas também no nível de namespace por meio das seguintes entidades:
- LimitRange — descreve a política de limitação ao nível do contêiner/pod no namespace e é necessária para descrever as limitações padrão para contêiner/pod, bem como para prevenir a criação de contêineres/pods excessivamente grandes (ou vice-versa), limitar sua quantidade e determinar a possível diferença entre os valores de limits e requests.
- ResourceQuotas — descrevem a política de cota em geral para todos os contêineres no ns e é utilizada, geralmente, para delimitar recursos entre os ambientes (útil quando os ambientes não são rigidamente separados ao nível dos nós)
Abaixo estão exemplos de manifests onde são estabelecidas limitações de recursos:
Ao nível de um contêiner específico:
containers: - name: app-nginx image: nginx resources: requests: memory: 1Gi limits: cpu: 200mOu seja, neste caso, para iniciar um contêiner com nginx, será necessário pelo menos 1G de RAM livre e 0.2 CPU no nó, enquanto o máximo que o contêiner pode consumir é 0.2 CPU e toda a RAM disponível no nó.
Ao nível de todo o ns:
apiVersion: v1 kind: ResourceQuota metadata: name: nxs-test spec: hard: requests.cpu: 300m requests.memory: 1Gi limits.cpu: 700m limits.memory: 2GiOu seja, a soma de todos os requests dos contêineres no ns padrão não pode ultrapassar 300m para CPU e 1G para RAM, enquanto a soma de todos os limits é de 700m para CPU e 2G para RAM.
Limitações padrão para contêineres no ns:
apiVersion: v1 kind: LimitRange metadata: name: nxs-limit-per-container spec: limits: - type: Container defaultRequest: cpu: 100m memory: 1Gi default: cpu: 1 memory: 2Gi min: cpu: 50m memory: 500Mi max: cpu: 2 memory: 4GiOu seja, no namespace padrão, todos os contêineres terão, por padrão, um request de 100m para CPU e 1G para RAM, e um limit de 1 CPU e 2G. Além disso, também foi estabelecido um limite nos possíveis valores para request/limit de CPU (50m < x < 2) e RAM (500M < x < 4G).
Limitações ao nível dos pods no ns:
apiVersion: v1 kind: LimitRange metadata: name: nxs-limit-pod spec: limits: - type: Pod max: cpu: 4 memory: 1GiOu seja, para cada pod no ns padrão, haverá uma limitação de 4 vCPU e 1G.
Agora, gostaria de falar sobre quais são as vantagens que a imposição dessas limitações pode nos trazer.
Mecanismo de balanceamento de carga entre os nós
Como é sabido, a distribuição de pods entre nós é feita por um componente do k8s chamado scheduler, que opera segundo um determinado algoritmo. Este algoritmo, ao escolher o nó ideal para executar, passa por duas etapas:
- Filtragem
- Ranqueamento
Ou seja, de acordo com a política descrita, inicialmente são selecionados os nós onde é possível executar o pod com base em um conjunto de predicates (incluindo a verificação se há recursos suficientes no nó para executar o pod — PodFitsResources), e em seguida, para cada um desses nós, de acordo com priorities são atribuídos pontos (isto é, quanto mais recursos livres houver no nó, mais pontos ele recebe — LeastResourceAllocation/LeastRequestedPriority/BalancedResourceAllocation) e é iniciado em um nó com o maior número de pontos (se vários nós satisfizerem essa condição, um deles é escolhido aleatoriamente).
É importante entender que o scheduler, ao avaliar os recursos disponíveis do nó, se orienta pelos dados armazenados no etcd — ou seja, pela soma dos recursos solicitados/limite de cada pod em execução nesse nó, mas não pelo consumo real de recursos. Essa informação pode ser obtida a partir da saída do comando kubectl describe node $NODE, por exemplo:
# kubectl describe nodes nxs-k8s-s1
..
Non-terminated Pods: (9 in total)
Namespace Name CPU Requests CPU Limits Memory Requests Memory Limits AGE
--------- ---- ------------ ---------- --------------- ------------- ---
ingress-nginx nginx-ingress-controller-754b85bf44-qkt2t 0 (0%) 0 (0%) 0 (0%) 0 (0%) 233d
kube-system kube-flannel-26bl4 150m (0%) 300m (1%) 64M (0%) 500M (1%) 233d
kube-system kube-proxy-exporter-cb629 0 (0%) 0 (0%) 0 (0%) 0 (0%) 233d
kube-system kube-proxy-x9fsc 0 (0%) 0 (0%) 0 (0%) 0 (0%) 233d
kube-system nginx-proxy-k8s-worker-s1 25m (0%) 300m (1%) 32M (0%) 512M (1%) 233d
nxs-monitoring alertmanager-main-1 100m (0%) 100m (0%) 425Mi (1%) 25Mi (0%) 233d
nxs-logging filebeat-lmsmp 100m (0%) 0 (0%) 100Mi (0%) 200Mi (0%) 233d
nxs-monitoring node-exporter-v4gdq 112m (0%) 122m (0%) 200Mi (0%) 220Mi (0%) 233d
Allocated resources:
(Total limits may be over 100 percent, i.e., overcommitted.)
Resource Requests Limits
-------- -------- ------
cpu 487m (3%) 822m (5%)
memory 15856217600 (2%) 749976320 (3%)
ephemeral-storage 0 (0%) 0 (0%)Aqui vemos todos os pods em execução em um nó específico, bem como os recursos solicitados por cada um deles. E aqui está como os logs do scheduler aparecem ao iniciar o pod cronjob-cron-events-1573793820-xt6q9 (essa informação nos logs do scheduler aparecerá ao configurar o nível 10 de log nos argumentos do comando de início —v=10):
log
I1115 07:57:21.637791 1 scheduling_queue.go:908] Prestes a tentar agendar o pod nxs-stage/cronjob-cron-events-1573793820-xt6q9
I1115 07:57:21.637804 1 scheduler.go:453] Tentando agendar o pod: nxs-stage/cronjob-cron-events-1573793820-xt6q9
I1115 07:57:21.638285 1 predicates.go:829] Agendar o pod nxs-stage/cronjob-cron-events-1573793820-xt6q9 no nó nxs-k8s-s5 é permitido, o nó está executando apenas 16 de 110 pods.
I1115 07:57:21.638300 1 predicates.go:829] Agendar o pod nxs-stage/cronjob-cron-events-1573793820-xt6q9 no nó nxs-k8s-s6 é permitido, o nó está executando apenas 20 de 110 pods.
I1115 07:57:21.638322 1 predicates.go:829] Agendar o pod nxs-stage/cronjob-cron-events-1573793820-xt6q9 no nó nxs-k8s-s3 é permitido, o nó está executando apenas 20 de 110 pods.
I1115 07:57:21.638322 1 predicates.go:829] Agendar o pod nxs-stage/cronjob-cron-events-1573793820-xt6q9 no nó nxs-k8s-s4 é permitido, o nó está executando apenas 17 de 110 pods.
I1115 07:57:21.638334 1 predicates.go:829] Agendar o pod nxs-stage/cronjob-cron-events-1573793820-xt6q9 no nó nxs-k8s-s10 é permitido, o nó está executando apenas 16 de 110 pods.
I1115 07:57:21.638365 1 predicates.go:829] Agendar o pod nxs-stage/cronjob-cron-events-1573793820-xt6q9 no nó nxs-k8s-s12 é permitido, o nó está executando apenas 9 de 110 pods.
I1115 07:57:21.638334 1 predicates.go:829] Agendar o pod nxs-stage/cronjob-cron-events-1573793820-xt6q9 no nó nxs-k8s-s11 é permitido, o nó está executando apenas 11 de 110 pods.
I1115 07:57:21.638385 1 predicates.go:829] Agendar o pod nxs-stage/cronjob-cron-events-1573793820-xt6q9 no nó nxs-k8s-s1 é permitido, o nó está executando apenas 19 de 110 pods.
I1115 07:57:21.638402 1 predicates.go:829] Agendar o pod nxs-stage/cronjob-cron-events-1573793820-xt6q9 no nó nxs-k8s-s2 é permitido, o nó está executando apenas 21 de 110 pods.
I1115 07:57:21.638383 1 predicates.go:829] Agendar o pod nxs-stage/cronjob-cron-events-1573793820-xt6q9 no nó nxs-k8s-s9 é permitido, o nó está executando apenas 16 de 110 pods.
I1115 07:57:21.638335 1 predicates.go:829] Agendar o pod nxs-stage/cronjob-cron-events-1573793820-xt6q9 no nó nxs-k8s-s8 é permitido, o nó está executando apenas 18 de 110 pods.
I1115 07:57:21.638408 1 predicates.go:829] Agendar o pod nxs-stage/cronjob-cron-events-1573793820-xt6q9 no nó nxs-k8s-s13 é permitido, o nó está executando apenas 8 de 110 pods.
I1115 07:57:21.638478 1 predicates.go:1369] Agendar o pod nxs-stage/cronjob-cron-events-1573793820-xt6q9 no nó nxs-k8s-s10 é permitido, termos de anti-afinação de pods existentes satisfatórios.
I1115 07:57:21.638505 1 predicates.go:1369] Agendar o pod nxs-stage/cronjob-cron-events-1573793820-xt6q9 no nó nxs-k8s-s8 é permitido, termos de anti-afinação de pods existentes satisfatórios.
I1115 07:57:21.638577 1 predicates.go:1369] Agendar o pod nxs-stage/cronjob-cron-events-1573793820-xt6q9 no nó nxs-k8s-s9 é permitido, termos de anti-afinação de pods existentes satisfatórios.
I1115 07:57:21.638583 1 predicates.go:829] Agendar o pod nxs-stage/cronjob-cron-events-1573793820-xt6q9 no nó nxs-k8s-s7 é permitido, o nó está executando apenas 25 de 110 pods.
I1115 07:57:21.638932 1 resource_allocation.go:78] cronjob-cron-events-1573793820-xt6q9 -> nxs-k8s-s10: BalancedResourceAllocation, capacidade 39900 milicore 66620178432 bytes de memória, total de solicitação 2343 milicore 9640186880 bytes de memória, pontuação 9
I1115 07:57:21.638946 1 resource_allocation.go:78] cronjob-cron-events-1573793820-xt6q9 -> nxs-k8s-s10: LeastResourceAllocation, capacidade 39900 milicore 66620178432 bytes de memória, total de solicitação 2343 milicore 9640186880 bytes de memória, pontuação 8
I1115 07:57:21.638961 1 resource_allocation.go:78] cronjob-cron-events-1573793820-xt6q9 -> nxs-k8s-s9: BalancedResourceAllocation, capacidade 39900 milicore 66620170240 bytes de memória, total de solicitação 4107 milicore 11307422720 bytes de memória, pontuação 9
I1115 07:57:21.638971 1 resource_allocation.go:78] cronjob-cron-events-1573793820-xt6q9 -> nxs-k8s-s8: BalancedResourceAllocation, capacidade 39900 milicore 66620178432 bytes de memória, total de solicitação 5847 milicore 24333637120 bytes de memória, pontuação 7
I1115 07:57:21.638975 1 resource_allocation.go:78] cronjob-cron-events-1573793820-xt6q9 -> nxs-k8s-s9: LeastResourceAllocation, capacidade 39900 milicore 66620170240 bytes de memória, total de solicitação 4107 milicore 11307422720 bytes de memória, pontuação 8
I1115 07:57:21.638990 1 resource_allocation.go:78] cronjob-cron-events-1573793820-xt6q9 -> nxs-k8s-s8: LeastResourceAllocation, capacidade 39900 milicore 66620178432 bytes de memória, total de solicitação 5847 milicore 24333637120 bytes de memória, pontuação 7
I1115 07:57:21.639022 1 generic_scheduler.go:726] cronjob-cron-events-1573793820-xt6q9_nxs-stage -> nxs-k8s-s10: TaintTolerationPriority, Pontuação: (10)
I1115 07:57:21.639030 1 generic_scheduler.go:726] cronjob-cron-events-1573793820-xt6q9_nxs-stage -> nxs-k8s-s8: TaintTolerationPriority, Pontuação: (10)
I1115 07:57:21.639034 1 generic_scheduler.go:726] cronjob-cron-events-1573793820-xt6q9_nxs-stage -> nxs-k8s-s9: TaintTolerationPriority, Pontuação: (10)
I1115 07:57:21.639041 1 generic_scheduler.go:726] cronjob-cron-events-1573793820-xt6q9_nxs-stage -> nxs-k8s-s10: NodeAffinityPriority, Pontuação: (0)
I1115 07:57:21.639053 1 generic_scheduler.go:726] cronjob-cron-events-1573793820-xt6q9_nxs-stage -> nxs-k8s-s8: NodeAffinityPriority, Pontuação: (0)
I1115 07:57:21.639059 1 generic_scheduler.go:726] cronjob-cron-events-1573793820-xt6q9_nxs-stage -> nxs-k8s-s9: NodeAffinityPriority, Pontuação: (0)
I1115 07:57:21.639061 1 interpod_affinity.go:237] cronjob-cron-events-1573793820-xt6q9 -> nxs-k8s-s10: InterPodAffinityPriority, Pontuação: (0)
I1115 07:57:21.639063 1 selector_spreading.go:146] cronjob-cron-events-1573793820-xt6q9 -> nxs-k8s-s10: SelectorSpreadPriority, Pontuação: (10)
I1115 07:57:21.639073 1 interpod_affinity.go:237] cronjob-cron-events-1573793820-xt6q9 -> nxs-k8s-s8: InterPodAffinityPriority, Pontuação: (0)
I1115 07:57:21.639077 1 selector_spreading.go:146] cronjob-cron-events-1573793820-xt6q9 -> nxs-k8s-s8: SelectorSpreadPriority, Pontuação: (10)
I1115 07:57:21.639085 1 interpod_affinity.go:237] cronjob-cron-events-1573793820-xt6q9 -> nxs-k8s-s9: InterPodAffinityPriority, Pontuação: (0)
I1115 07:57:21.639088 1 selector_spreading.go:146] cronjob-cron-events-1573793820-xt6q9 -> nxs-k8s-s9: SelectorSpreadPriority, Pontuação: (10)
I1115 07:57:21.639103 1 generic_scheduler.go:726] cronjob-cron-events-1573793820-xt6q9_nxs-stage -> nxs-k8s-s10: SelectorSpreadPriority, Pontuação: (10)
I1115 07:57:21.639109 1 generic_scheduler.go:726] cronjob-cron-events-1573793820-xt6q9_nxs-stage -> nxs-k8s-s8: SelectorSpreadPriority, Pontuação: (10)
I1115 07:57:21.639114 1 generic_scheduler.go:726] cronjob-cron-events-1573793820-xt6q9_nxs-stage -> nxs-k8s-s9: SelectorSpreadPriority, Pontuação: (10)
I1115 07:57:21.639127 1 generic_scheduler.go:781] Host nxs-k8s-s10 -> Pontuação 100037
I1115 07:57:21.639150 1 generic_scheduler.go:781] Host nxs-k8s-s8 -> Pontuação 100034
I1115 07:57:21.639154 1 generic_scheduler.go:781] Host nxs-k8s-s9 -> Pontuação 100037
I1115 07:57:21.639267 1 scheduler_binder.go:269] AssumePodVolumes para o pod "nxs-stage/cronjob-cron-events-1573793820-xt6q9", nó "nxs-k8s-s10"
I1115 07:57:21.639286 1 scheduler_binder.go:279] AssumePodVolumes para o pod "nxs-stage/cronjob-cron-events-1573793820-xt6q9", nó "nxs-k8s-s10": todos os PVCs vinculados e nada a fazer
I1115 07:57:21.639333 1 factory.go:733] Tentando vincular cronjob-cron-events-1573793820-xt6q9 ao nxs-k8s-s10Aqui vemos que, inicialmente, o scheduler filtra e forma uma lista com 3 nós onde a execução é possível (nxs-k8s-s8, nxs-k8s-s9, nxs-k8s-s10). Em seguida, calcula a pontuação com base em vários parâmetros (incluindo BalancedResourceAllocation e LeastResourceAllocation) para cada um desses nós, com o objetivo de determinar o nó mais adequado. No final, o plano é executado no nó com a maior quantidade de pontos (neste caso, dois nós possuem o mesmo número de pontos 100037, portanto, uma escolha aleatória é feita entre eles — nxs-k8s-s10).
Saída: se em um nó estiverem funcionando pods para os quais não foram definidos limites, para o k8s (em termos de consumo de recursos) isso será o mesmo que se esses pods não estivessem nesse nó. Portanto, se você tiver, hipoteticamente, um pod com um processo voraz (por exemplo, wowza) e não foram definidos limites para ele, pode ocorrer uma situação em que esse pod consome todos os recursos do nó, mas, para o k8s, esse nó é considerado como não sobrecarregado e receberá a mesma quantidade de pontos na classificação (exatamente nos pontos de avaliação de recursos disponíveis) que o nó onde não há pods em funcionamento, o que pode levar a uma distribuição desigual de carga entre os nós.
Esvaziamento de pod
Como é sabido, cada pod recebe uma das 3 classes QoS:
- garantido — é atribuído quando para cada contêiner no pod são definidos request e limit para memória e CPU, e esses valores devem coincidir
- burstable — pelo menos um contêiner no pod tem request e limit, sendo que request < limit
- melhor esforço — quando nenhum contêiner no pod é restrito em recursos
Neste caso, quando há escassez de recursos (disco, memória) no nó, o kubelet começa a classificar e esvaziar os pods com base em um algoritmo que considera a prioridade do pod e sua classe QoS. Por exemplo, quando se trata de RAM, os pontos são atribuídos com base na classe QoS da seguinte forma:
- Garantido: -998
- BestEffort: 1000
- Burstable: min(max(2, 1000 — (1000 * memoryRequestBytes) / machineMemoryCapacityBytes), 999)
Ou seja, com prioridade igual, o kubelet esvaziará primeiro os pods com classe QoS de melhor esforço.
Saída: se você deseja reduzir a probabilidade de um pod necessário ser esvaziado do nó em caso de escassez de recursos nele, deve se preocupar em definir request/limit para ele, além da prioridade.
Mecanismo de dimensionamento automático horizontal de pods da aplicação (HPA)
Quando há a necessidade de aumentar ou diminuir automaticamente a quantidade de pods com base no uso de recursos (sistemáticos — CPU/RAM ou do usuário — rps), uma entidade do k8s pode ajudar na solução: HPA (Horizontal Pod Autoscaler). O algoritmo funciona da seguinte forma:
- Os valores atuais do recurso observado (currentMetricValue) são determinados.
- Os valores desejados para o recurso (desiredMetricValue) são definidos, os quais para recursos sistêmicos são estabelecidos através de requests.
- A quantidade atual de réplicas (currentReplicas) é determinada.
- A quantidade desejada de réplicas (desiredReplicas) é calculada pela seguinte fórmula:
desiredReplicas = [ currentReplicas * ( currentMetricValue / desiredMetricValue )]
Neste caso, não ocorrerá escalonamento quando o fator (currentMetricValue / desiredMetricValue) estiver próximo de 1 (a tolerância que podemos definir, por padrão, é 0,1).
Vamos considerar o funcionamento do HPA com o exemplo da aplicação app-test (descrito como Deployment), onde é necessário alterar a quantidade de réplicas com base no consumo de CPU:
Manifesto da aplicação
kind: Deployment apiVersion: apps/v1beta2 metadata: name: app-test spec: selector: matchLabels: app: app-test replicas: 2 template: metadata: labels: app: app-test spec: containers: - name: nginx image: registry.nixys.ru/generic-images/nginx imagePullPolicy: Always resources: requests: cpu: 60m ports: - name: http containerPort: 80 - name: nginx-exporter image: nginx/nginx-prometheus-exporter resources: requests: cpu: 30m ports: - name: nginx-exporter containerPort: 9113 args: - -nginx.scrape-uri - http://127.0.0.1:80/nginx-statusOu seja, vemos que o pod da aplicação é inicialmente iniciado em duas instâncias, cada uma contendo dois contêineres nginx e nginx-exporter, para os quais é definido requests para CPU.
Manifesto HPA
apiVersion: autoscaling/v2beta2 kind: HorizontalPodAutoscaler metadata: name: app-test-hpa spec: maxReplicas: 10 minReplicas: 2 scaleTargetRef: apiVersion: extensions/v1beta1 kind: Deployment name: app-test metrics: - type: Resource resource: name: cpu target: type: Utilization averageUtilization: 30Ou seja, criamos um HPA que irá monitorar o Deployment app-test e regular a quantidade de pods da aplicação com base no indicador de CPU (esperamos que o pod consuma 30% do CPU solicitado), onde o número de réplicas está entre 2-10.
Agora, vamos considerar o mecanismo de funcionamento do HPA quando uma carga é aplicada a um dos pods:
# kubectl top pod NAME CPU(cores) MEMORY(bytes) app-test-78559f8f44-pgs58 101m 243Mi app-test-78559f8f44-cj4jz 4m 240Mi
Em resumo, temos o seguinte:
- O valor desejado (desiredMetricValue) — de acordo com as configurações do hpa, é igual a 30%
- O valor atual (currentMetricValue) — para o cálculo, o controller-manager calcula a média do consumo de recursos em %, ou seja, realiza o seguinte:
- Obtém os valores absolutos das métricas dos pods do metric-server, ou seja, 101m e 4m
- Calcula a média absoluta, ou seja, (101m + 4m) / 2 = 53m
- Obtém o valor absoluto para o consumo de recursos desejado (para isso, soma-se a request de todos os contêineres) 60m + 30m = 90m
- Calcula a porcentagem média do consumo de CPU em relação à request do pod, ou seja, 53m / 90m * 100% = 59%
Agora temos tudo o que precisamos para determinar se devemos alterar o número de réplicas, para isso, calculamos o coeficiente:
ratio = 59% / 30% = 1.96
Ou seja, o número de réplicas deve ser aumentado em ~2 vezes e ser igual a [2 * 1.96] = 4.
Conclusão: Como podemos notar, para que esse mecanismo funcione, uma condição necessária é que haja requests para todos os contêineres no pod observado.
O mecanismo de autoscaling horizontal de nós (Cluster Autoscaler)
Para mitigar o impacto negativo no sistema durante picos de carga, ter um hpa configurado pode ser insuficiente. Por exemplo, de acordo com as configurações, o controller manager do hpa decide que o número de réplicas deve ser dobrado, no entanto, não há recursos disponíveis nos nós para executar essa quantidade de pods (ou seja, o nó não consegue fornecer os recursos solicitados pelo pod). Esses pods entram em estado Pending.
Nesse caso, se o provedor tiver o correspondente IaaS/PaaS (por exemplo, GKE/GCE, AKS, EKS etc.), podemos contar com uma ferramenta, como Node Autoscaler. Ela permite definir o número máximo e mínimo de nós no cluster e regular automaticamente o número atual de nós (através de chamadas à API do provedor de nuvem para solicitar/remover um nó), quando há falta de recursos no cluster e os pods não podem ser agendados (estão em estado Pending).
Conclusão: Para possibilitar o autoscaling dos nós, é necessário definir requests nos contêineres dos pods, para que o k8s possa avaliar corretamente a carga dos nós e, consequentemente, informar que não há recursos suficientes no cluster para iniciar um novo pod.
Conclusão
É importante mencionar que a configuração de limitações de recursos para o contêiner não é uma condição obrigatória para o lançamento bem-sucedido do aplicativo, mas ainda assim é recomendável fazê-lo pelos seguintes motivos:
- Para um funcionamento mais preciso do scheduler em relação ao balanceamento de carga entre os nós do k8s
- Para reduzir a probabilidade de um evento de “despejo do pod”
- Para que o escalonamento automático horizontal dos pods do aplicativo (HPA) funcione
- Para que o escalonamento automático horizontal dos nós (Cluster Autoscaling) funcione em provedores de nuvem
Leia também outros artigos em nosso blog:
Fonte: habr.com
