Kubernetes: por que é tão importante configurar o gerenciamento de recursos do sistema?

Via de regra, há sempre a necessidade de fornecer um pool de recursos dedicado a uma aplicação para seu correto e estável funcionamento. Mas e se vários aplicativos estiverem sendo executados com a mesma energia? Como dotar cada um deles dos recursos mínimos necessários? Como você pode limitar o consumo de recursos? Como distribuir corretamente a carga entre os nós? Como garantir que o mecanismo de escalonamento horizontal funcione se a carga do aplicativo aumentar?

Kubernetes: por que é tão importante configurar o gerenciamento de recursos do sistema?

Você precisa começar com os principais tipos de recursos existentes no sistema - isso, é claro, é o tempo do processador e a RAM. Nos manifestos k8s, esses tipos de recursos são medidos nas seguintes unidades:

  • CPU - em núcleos
  • RAM - em bytes

Além disso, para cada recurso é possível definir dois tipos de requisitos - pedidos и limites. Solicitações - descreve os requisitos mínimos para recursos livres de um nó para executar um contêiner (e pod como um todo), enquanto limites definem um limite rígido para os recursos disponíveis para o contêiner.

É importante entender que o manifesto não precisa definir explicitamente os dois tipos, mas o comportamento será o seguinte:

  • Se apenas os limites de um recurso forem especificados explicitamente, as solicitações para esse recurso assumirão automaticamente um valor igual aos limites (você pode verificar isso chamando entidades de descrição). Aqueles. na verdade, o contêiner será limitado à mesma quantidade de recursos necessários para funcionar.
  • Se apenas as solicitações forem especificadas explicitamente para um recurso, nenhuma restrição superior será definida para esse recurso - ou seja, o contêiner é limitado apenas pelos recursos do próprio nó.

Também é possível configurar o gerenciamento de recursos não apenas no nível de um contêiner específico, mas também no nível do namespace usando as seguintes entidades:

  • LimitRange — descreve a política de restrição no nível do contêiner/pod em ns e é necessária para descrever os limites padrão no contêiner/pod, bem como evitar a criação de contêineres/pods obviamente gordos (ou vice-versa), limitar seu número e determinar a possível diferença nos valores em limites e solicitações
  • Cotas de recursos — descreve a política de restrição em geral para todos os contêineres em ns e é usada, via de regra, para delimitar recursos entre ambientes (útil quando os ambientes não são estritamente demarcados no nível do nó)

A seguir estão exemplos de manifestos que definem limites de recursos:

  • No nível do contêiner específico:

    containers:
    - name: app-nginx
      image: nginx
      resources:
        requests:
          memory: 1Gi
        limits:
          cpu: 200m

    Aqueles. neste caso, para executar um contêiner com nginx, você precisará de pelo menos 1G de RAM livre e 0.2 CPU no nó, enquanto no máximo o contêiner pode consumir 0.2 CPU e toda a RAM disponível no nó.

  • No nível inteiro ns:

    apiVersion: v1
    kind: ResourceQuota
    metadata:
      name: nxs-test
    spec:
      hard:
        requests.cpu: 300m
        requests.memory: 1Gi
        limits.cpu: 700m
        limits.memory: 2Gi

    Aqueles. a soma de todos os contêineres de solicitação no ns padrão não pode exceder 300m para a CPU e 1G para o OP, e a soma de todos os limites é 700m para a CPU e 2G para o OP.

  • Limites padrão para contêineres em 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: 4Gi

    Aqueles. no namespace padrão para todos os contêineres, a solicitação será definida como 100m para CPU e 1G para OP, limite - 1 CPU e 2G. Ao mesmo tempo, também é definido um limite nos valores possíveis em solicitação/limite para CPU (50m < x < 2) e RAM (500M < x < 4G).

  • Restrições no nível do pod:

    apiVersion: v1
    kind: LimitRange
    metadata:
     name: nxs-limit-pod
    spec:
     limits:
     - type: Pod
       max:
         cpu: 4
         memory: 1Gi

    Aqueles. para cada pod no ns padrão haverá um limite de 4 vCPU e 1G.

Agora gostaria de contar quais vantagens a definição dessas restrições pode nos trazer.

Mecanismo de balanceamento de carga entre nós

Como você sabe, o componente k8s é responsável pela distribuição dos pods entre os nós, como agendador, que funciona de acordo com um algoritmo específico. Este algoritmo passa por dois estágios ao selecionar o nó ideal para iniciar:

  1. filtragem
  2. Variação

Aqueles. de acordo com a política descrita, são inicialmente selecionados nós nos quais é possível lançar um pod com base em um conjunto predicados (incluindo verificar se o nó possui recursos suficientes para executar o pod - PodFitsResources) e, em seguida, para cada um desses nós, de acordo com prioridades pontos são concedidos (incluindo quanto mais recursos livres um nó tiver, mais pontos ele será atribuído - LeastResourceAllocation/LeastRequestedPriority/BalancedResourceAllocation) e o pod será iniciado no nó com mais pontos (se vários nós satisfizerem esta condição ao mesmo tempo, então um aleatório é selecionado).

Ao mesmo tempo, você precisa entender que o agendador, ao avaliar os recursos disponíveis de um nó, é guiado pelos dados que estão armazenados no etcd - ou seja, para a quantidade de recurso solicitado/limite de cada pod em execução neste nó, mas não para o consumo real de recursos. Esta informação pode ser obtida na 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 que cada pod solicita. E aqui está a aparência dos logs do agendador quando o pod cronjob-cron-events-1573793820-xt6q9 é iniciado (esta informação aparecerá no log do agendador quando você definir o 10º nível de log nos argumentos do comando de inicialização -v=10):

log

I1115 07:57:21.637791       1 scheduling_queue.go:908] About to try and schedule pod nxs-stage/cronjob-cron-events-1573793820-xt6q9                                                                                                                                           
I1115 07:57:21.637804       1 scheduler.go:453] Attempting to schedule pod: nxs-stage/cronjob-cron-events-1573793820-xt6q9                                                                                                                                                    
I1115 07:57:21.638285       1 predicates.go:829] Schedule Pod nxs-stage/cronjob-cron-events-1573793820-xt6q9 on Node nxs-k8s-s5 is allowed, Node is running only 16 out of 110 Pods.                                                                               
I1115 07:57:21.638300       1 predicates.go:829] Schedule Pod nxs-stage/cronjob-cron-events-1573793820-xt6q9 on Node nxs-k8s-s6 is allowed, Node is running only 20 out of 110 Pods.                                                                               
I1115 07:57:21.638322       1 predicates.go:829] Schedule Pod nxs-stage/cronjob-cron-events-1573793820-xt6q9 on Node nxs-k8s-s3 is allowed, Node is running only 20 out of 110 Pods.                                                                               
I1115 07:57:21.638322       1 predicates.go:829] Schedule Pod nxs-stage/cronjob-cron-events-1573793820-xt6q9 on Node nxs-k8s-s4 is allowed, Node is running only 17 out of 110 Pods.                                                                               
I1115 07:57:21.638334       1 predicates.go:829] Schedule Pod nxs-stage/cronjob-cron-events-1573793820-xt6q9 on Node nxs-k8s-s10 is allowed, Node is running only 16 out of 110 Pods.                                                                              
I1115 07:57:21.638365       1 predicates.go:829] Schedule Pod nxs-stage/cronjob-cron-events-1573793820-xt6q9 on Node nxs-k8s-s12 is allowed, Node is running only 9 out of 110 Pods.                                                                               
I1115 07:57:21.638334       1 predicates.go:829] Schedule Pod nxs-stage/cronjob-cron-events-1573793820-xt6q9 on Node nxs-k8s-s11 is allowed, Node is running only 11 out of 110 Pods.                                                                              
I1115 07:57:21.638385       1 predicates.go:829] Schedule Pod nxs-stage/cronjob-cron-events-1573793820-xt6q9 on Node nxs-k8s-s1 is allowed, Node is running only 19 out of 110 Pods.                                                                               
I1115 07:57:21.638402       1 predicates.go:829] Schedule Pod nxs-stage/cronjob-cron-events-1573793820-xt6q9 on Node nxs-k8s-s2 is allowed, Node is running only 21 out of 110 Pods.                                                                               
I1115 07:57:21.638383       1 predicates.go:829] Schedule Pod nxs-stage/cronjob-cron-events-1573793820-xt6q9 on Node nxs-k8s-s9 is allowed, Node is running only 16 out of 110 Pods.                                                                               
I1115 07:57:21.638335       1 predicates.go:829] Schedule Pod nxs-stage/cronjob-cron-events-1573793820-xt6q9 on Node nxs-k8s-s8 is allowed, Node is running only 18 out of 110 Pods.                                                                               
I1115 07:57:21.638408       1 predicates.go:829] Schedule Pod nxs-stage/cronjob-cron-events-1573793820-xt6q9 on Node nxs-k8s-s13 is allowed, Node is running only 8 out of 110 Pods.                                                                               
I1115 07:57:21.638478       1 predicates.go:1369] Schedule Pod nxs-stage/cronjob-cron-events-1573793820-xt6q9 on Node nxs-k8s-s10 is allowed, existing pods anti-affinity terms satisfied.                                                                         
I1115 07:57:21.638505       1 predicates.go:1369] Schedule Pod nxs-stage/cronjob-cron-events-1573793820-xt6q9 on Node nxs-k8s-s8 is allowed, existing pods anti-affinity terms satisfied.                                                                          
I1115 07:57:21.638577       1 predicates.go:1369] Schedule Pod nxs-stage/cronjob-cron-events-1573793820-xt6q9 on Node nxs-k8s-s9 is allowed, existing pods anti-affinity terms satisfied.                                                                          
I1115 07:57:21.638583       1 predicates.go:829] Schedule Pod nxs-stage/cronjob-cron-events-1573793820-xt6q9 on Node nxs-k8s-s7 is allowed, Node is running only 25 out of 110 Pods.                                                                               
I1115 07:57:21.638932       1 resource_allocation.go:78] cronjob-cron-events-1573793820-xt6q9 -> nxs-k8s-s10: BalancedResourceAllocation, capacity 39900 millicores 66620178432 memory bytes, total request 2343 millicores 9640186880 memory bytes, score 9        
I1115 07:57:21.638946       1 resource_allocation.go:78] cronjob-cron-events-1573793820-xt6q9 -> nxs-k8s-s10: LeastResourceAllocation, capacity 39900 millicores 66620178432 memory bytes, total request 2343 millicores 9640186880 memory bytes, score 8           
I1115 07:57:21.638961       1 resource_allocation.go:78] cronjob-cron-events-1573793820-xt6q9 -> nxs-k8s-s9: BalancedResourceAllocation, capacity 39900 millicores 66620170240 memory bytes, total request 4107 millicores 11307422720 memory bytes, score 9        
I1115 07:57:21.638971       1 resource_allocation.go:78] cronjob-cron-events-1573793820-xt6q9 -> nxs-k8s-s8: BalancedResourceAllocation, capacity 39900 millicores 66620178432 memory bytes, total request 5847 millicores 24333637120 memory bytes, score 7        
I1115 07:57:21.638975       1 resource_allocation.go:78] cronjob-cron-events-1573793820-xt6q9 -> nxs-k8s-s9: LeastResourceAllocation, capacity 39900 millicores 66620170240 memory bytes, total request 4107 millicores 11307422720 memory bytes, score 8           
I1115 07:57:21.638990       1 resource_allocation.go:78] cronjob-cron-events-1573793820-xt6q9 -> nxs-k8s-s8: LeastResourceAllocation, capacity 39900 millicores 66620178432 memory bytes, total request 5847 millicores 24333637120 memory bytes, score 7           
I1115 07:57:21.639022       1 generic_scheduler.go:726] cronjob-cron-events-1573793820-xt6q9_nxs-stage -> nxs-k8s-s10: TaintTolerationPriority, Score: (10)                                                                                                        
I1115 07:57:21.639030       1 generic_scheduler.go:726] cronjob-cron-events-1573793820-xt6q9_nxs-stage -> nxs-k8s-s8: TaintTolerationPriority, Score: (10)                                                                                                         
I1115 07:57:21.639034       1 generic_scheduler.go:726] cronjob-cron-events-1573793820-xt6q9_nxs-stage -> nxs-k8s-s9: TaintTolerationPriority, Score: (10)                                                                                                         
I1115 07:57:21.639041       1 generic_scheduler.go:726] cronjob-cron-events-1573793820-xt6q9_nxs-stage -> nxs-k8s-s10: NodeAffinityPriority, Score: (0)                                                                                                            
I1115 07:57:21.639053       1 generic_scheduler.go:726] cronjob-cron-events-1573793820-xt6q9_nxs-stage -> nxs-k8s-s8: NodeAffinityPriority, Score: (0)                                                                                                             
I1115 07:57:21.639059       1 generic_scheduler.go:726] cronjob-cron-events-1573793820-xt6q9_nxs-stage -> nxs-k8s-s9: NodeAffinityPriority, Score: (0)                                                                                                             
I1115 07:57:21.639061       1 interpod_affinity.go:237] cronjob-cron-events-1573793820-xt6q9 -> nxs-k8s-s10: InterPodAffinityPriority, Score: (0)                                                                                                                   
I1115 07:57:21.639063       1 selector_spreading.go:146] cronjob-cron-events-1573793820-xt6q9 -> nxs-k8s-s10: SelectorSpreadPriority, Score: (10)                                                                                                                   
I1115 07:57:21.639073       1 interpod_affinity.go:237] cronjob-cron-events-1573793820-xt6q9 -> nxs-k8s-s8: InterPodAffinityPriority, Score: (0)                                                                                                                    
I1115 07:57:21.639077       1 selector_spreading.go:146] cronjob-cron-events-1573793820-xt6q9 -> nxs-k8s-s8: SelectorSpreadPriority, Score: (10)                                                                                                                    
I1115 07:57:21.639085       1 interpod_affinity.go:237] cronjob-cron-events-1573793820-xt6q9 -> nxs-k8s-s9: InterPodAffinityPriority, Score: (0)                                                                                                                    
I1115 07:57:21.639088       1 selector_spreading.go:146] cronjob-cron-events-1573793820-xt6q9 -> nxs-k8s-s9: SelectorSpreadPriority, Score: (10)                                                                                                                    
I1115 07:57:21.639103       1 generic_scheduler.go:726] cronjob-cron-events-1573793820-xt6q9_nxs-stage -> nxs-k8s-s10: SelectorSpreadPriority, Score: (10)                                                                                                         
I1115 07:57:21.639109       1 generic_scheduler.go:726] cronjob-cron-events-1573793820-xt6q9_nxs-stage -> nxs-k8s-s8: SelectorSpreadPriority, Score: (10)                                                                                                          
I1115 07:57:21.639114       1 generic_scheduler.go:726] cronjob-cron-events-1573793820-xt6q9_nxs-stage -> nxs-k8s-s9: SelectorSpreadPriority, Score: (10)                                                                                                          
I1115 07:57:21.639127       1 generic_scheduler.go:781] Host nxs-k8s-s10 => Score 100037                                                                                                                                                                            
I1115 07:57:21.639150       1 generic_scheduler.go:781] Host nxs-k8s-s8 => Score 100034                                                                                                                                                                             
I1115 07:57:21.639154       1 generic_scheduler.go:781] Host nxs-k8s-s9 => Score 100037                                                                                                                                                                             
I1115 07:57:21.639267       1 scheduler_binder.go:269] AssumePodVolumes for pod "nxs-stage/cronjob-cron-events-1573793820-xt6q9", node "nxs-k8s-s10"                                                                                                               
I1115 07:57:21.639286       1 scheduler_binder.go:279] AssumePodVolumes for pod "nxs-stage/cronjob-cron-events-1573793820-xt6q9", node "nxs-k8s-s10": all PVCs bound and nothing to do                                                                             
I1115 07:57:21.639333       1 factory.go:733] Attempting to bind cronjob-cron-events-1573793820-xt6q9 to nxs-k8s-s10

Aqui vemos que inicialmente o agendador filtra e gera uma lista de 3 nós nos quais pode ser iniciado (nxs-k8s-s8, nxs-k8s-s9, nxs-k8s-s10). Em seguida, ele calcula pontuações com base em vários parâmetros (incluindo BalancedResourceAllocation, LeastResourceAllocation) para cada um desses nós, a fim de determinar o nó mais adequado. Em última análise, o pod é agendado no nó com o maior número de pontos (aqui dois nós ao mesmo tempo têm o mesmo número de pontos 100037, então um nó aleatório é selecionado - nxs-k8s-s10).

Jogar aviator online grátis: hack aviator funciona: se um nó executa pods para os quais nenhuma restrição é definida, então para k8s (do ponto de vista do consumo de recursos) isso será equivalente a como se não existissem tais pods neste nó. Portanto, se você, condicionalmente, tiver um pod com um processo guloso (por exemplo, wowza) e nenhuma restrição for definida para ele, então pode surgir uma situação em que esse pod realmente comeu todos os recursos do nó, mas para k8s este nó é considerado descarregado e receberá o mesmo número de pontos na classificação (precisamente em pontos que avaliam os recursos disponíveis) como um nó que não possui pods funcionais, o que em última análise pode levar a uma distribuição desigual da carga entre os nós.

Despejo de pod

Como você sabe, cada pod recebe uma das três classes de QoS:

  1. garantido — é atribuído quando para cada contêiner no pod uma solicitação e limite são especificados para memória e CPU, e esses valores devem corresponder
  2. estourável — pelo menos um contêiner no pod tem uma solicitação e um limite, com solicitação <limite
  3. melhor esforço — quando nenhum contêiner no pod tem recursos limitados

Ao mesmo tempo, quando um nó apresenta falta de recursos (disco, memória), o kubelet começa a classificar e despejar pods de acordo com um algoritmo específico que leva em consideração a prioridade do pod e sua classe de QoS. Por exemplo, se estamos falando de RAM, então com base na classe QoS, os pontos são atribuídos de acordo com o seguinte princípio:

  • Garantida: -998
  • Melhor esforço 1000
  • Explosável: min(máx(2, 1000 - (1000 * memóriaRequestBytes) /máquinaMemoryCapacityBytes), 999)

Aqueles. com a mesma prioridade, o kubelet primeiro removerá os pods com a classe de QoS de melhor esforço do nó.

Jogar aviator online grátis: hack aviator funciona: se você deseja reduzir a probabilidade de o pod desejado ser despejado do nó em caso de falta de recursos nele, junto com a prioridade, você também precisa definir a solicitação/limite para ele.

Mecanismo para escalonamento automático horizontal de pods de aplicativos (HPA)

Quando a tarefa é aumentar e diminuir automaticamente o número de pods dependendo do uso de recursos (sistema - CPU/RAM ou usuário - rps), uma entidade k8s como HPA (escalador automático de pod horizontal). O algoritmo é o seguinte:

  1. As leituras atuais do recurso observado são determinadas (currentMetricValue)
  2. São determinados os valores desejados para o recurso (desiredMetricValue), que para recursos do sistema são definidos usando request
  3. O número atual de réplicas é determinado (currentReplicas)
  4. A fórmula a seguir calcula o número desejado de réplicas (desiredReplicas)
    desejadaReplicas = [ currentReplicas * ( currentMetricValue / desejadoMetricValue )]

Neste caso, o escalonamento não ocorrerá quando o coeficiente (currentMetricValue/desejadoMetricValue) estiver próximo de 1 (neste caso, podemos definir nós mesmos o erro permitido; por padrão é 0.1).

Vejamos como funciona o hpa usando o exemplo da aplicação app-test (descrita como Deployment), onde é necessário alterar o número de réplicas dependendo do consumo de CPU:

  • Manifesto do aplicativo

    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-status

    Aqueles. vemos que o pod do aplicativo é inicialmente iniciado em duas instâncias, cada uma contendo dois contêineres nginx e nginx-exporter, para cada um dos quais um especificado pedidos 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: 30

    Aqueles. Criamos um hpa que irá monitorar o Deployment app-test e ajustar o número de pods com a aplicação com base no indicador de CPU (esperamos que o pod consuma 30% da CPU que ele solicita), com o número de réplicas sendo em o intervalo de 2 a 10.

    Agora, vejamos o mecanismo de funcionamento do hpa se aplicarmos uma carga a uma das lareiras:

     # kubectl top pod
    NAME                                                   CPU(cores)   MEMORY(bytes)
    app-test-78559f8f44-pgs58            101m         243Mi
    app-test-78559f8f44-cj4jz            4m           240Mi

No total temos o seguinte:

  • O valor desejado (desiredMetricValue) - de acordo com as configurações do hpa, temos 30%
  • Valor atual (currentMetricValue) - para cálculo, o controller-manager calcula o valor médio do consumo de recursos em%, ou seja, condicionalmente faz o seguinte:
    1. Recebe valores absolutos de métricas de pod do servidor de métricas, ou seja, 101m e 4m
    2. Calcula o valor absoluto médio, ou seja, (101m + 4m) / 2 = 53m
    3. Obtém o valor absoluto do consumo de recursos desejado (para isso somam-se as solicitações de todos os containers) 60m + 30m = 90m
    4. Calcula a porcentagem média de consumo de CPU em relação ao pod de solicitação, ou seja, 53m / 90m * 100% = 59%

Agora temos tudo o que precisamos para determinar se precisamos alterar o número de réplicas; para fazer isso, calculamos o coeficiente:

ratio = 59% / 30% = 1.96

Aqueles. o número de réplicas deve ser aumentado em aproximadamente 2 vezes e totalizar [2 * 1.96] = 4.

Conclusão: Como você pode ver, para que esse mecanismo funcione, uma condição necessária é a presença de solicitações para todos os containers no pod observado.

Mecanismo para escalonamento automático horizontal de nós (Cluster Autoscaler)

Para neutralizar o impacto negativo no sistema durante picos de carga, não basta ter um HPa configurado. Por exemplo, de acordo com as configurações no gerenciador do controlador HPA, ele decide que o número de réplicas precisa ser aumentado em 2 vezes, mas os nós não têm recursos livres para executar tal número de pods (ou seja, o nó não pode fornecer o recursos solicitados para o pod de solicitações) e esses pods mudam para o estado Pendente.

Neste caso, se o provedor tiver um IaaS/PaaS correspondente (por exemplo, GKE/GCE, AKS, EKS, etc.), uma ferramenta como Escalonador automático de nós. Ele permite que você defina o número máximo e mínimo de nós no cluster e ajuste automaticamente o número atual de nós (chamando a API do provedor de nuvem para solicitar/remover um nó) quando houver falta de recursos no cluster e nos pods não podem ser agendados (estão no estado Pendente).

Conclusão: Para poder dimensionar automaticamente os nós, é necessário definir solicitações nos contêineres do pod para que o k8s possa avaliar corretamente a carga nos nós e, consequentemente, relatar que não há recursos no cluster para iniciar o próximo pod.

Conclusão

Deve-se observar que definir limites de recursos do contêiner não é um requisito para que o aplicativo seja executado com êxito, mas ainda é melhor fazê-lo pelos seguintes motivos:

  1. Para uma operação mais precisa do agendador em termos de balanceamento de carga entre nós k8s
  2. Para reduzir a probabilidade de ocorrência de um evento de “despejo de pod”
  3. Para que o escalonamento automático horizontal de pods de aplicativos (HPA) funcione
  4. Para escalonamento automático horizontal de nós (escalonamento automático de cluster) para provedores de nuvem

Leia também outros artigos em nosso blog:

Fonte: habr.com

Adicionar um comentário