Introdução

Ao trabalhar com uma aplicação criada no Kubernetes, os desenvolvedores frequentemente precisam provisionar pods adicionais para lidar com períodos de pico de tráfego ou aumento da carga de processamento. Por padrão, provisionar esses pods adicionais é uma etapa manual; o desenvolvedor deve alterar o número de réplicas desejadas no objeto do deployment para contar com o aumento do tráfego e alterá-lo novamente quando os pods adicionais não forem mais necessários. Essa dependência da intervenção manual pode não ser o ideal em muitos cenários. Por exemplo, sua carga de trabalho pode atingir o horário de pico no meio da noite, quando ninguém está acordado para escalar os pods, ou seu site pode receber um aumento inesperado no tráfego quando uma resposta manual não seria rápida o suficiente para lidar com a carga. Nessas situações, a abordagem mais eficiente e menos sujeita a erros é automatizar o escalonamento dos seus clusters com o Horizontal Pod Autoscaler (HPA).

Usando informações do Metrics Server, o HPA detectará aumento no uso de recursos e responderá escalando sua carga de trabalho para você. Isso é especialmente útil nas arquiteturas de microsserviço e dará ao cluster Kubernetes a capacidade de escalar seu deployment com base em métricas como a utilização da CPU. Quando combinado como o DigitalOcean Kubernetes (DOKS), uma oferta de Kubernetes gerenciada que fornece aos desenvolvedores uma plataforma para fazer o deploy de aplicações containerizadas, o uso do HPA pode criar uma infraestrutura automatizada que se ajusta rapidamente às mudanças no tráfego e na carga.

Nota: Ao considerar a possibilidade de usar o autoscaling para sua carga de trabalho, lembre-se de que o autoscaling funciona melhor para aplicativos sem estado ou stateless, especialmente aqueles capazes de ter várias instâncias da aplicação em execução e aceitando tráfego em paralelo. Esse paralelismo é importante porque o principal objetivo do autoscaling é distribuir dinamicamente a carga de trabalho de uma aplicação por várias instâncias no cluster Kubernetes para garantir que sua aplicação tenha os recursos necessários para atender o tráfego de maneira ágil e estável, sem sobrecarregar nenhuma instância única.

Um exemplo de carga de trabalho que não apresenta esse paralelismo é o autoscaling de banco de dados. A configuração do autoscaling para um banco de dados seria muito mais complexa, pois você precisaria considerar race conditions, problemas com a integridade dos dados, sincronização de dados e adições e remoções constantes de membros do cluster de banco de dados. Por razões como essas, não recomendamos o uso da estratégia de autoscaling deste tutorial para bancos de dados.

Neste tutorial você vai configurar um deployment de exemplo do Nginx no DOKS que pode auto escalar horizontalmente para dar conta do aumento da carga de CPU. Você conseguirá isso ao fazer o deploy do Metrics Server em seu cluster para reunir métricas de pod para o HPA usar para determinar quando escalar.

Pré-requisitos

Antes de começar este guia, você precisará do seguinte:

  • Um cluster Kubernetes na DigitalOcean com sua conexão configurada como padrão kubectl. As instruções sobre como configurar o kubectl são mostradas no passo Connect to your Cluster quando você cria seu cluster. Para criar um cluster Kubernetes na DigitalOcean, consulte Kubernetes Quickstart.

  • O gerenciador de pacotes Helm instalado em sua máquina local e o Tiller instalado em seu cluster. Para fazer isso, execute os passos 1 e 2 do tutorial How To Install Software on Kubernetes Clusters with the Helm Package Manager

Passo 1 — Criando um Deployment de Teste

Para mostrar o efeito do HPA, você primeiro fará o deploy de uma aplicação que você utilizará para fazer autoscale. Este tutorial usa uma imagem Nginx Docker padrão como um deployment porque ela é totalmente capaz de operar em paralelo, é amplamente usada no Kubernetes com ferramentas como o Nginx Ingress Controller, e é leve para configurar. Esse deployment do Nginx servirá uma página estática Welcome to Nginx!, que vem por padrão na imagem base. Se você já possui um deployment que gostaria de escalar, sinta-se à vontade para usá-lo e pule este passo.

Crie o deployment de exemplo usando a imagem base do Nginx executando o seguinte comando. Você pode substituir o nome web se desejar atribuir um nome diferente ao seu deployment:

  • kubectl create deployment web --image=nginx:latest

A flag --image=nginx:latest criará o deployment a partir da versão mais recente da imagem base do Nginx.

Após alguns segundos, seu pod web será lançado. Para ver este pod, execute o seguinte comando, que mostrará os pods em execução no namespace atual:

  • kubectl get pods

Isso lhe dará uma saída semelhante à seguinte:

Output
NAME READY STATUS RESTARTS AGE web-84d7787df5-btf9h 1/1 Running 0 11s

Observe que há apenas um pod deployado originalmente. Depois que o autoscaling é acionado, mais pods serão criados automaticamente.

Agora você tem um deployment básico em funcionamento no cluster. Este é o deployment que você irá configurar para o autoscaling. Seu próximo passo é configurar esse deployment para definir suas solicitações de recursos e limites.

Passo 2 — Definindo Limites e Solicitações de CPU em seu Deployment

Neste passo, você irá definir solicitações e limites no uso da CPU para seu deployment. Limites ou Limits no Kubernetes são definidos no deployment para descrever a quantidade máxima de recursos (CPU ou Memória) que o pod pode usar. Solicitações ou Requests são definidas no deployment para descrever quanto desse recurso é necessário em um node para que esse node seja considerado como um node válido para escalonamento. Por exemplo, se seu servidor web tivesse uma solicitação de memória definida em 1 GB, apenas os nodes com pelo menos 1 GB de memória livre seriam considerados para escalonamento. Para o autoscaling, é necessário definir esses limites e solicitações, pois o HPA precisará ter essas informações ao tomar decisões de escalonamento e provisionamento.

Para definir solicitações e limites, você precisará fazer alterações no deployment que você acabou de criar. Este tutorial usará o seguinte comando kubectl edit para modificar a configuração do objeto API armazenada no cluster. O comando kubectl edit abrirá o editor definido por suas variáveis de ambiente KUBE_EDITOR ou EDITOR, ou cairá de volta no vi para Linux ou notepad para Windows por padrão.

Edite seu deployment:

  • kubectl edit deployment web

Você verá a configuração para o deployment. Agora você pode definir limites de recursos e solicitações especificadas para o uso de CPU do seu deployment. Esses limites definem a linha de base de quanto de cada recurso um pod deste deployment pode usar individualmente. Definir isso dará ao HPA um quadro de referência para saber se um pod está sendo sobrecarregado. Por exemplo, se você espera que seu pod tenha um limit superior de 100 milicores de CPU e o pod esteja usando 95 milicores atualmente, a HPA saberá que está com 95% da capacidade. Sem fornecer esse limite de 100 milicores, o HPA não pode decifrar a capacidade total do pod.

Podemos definir os limites e solicitações na seção resources:

Deployment Configuration File
. . .
  template:
    metadata:
      creationTimestamp: null
      labels:
        app: web
    spec:
      containers:
      - image: nginx:latest
        imagePullPolicy: Always
        name: nginx
        resources: {}
        terminationMessagePath: /dev/termination-log
        terminationMessagePolicy: File
      dnsPolicy: ClusterFirst
      restartPolicy: Always
      schedulerName: default-scheduler
      securityContext: {}
      terminationGracePeriodSeconds: 30
status:
  availableReplicas: 1
. . .

Para este tutorial, você definirá requests para CPU como 100m e memória para 250Mi. Esses valores são apenas para fins de demonstração; cada carga de trabalho é diferente, portanto, esses valores podem não fazer sentido para outras cargas de trabalho. Como regra geral, esses valores devem ser definidos no máximo que um pod dessa carga de trabalho deve usar. Recomenda-se o monitoramento da aplicação e a coleta de dados de uso de recursos sobre o desempenho em períodos de baixa e de pico para ajudar a determinar esses valores. Esses valores também podem ser ajustados e alterados a qualquer momento, assim você sempre pode voltar e otimizar seu deployment posteriormente.

Vá em frente e insira as seguintes linhas destacadas na seção resources do seu container Nginx:

Deployment Configuration File
. . .
  template:
    metadata:
      creationTimestamp: null
      labels:
        app: web
    spec:
      containers:
      - image: nginx:latest
        imagePullPolicy: Always
        name: nginx
        resources:
          limits:
            cpu: 300m
          requests:
            cpu: 100m
            memory: 250Mi
        terminationMessagePath: /dev/termination-log
        terminationMessagePolicy: File
      dnsPolicy: ClusterFirst
      restartPolicy: Always
      schedulerName: default-scheduler
      securityContext: {}
      terminationGracePeriodSeconds: 30
status:
  availableReplicas: 1
. . .

Depois de inserir essas linhas, salve e saia do arquivo. Se houver um problema com a sintaxe, o kubectl irá reabrir o arquivo para você com um erro publicado para que você obtenha mais informações.

Agora que você definiu seus limites e solicitações, você precisa garantir que suas métricas sejam reunidas para que o HPA possa monitorar e aderir corretamente a esses limites. Para fazer isso, você irá configurar um serviço para reunir as métricas de CPU. Para este tutorial, você usará o projeto Metrics Server para coletar essas métricas, que você instalará com um chart do Helm.

Passo 3 — Instalando o Metrics Server

Agora você instalará o Kubernetes Metric Server. Esse é o servidor que extrai as métricas do pod, que reunirá as métricas que o HPA usará para decidir se o autoscaling é necessário.

Para instalar o Metrics Server usando o Helm, execute o seguinte comando:

  • helm install stable/metrics-server --name metrics-server

Isso instalará a versão estável mais recente do Metrics Server. A flag --name nomeia este release como metrics-server.

Depois de aguardar a inicialização deste pod, tente usar o comando kubectl top pod para exibir as métricas do seu pod:

  • kubectl top pod

Este comando tem como objetivo fornecer uma visão em nível de pod do uso de recursos em seu cluster, mas devido à maneira como o DOKS lida com o DNS, esse comando retornará um erro neste momento:

Output
Error: Metrics not available for pod Error from server (ServiceUnavailable): the server is currently unable to handle the request (get pods.metrics.k8s.io)

Esse erro ocorre porque os nodes DOKS não criam um registro DNS para eles mesmos e, como o Metrics Server entra em contato com os nodes por meio de seus nomes de host, os nomes de host não são resolvidos corretamente. Para corrigir esse problema, altere a maneira como o Metrics Server se comunica com os nodes adicionando flags de runtime ao container do Metrics Server usando o seguinte comando:

  • kubectl edit deployment metrics-server

Você estará adicionando uma flag na seção command.

metrics-server Configuration File
. . .
  template:
    metadata:
      creationTimestamp: null
      labels:
        app: metrics-server
        release: metrics-server
    spec:
      affinity: {}
      containers:
      - command:
        - /metrics-server
        - --cert-dir=/tmp
        - --logtostderr
        - --secure-port=8443
        image: gcr.io/google_containers/metrics-server-amd64:v0.3.4
        imagePullPolicy: IfNotPresent
        livenessProbe:
          failureThreshold: 3
          httpGet:
            path: /healthz
. . .

A flag que você está adicionando é --kubelet-preferred-address-types=InternalIP. Essa flag informa ao metrics server para contatar os nodes usando seu internalIP em oposição ao nome do host. Você pode usar essa flag como uma solução alternativa para se comunicar com os nodes por meio de endereços IP internos.

Adicione também a flag --metric-resolution para alterar a taxa padrão na qual o Metrics Server extrai as métricas. Para este tutorial, configuraremos o Metrics Server para realizar pontos de coletas de dados a cada 60s, mas se você quiser mais dados de métricas, poderá solicitar ao Metrics Server que extraia as métricas a cada 10s ou 20s. Isso lhe fornecerá mais pontos de dados de uso de recursos por período de tempo. Sinta-se livre para ajustar esta resolução para atender às suas necessidades.

Adicione as seguintes linhas destacadas ao arquivo:

metrics-server Configuration File
. . .
  template:
    metadata:
      creationTimestamp: null
      labels:
        app: metrics-server
        release: metrics-server
    spec:
      affinity: {}
      containers:
      - command:
        - /metrics-server
        - --cert-dir=/tmp
        - --logtostderr
        - --secure-port=8443
        - --metric-resolution=60s
        - --kubelet-preferred-address-types=InternalIP
        image: gcr.io/google_containers/metrics-server-amd64:v0.3.4
        imagePullPolicy: IfNotPresent
        livenessProbe:
          failureThreshold: 3
          httpGet:
            path: /healthz
. . .

Após a adição da flag, salve e saia do seu editor.

Para verificar se o Metrics Server está em execução, use o kubectl top pod após alguns minutos. Como antes, este comando nos fornecerá o uso de recursos em um nível de pod. Dessa vez, um Metrics Server funcionando permitirá que você veja as métricas em cada pod:

  • kubectl top pod

Isso fornecerá a seguinte saída, com o seu pod do Metrics Server em execução:

Output
NAME CPU(cores) MEMORY(bytes) metrics-server-db745fcd5-v8gv6 3m 12Mi web-555db5bf6b-f7btr 0m 2Mi

Agora você tem um Metrics Server funcional e pode visualizar e monitorar o uso de recursos de pods em seu cluster. Em seguida, você irá configurar o HPA para monitorar esses dados e reagir a períodos de alto uso da CPU.

Passo 4 — Criando e Validando o Autoscaler Horizontal de Pod

Por fim, é hora de criar o Horizontal Pod Autoscaler (HPA) para seu deployment. O HPA é o objeto real do Kubernetes que verifica rotineiramente os dados de uso de CPU coletados do Metrics Server e escala seu deployment com base nos limites que você definiu no Passo 2.

Crie o HPA usando o comando kubectl autoscale:

  • kubectl autoscale deployment web --max=4 --cpu-percent=80

Este comando cria o HPA para seu deployment web. Ele também usa a flag --max para definir o máximo de réplicas nas quais web pode ser escalado, o que, neste caso, você define como 4.

A flag --cpu-percent informa ao HPA em qual porcentagem de uso do limite que você definiu no Passo 2 você deseja que o autoscale ocorra. Isso também usa os requests para ajudar a provisionar os pods escalados para um node que possa acomodar a alocação inicial de recursos. Neste exemplo, se o limite que você definiu para o seu deployment no Passo 1 fosse 100 milicores (100m), esse comando dispararia um autoscale assim que o pod atingisse 80m no uso médio da CPU. Isso permitiria que o deployment fosse escalado automaticamente antes de estourar seus recursos de CPU.

Agora que seu deployment pode ser escalado automaticamente, é hora de testar isso.

Para validar, você irá gerar uma carga que colocará seu cluster acima do seu limite e assistirá o autoscaler assumir o controle. Para começar, abra um segundo terminal para observar os pods provisionados no momento e atualizar a lista de pods a cada 2 segundos. Para fazer isso, use o comando watch neste segundo terminal:

  • watch "kubectl top pods"

O comando watch emite o comando dado como argumento continuamente, exibindo a saída no seu terminal. A duração entre repetições pode ser configurada mais finamente com a flag -n. Para os fins deste tutorial, a configuração padrão de dois segundos será suficiente.

O terminal agora exibirá a saída do kubectl top pods inicialmente e, a cada 2 segundos, atualizará a saída que esse comando gera, que será semelhante a esta:

Output
Every 2.0s: kubectl top pods NAME CPU(cores) MEMORY(bytes) metrics-server-6fd5457684-7kqtz 3m 15Mi web-7476bb659d-q5bjv 0m 2Mi

Anote o número de pods atualmente deployados para o web.

Volte ao seu terminal original. Agora você abrirá um terminal dentro do seu pod web atual usando kubectl exec e criará uma carga artificial. Você pode fazer isso entrando no pod e instalando o stress CLI tool.

Digite seu pod usando kubectl exec, substituindo o nome do pod realçado pelo nome do seu pod web:

  • kubectl exec -it web-f765fd676-s9729 /bin/bash

Este comando é muito semelhante em conceito ao de usar ssh para efetuar login em outra máquina. O /bin/bash estabelece um shell bash no seu pod.

Em seguida, no shell bash dentro do seu pod, atualize os metadados do repositório e instale o pacote stress.

  • apt update; apt-get install -y stress

Nota: Para containers baseados no CentOS, isso seria assim:

  • yum install -y stress

Em seguida, gere alguma carga de CPU no seu pod usando o comando stress e deixe-o executar:

  • stress -c 3

Agora, volte ao seu comando watch no segundo terminal. Aguarde alguns minutos para o Metrics Server reunir dados de CPU acima do limite definido pelo HPA. Observe que as métricas por padrão são coletadas na taxa que você definir como --metric-resolution ao configurar o metrics server. Pode demorar um minuto para que as métricas de uso sejam atualizadas.

Após cerca de dois minutos, você verá pods adicionais web subindo:

Output
Every 2.0s: kubectl top pods NAME CPU(cores) MEMORY(bytes) metrics-server-db745fcd5-v8gv6 6m 16Mi web-555db5bf6b-ck98q 0m 2Mi web-555db5bf6b-f7btr 494m 21Mi web-555db5bf6b-h5cbx 0m 1Mi web-555db5bf6b-pvh9f 0m 2Mi

Agora você pode ver que o HPA provisionou novos pods com base na carga de CPU coletada pelo Metrics Server. Quando estiver satisfeito com esta validação, use CTRL+C para interromper o comando stress no seu primeiro terminal e então, saia do shell bash do seu pod.

Conclusão

Neste artigo, você criou um deployment que será escalado automaticamente com base na carga de CPU. Você adicionou limites de recursos e solicitações de CPU ao seu deployment, instalou e configurou o Metrics Server em seu cluster por meio do uso do Helm e criou um HPA para tomar decisões de escalabilidade.

Esse foi um deployment de demonstração tanto do Metrics Server quanto do HPA. Agora você pode ajustar a configuração para se adequar aos seus casos de uso específicos. Certifique-se de verificar a documentação do Kubernetes HPA para ajuda e informação sobre requests e limits. Além disso, confira o Projeto Metrics Server para ver todas as configurações ajustáveis que podem ser aplicadas ao seu caso de uso.

Se você gostaria de fazer mais com o Kubernetes, visite nossa Página da Comunidade Kubernetes ou explore nosso Serviço Gerenciado de Kubernetes.

0 Comments

Creative Commons License