One place for hosting & domains

      Kubernetes

      Como gerenciar a infraestrutura DigitalOcean e o Kubernetes com o Pulumi


      O autor escolheu a Diversity in Tech Fund para receber uma doação como parte do programa Write for DOnations.

      Introdução

      O Pulumi é uma ferramenta para criar, implantar e gerenciar infraestrutura usando código escrito em linguagens de programação de uso geral. Ele suporta a automação de todos os serviços gerenciados da DigitalOcean, como Droplets, bancos de dados gerenciados, registros DNS e clusters Kubernetes, além da configuração de aplicações. Os deployments são realizados a partir de uma interface de linha de comando fácil de usar que também se integra a uma ampla variedade de sistemas populares de CI/CD.

      O Pulumi suporta várias linguagens, mas neste tutorial você usará TypeScript, uma versão de tipagem estática do JavaScript que utiliza o runtime Node.js. Isso significa que você obterá suporte a IDE e checagem em tempo de compilação que o ajudarão a garantir que você configurou os recursos certos, usou slugs corretos etc., enquanto continua podendo acessar qualquer módulo NPM para tarefas utilitárias.

      Neste tutorial, você provisionará um cluster Kubernetes na DigitalOcean, uma aplicação Kubernetes com balanceamento de carga e um domínio DNS da DigitalOcean que disponibiliza seu aplicativo em um nome de domínio estável de sua escolha. Tudo isso pode ser provisionado em 60 linhas de infraestrutura como código e em uma única execução de linha de comando pulumi up. Após este tutorial, você estará pronto para criar com produtividade, arquiteturas poderosas de nuvem usando a infraestrutura como código do Pulumi que aproveita toda a área de serviços DigitalOcean e Kubernetes.

      Pré-requisitos

      Para seguir este tutorial, você precisará de:

      • Uma conta na DigitalOcean na qual fazer o deployment dos recursos. Se você ainda não possui uma, cadastre-se aqui.
      • Um token de API da DigitalOcean para executar deployments automatizados. Gere um token de acesso pessoal aqui e mantenha-o à mão, pois você o usará no Passo 2.
      • Como você criará e usará um cluster Kubernetes, precisará instalar o kubectl. Não se preocupe em configurá-lo ainda, pois você fará isso mais tarde.
      • Você escreverá sua infraestrutura como código no TypeScript e precisará do Node.js 8 ou posterior. Faça o download aqui ou instale-o usando o gerenciador de pacotes do seu sistema.
      • Você usará o Pulumi para fazer o deploy da infraestrutura, por isso precisará instalar o SDK do Pulumi open source.
      • Para executar o Passo 5 opcional, você precisará de um nome de domínio configurado para usar os servidores de nomes da DigitalOcean. Este guia explica como fazer isso para o registrador de sua escolha.

      Passo 1 — Estruturando um Novo Projeto

      O primeiro passo é criar um diretório que irá armazenar seu projeto Pulumi. Esse diretório conterá o código-fonte para suas definições de infraestrutura, além dos arquivos de metadados que descrevem o projeto e suas dependências NPM.

      Primeiro, crie o diretório:

      Em seguida, vá para o diretório recém-criado:

      A partir de agora, execute comandos a partir do seu diretório do-k8s recém-criado.

      Em seguida, crie um novo projeto Pulumi. Existem diferentes maneiras de fazer isso, mas a maneira mais fácil é usar o comando pulumi new com o modelo de projeto typescript. Este comando primeiro solicitará que você efetue login no Pulumi para que seu projeto e o estado do deployment sejam salvos e, em seguida, criará um projeto TypeScript simples no diretório atual:

      Aqui você passou a opção -y para o comando new, que diz a ele para aceitar as opções padrão do projeto. Por exemplo, o nome do projeto é retirado do nome do diretório atual e, portanto, será do-k8s. Se você quiser usar opções diferentes para o nome do seu projeto, simplesmente elimine o -y.

      Após executar o comando, liste o conteúdo do diretório com ls:

      Os seguintes arquivos estarão agora presentes:

      Output

      Pulumi.yaml index.ts node_modules package-lock.json package.json tsconfig.json

      O arquivo principal que você estará editando é index.ts. Embora este tutorial use apenas esse arquivo único, você pode organizar seu projeto da maneira que achar melhor usando os módulos Node.js. Este tutorial também descreve uma etapa de cada vez, aproveitando o fato de que o Pulumi pode detectar e deployar de forma incremental apenas o que mudou. Se preferir, você pode simplesmente preencher o programa inteiro e fazer o deploy de uma só vez usando o pulumi up.

      Agora que você estruturou seu novo projeto, está pronto para adicionar as dependências necessárias para seguir o tutorial.

      Passo 2 — Adicionando Dependências

      O próximo passo é instalar e adicionar dependências nos pacotes DigitalOcean e Kubernetes. Primeiro, instale-os usando o NPM:

      Isso fará o download dos pacotes NPM, plug-ins do Pulumi e os salvará como dependências.

      Em seguida, abra o arquivo index.ts com seu editor favorito. Este tutorial usará o nano:

      Substitua o conteúdo do seu index.ts pelo seguinte:

      index.ts

      import * as digitalocean from "@pulumi/digitalocean";
      import * as kubernetes from "@pulumi/kubernetes";
      

      Isso disponibiliza todo o conteúdo desses pacotes para o seu programa. Se você digitar "digitalocean." usando um IDE que entenda TypeScript e Node.js, você deverá ver uma lista dos recursos da DigitalOcean suportados por este pacote, por exemplo.

      Salve e feche o arquivo após adicionar o conteúdo.

      Nota: Usaremos um subconjunto do que está disponível nesses pacotes. Para obter a documentação completa dos recursos, propriedades e APIs associadas, consulte a documentação relevante da API para os pacotes @pulumi/digitalocean e @pulumi/kubernetes.

      Em seguida, você configurará seu token DigitalOcean para que o Pulumi possa provisionar recursos em sua conta:

      • pulumi config set digitalocean:token SEU_TOKEN_AQUI --secret

      Observe a flag --secret, que usa o serviço de criptografia do Pulumi para criptografar seu token, garantindo que ele seja armazenado em texto cifrado. Se preferir, você pode usar a variável de ambiente DIGITALOCEAN_TOKEN, mas você vai precisar lembrar-se de defini-la sempre que atualizar seu programa, enquanto o uso da configuração armazena e o utiliza automaticamente para o seu projeto.

      Nesta etapa, você adicionou as dependências necessárias e configurou seu token de API com o Pulumi para poder provisionar seu cluster Kubernetes.

      Passo 3 — Provisionando um Cluster Kubernetes

      Agora você está pronto para criar um cluster Kubernetes na DigitalOcean. Comece reabrindo o arquivo index.ts:

      Adicione estas linhas no final do seu arquivo index.ts:

      index.ts

      ...
      const cluster = new digitalocean.KubernetesCluster("do-cluster", {
          region: digitalocean.Regions.SFO2,
          version: "latest",
          nodePool: {
              name: "default",
              size: digitalocean.DropletSlugs.DropletS2VPCU2GB,
              nodeCount: 3,
          },
      });
      
      export const kubeconfig = cluster.kubeConfigs[0].rawConfig;
      

      Este novo código aloca uma instância do digitalocean.KubernetesCluster e define várias propriedades nele. Isso inclui o uso da sfo2 como slug da região, a versão mais recente, latest, do Kubernetes, o s-2vcpu-2gb slug de tamanho do Droplet, e indica a contagem desejada de três instâncias do Droplet. Sinta-se à vontade para alterar qualquer uma dessas opções, mas lembre-se de que o Kubernetes da DigitalOcean está disponível apenas em determinadas regiões no momento em que este artigo foi escrito. Você pode consultar a documentação do produto para obter informações atualizadas sobre a disponibilidade da região.

      Para obter uma lista completa das propriedades que você pode configurar no seu cluster, consulte a documentação da API do KubernetesCluster.

      A linha final nesse trecho de código exporta o aqruivo kubeconfig resultante do cluster Kubernetes para que seja fácil de usar. As variáveis exportadas são impressas no console e também acessíveis às ferramentas. Você usará isso momentaneamente para acessar nosso cluster a partir de ferramentas padrão como o kubectl.

      Agora você está pronto para implantar seu cluster. Para fazer isso, execute pulumi up:

      Este comando pega o programa, gera um plano para criar a infraestrutura descrita e executa uma série de etapas para deployar essas alterações. Isso funciona para a criação inicial da infraestrutura, além de poder diferenciar e atualizar sua infraestrutura quando as atualizações subsequentes são feitas. Nesse caso, a saída será mais ou menos assim:

      Output

      Previewing update (dev): Type Name Plan + pulumi:pulumi:Stack do-k8s-dev create + └─ digitalocean:index:KubernetesCluster do-cluster create Resources: + 2 to create Do you want to perform this update? yes > no details

      Isso indica que prosseguindo com a atualização será criado um único cluster Kubernetes chamado do-cluster. O prompt yes/no/details permite confirmar que este é o resultado desejado antes que quaisquer alterações sejam realmente feitas. Se você selecionar details, uma lista completa de recursos e suas propriedades serão mostrados. Escolha yes para iniciar o deployment:

      Output

      Updating (dev): Type Name Status + pulumi:pulumi:Stack do-k8s-dev created + └─ digitalocean:index:KubernetesCluster do-cluster created Outputs: kubeconfig: "..." Resources: + 2 created Duration: 6m5s Permalink: https://app.pulumi.com/.../do-k8s/dev/updates/1

      Leva alguns minutos para criar o cluster, mas depois ele estará em funcionamento e o kubeconfig completo será impresso no console. Salve o kubeconfig em um arquivo:

      • pulumi stack output kubeconfig > kubeconfig.yml

      E então use-o com o kubectl para executar qualquer comando do Kubernetes:

      • KUBECONFIG=./kubeconfig.yml kubectl get nodes

      Você receberá uma saída semelhante à seguinte:

      Output

      NAME STATUS ROLES AGE VERSION default-o4sj Ready <none> 4m5s v1.14.2 default-o4so Ready <none> 4m3s v1.14.2 default-o4sx Ready <none> 3m37s v1.14.2

      Nesse ponto, você configurou a infraestrutura como código e tem uma maneira repetível de ativar e configurar novos clusters Kubernetes na DigitalOcean . No próximo passo, você trabalhará em cima disso para definir a infraestrutura do Kubernetes no código e aprender como fazer o deploy e gerenciá-la da mesma forma.

      Passo 4 — Fazendo o Deploy de uma Aplicação no seu Cluster

      A seguir, você descreverá a configuração de uma aplicação Kubernetes usando infraestrutura como código. Isso consistirá em três partes:

      1. Um objeto Provider, que diz ao Pulumi para deployar recursos do Kubernetes no cluster da DigitalOcean, em vez do padrão que qualquer kubectl esteja configurado para usar.
      2. Um Deployment de Kubernetes, que é a maneira padrão do Kubernetes de deployar uma imagem de container Docker que é replicada em qualquer número de Pods.
      3. Um Serviço Kubernetes, que é a maneira padrão para dizer ao Kubernetes para balancear o acesso entre um conjunto alvo de Pods (neste caso, o Deployment acima).

      Essa é uma arquitetura de referência razoavelmente padrão para iniciar e executar um serviço com balanceamento de carga no Kubernetes.

      Para implantar todos os três, abra o arquivo index.ts novamente:

      Depois de abrir o arquivo, acrescente este código ao final dele:

      index.ts

      ...
      const provider = new kubernetes.Provider("do-k8s", { kubeconfig })
      
      const appLabels = { "app": "app-nginx" };
      const app = new kubernetes.apps.v1.Deployment("do-app-dep", {
          spec: {
              selector: { matchLabels: appLabels },
              replicas: 5,
              template: {
                  metadata: { labels: appLabels },
                  spec: {
                      containers: [{
                          name: "nginx",
                          image: "nginx",
                      }],
                  },
              },
          },
      }, { provider });
      const appService = new kubernetes.core.v1.Service("do-app-svc", {
          spec: {
              type: "LoadBalancer",
              selector: app.spec.template.metadata.labels,
              ports: [{ port: 80 }],
          },
      }, { provider });
      
      export const ingressIp = appService.status.loadBalancer.ingress[0].ip;
      

      Esse código é semelhante à configuração padrão do Kubernetes, e o comportamento dos objetos e suas propriedades é equivalente, exceto que ele está escrito em TypeScript ao lado de suas outras declarações de infraestrutura.

      Salve e feche o arquivo depois de fazer as alterações.

      Assim como antes, execute pulumi up para visualizar e deployar as alterações:

      Depois de selecionar yes para prosseguir, a CLI imprimirá atualizações de status detalhadas, incluindo diagnósticos sobre disponibilidade de Pod, alocação de endereço IP e muito mais. Isso ajudará você a entender por que seu deployment pode levar algum tempo para ser concluído ou ficar travado.

      A saída completa será mais ou menos assim:

      Output

      Updating (dev): Type Name Status pulumi:pulumi:Stack do-k8s-dev + ├─ pulumi:providers:kubernetes do-k8s created + ├─ kubernetes:apps:Deployment do-app-dep created + └─ kubernetes:core:Service do-app-svc created Outputs: + ingressIp : "157.230.199.202" Resources: + 3 created 2 unchanged Duration: 2m52s Permalink: https://app.pulumi.com/.../do-k8s/dev/updates/2

      Após a conclusão, observe que o número desejado de Pods está em execução:

      • KUBECONFIG=./kubeconfig.yml kubectl get pods

      Output

      NAME READY STATUS RESTARTS AGE do-app-dep-vyf8k78z-758486ff68-5z8hk 1/1 Running 0 1m do-app-dep-vyf8k78z-758486ff68-8982s 1/1 Running 0 1m do-app-dep-vyf8k78z-758486ff68-94k7b 1/1 Running 0 1m do-app-dep-vyf8k78z-758486ff68-cqm4c 1/1 Running 0 1m do-app-dep-vyf8k78z-758486ff68-lx2d7 1/1 Running 0 1m

      Similar à maneira como o programa exporta o arquivo kubeconfig do cluster, este programa também exporta o endereço IP do balanceador de carga resultante do serviço Kubernetes. Use isto para fazer um curl no endpoint e verifique se ele está funcionando:

      • curl $(pulumi stack output ingressIp)

      Output

      <!DOCTYPE html> <html> <head> <title>Welcome to nginx!</title> <style> body { width: 35em; margin: 0 auto; font-family: Tahoma, Verdana, Arial, sans-serif; } </style> </head> <body> <h1>Welcome to nginx!</h1> <p>If you see this page, the nginx web server is successfully installed and working. Further configuration is required.</p> <p>For online documentation and support please refer to <a href="http://nginx.org/">nginx.org</a>.<br/> Commercial support is available at <a href="http://nginx.com/">nginx.com</a>.</p> <p><em>Thank you for using nginx.</em></p> </body> </html>

      A partir daqui, você pode editar e re-deployar facilmente sua infraestrutura de aplicações. Por exemplo, tente alterar a linha replicas: 5 para digamos replicas: 7 e, em seguida, execute novamente pulumi up:

      Observe que ele apenas mostra o que mudou e que ao selecionar detalhes, exibe a diferença precisa:

      Output

      Previewing update (dev): Type Name Plan Info pulumi:pulumi:Stack do-k8s-dev ~ └─ kubernetes:apps:Deployment do-app-dep update [diff: ~spec] Resources: ~ 1 to update 4 unchanged Do you want to perform this update? details pulumi:pulumi:Stack: (same) [urn=urn:pulumi:dev::do-k8s::pulumi:pulumi:Stack::do-k8s-dev] ~ kubernetes:apps/v1:Deployment: (update) [id=default/do-app-dep-vyf8k78z] [urn=urn:pulumi:dev::do-k8s::kubernetes:apps/v1:Deployment::do-app-dep] [provider=urn:pulumi:dev::do-k8s::pulumi:providers:kubernetes::do-k8s::80f36105-337f-451f-a191-5835823df9be] ~ spec: { ~ replicas: 5 => 7 }

      Agora você tem um cluster Kubernetes em plena operação e uma aplicação em funcionamento. Com a aplicação em funcionamento, você pode querer configurar um domínio personalizado para usar com ela. O próximo passo o guiará na configuração do DNS com o Pulumi.

      Passo 5 — Criando um Domínio DNS (Opcional)

      Embora o cluster e a aplicação Kubernetes estejam em funcionamento, o endereço da aplicação é dependente dos caprichos da atribuição automática de endereços IP pelo seu cluster. Conforme você ajusta e reimplementa as coisas, esse endereço pode mudar. Neste passo, você verá como atribuir um nome DNS personalizado ao endereço IP do balanceador de carga, para que fique estável, mesmo que você altere sua infraestrutura posteriormente.

      Nota: Para concluir este passo, garanta que você possui um domínio usando os servidores de nomes DNS da DigitalOcean, ns1.digitalocean.com, ns2.digitalocean.com e ns3.digitalocean.com. Instruções para configurar isso estão disponíveis na seção Pré-requisitos.

      Para configurar o DNS, abra o arquivo index.ts e acrescente o seguinte código ao final do arquivo:

      index.ts

      ...
      const domain = new digitalocean.Domain("do-domain", {
          name: "seu_domínio",
          ipAddress: ingressIp,
      });
      

      Este código cria uma nova entrada DNS com um registro A que se refere ao endereço IP do seu serviço Kubernetes. Substitua seu_domínio neste trecho pelo nome de domínio escolhido.

      É comum querer subdomínios adicionais, como www, apontando para a aplicação web. É fácil conseguir isso usando um registro DNS da DigitalOcean. Para tornar este exemplo mais interessante, adicione também um registro CNAME que aponte www.seu_domínio.com para seu_domínio.com:

      index.ts

      ...
      const cnameRecord = new digitalocean.DnsRecord("do-domain-cname", {
          domain: domain.name,
          type: "CNAME",
          name: "www",
          value: "@",
      });
      

      Salve e feche o arquivo depois de fazer essas alterações.

      Por fim, execute pulumi up para fazer o deploy das alterações no DNS para apontar para a aplicação e o cluster existentes:

      Output

      Updating (dev): Type Name Status pulumi:pulumi:Stack do-k8s-dev + ├─ digitalocean:index:Domain do-domain created + └─ digitalocean:index:DnsRecord do-domain-cname created Resources: + 2 created 5 unchanged Duration: 6s Permalink: https://app.pulumi.com/.../do-k8s/dev/updates/3

      Após a propagação das alterações no DNS, você poderá acessar seu conteúdo em seu domínio personalizado:

      • curl www.seu_domínio.com

      Você receberá uma saída semelhante à seguinte:

      Output

      <!DOCTYPE html> <html> <head> <title>Welcome to nginx!</title> <style> body { width: 35em; margin: 0 auto; font-family: Tahoma, Verdana, Arial, sans-serif; } </style> </head> <body> <h1>Welcome to nginx!</h1> <p>If you see this page, the nginx web server is successfully installed and working. Further configuration is required.</p> <p>For online documentation and support please refer to <a href="http://nginx.org/">nginx.org</a>.<br/> Commercial support is available at <a href="http://nginx.com/">nginx.com</a>.</p> <p><em>Thank you for using nginx.</em></p> </body> </html>

      Com isso, você configurou com êxito um novo cluster Kubernetes na DigitalOcean, fez o deploy de uma aplicação Kubernetes com balanceamento de carga e deu ao balanceador de carga dessa aplicação um nome de domínio estável usando o DNS da DigitalOcean, tudo em 60 linhas de código e um comando pulumi up .

      A próximo passo o guiará na remoção dos recursos, se você não precisar mais deles.

      Passo 6 — Removendo os Recursos (Opcional)

      Antes de concluir o tutorial, você pode querer destruir todos os recursos criados acima. Isso garantirá que você não seja cobrado pelos recursos que não estão sendo usados. Se você preferir manter sua aplicação em funcionamento, fique à vontade para pular esta etapa.

      Execute o seguinte comando para destruir os recursos. Cuidado ao usar isso, pois não pode ser desfeito!

      Assim como no comando up, destroy exibe uma visualização e um prompt antes de executar uma ação:

      Output

      Previewing destroy (dev): Type Name Plan - pulumi:pulumi:Stack do-k8s-dev delete - ├─ digitalocean:index:DnsRecord do-domain-cname delete - ├─ digitalocean:index:Domain do-domain delete - ├─ kubernetes:core:Service do-app-svc delete - ├─ kubernetes:apps:Deployment do-app-dep delete - ├─ pulumi:providers:kubernetes do-k8s delete - └─ digitalocean:index:KubernetesCluster do-cluster delete Resources: - 7 to delete Do you want to perform this destroy? yes > no details

      Supondo que é isso que você deseja, selecione yes e observe as exclusões:

      Output

      Destroying (dev): Type Name Status - pulumi:pulumi:Stack do-k8s-dev deleted - ├─ digitalocean:index:DnsRecord do-domain-cname deleted - ├─ digitalocean:index:Domain do-domain deleted - ├─ kubernetes:core:Service do-app-svc deleted - ├─ kubernetes:apps:Deployment do-app-dep deleted - ├─ pulumi:providers:kubernetes do-k8s deleted - └─ digitalocean:index:KubernetesCluster do-cluster deleted Resources: - 7 deleted Duration: 7s Permalink: https://app.pulumi.com/.../do-k8s/dev/updates/4

      Nesse momento, nada mais resta: as entradas de DNS desaparecem e o cluster Kubernetes — juntamente com a aplicação em execução nele — também desaparece. O link permanente, permalink, ainda está disponível, para que você possa voltar e ver o histórico completo de atualizações para essa pilha. Isso pode ajudá-lo a se recuperar se a destruição for um erro, uma vez que o serviço mantém um histórico completo do estado de todos os recursos.

      Se você gostaria de destruir o seu projeto na sua totalidade, remova a pilha:

      Você receberá uma saída pedindo para confirmar a exclusão digitando o nome da pilha:

      Output

      This will permanently remove the 'dev' stack! Please confirm that this is what you'd like to do by typing ("dev"):

      Ao contrário do comando destroy, que exclui os recursos de infraestrutura em nuvem, a remoção de uma pilha apaga totalmente o histórico completo da sua pilha do alcance do Pulumi.

      Conclusão

      Neste tutorial, você fez o deploy dos recursos de infraestrutura na DigitalOcean — um cluster Kubernetes e um domínio DNS com registros A e CNAME — além da configuração da aplicação Kubernetes que usa esse cluster. Você fez isso usando infraestrutura como código escrita em uma linguagem de programação familiar, TypeScript, que trabalha com editores, ferramentas e bibliotecas existentes e aproveita as comunidades e pacotes existentes. Você fez tudo isso usando um único fluxo de trabalho de linha de comando para realizar deployments que abrangem sua aplicação e a infraestrutura.

      A partir daqui, há uma série de próximos passos que você pode dar:

      O exemplo completo deste tutorial está disponível no GitHub. Para obter maiores detalhes sobre como usar a infraestrutura como código do Pulumi em seus próprios projetos hoje, consulte a Documentação do Pulumi, Tutorials, ou os guias Getting Started. O Pulumi é open source e é livre para usar.



      Source link

      Getting Started with Containers and Kubernetes: A DigitalOcean Meetup Kit


      Getting Started with Containers and Kubernetes Meetup Kit Materials

      This meetup kit is designed to help a technical audience become familiar with core Kubernetes concepts and practices.

      The aim is to provide a complete set of resources for a speaker to host an event and deliver an introductory talk on containers and Kubernetes. It includes:

      This tutorial is intended to supplement the talk demo with additional detail and elucidation. It also serves as a reference for readers seeking to get a minimal containerized Flask app up and running on DigitalOcean Kubernetes.

      Introduction

      In the past decade, containerized applications and container clusters have rapidly replaced the old paradigm of scaling applications using virtual machines. Containers offer the same process isolation, but are generally more lightweight, portable, and performant than full virtualization. Container clusters, which can be used to manage thousands of running containers across a set of physical machines, abstract away much of the work of rolling out new versions of applications, scaling them, and efficiently scheduling workloads. Out of these, Kubernetes has emerged as a mature, production-ready system. It provides a rich set of features like rolling deployments, health checking, self-monitoring, workload autoscaling, and much, much more.

      This tutorial, designed to accompany the Slides and speaker notes for the Getting Started with Kubernetes Meetup Kit, will show you how to harness these technologies and deploy the “Hello World” Flask app onto a DigitalOcean Kubernetes cluster.

      Prerequisites

      To follow this tutorial, you will need:

      • A Kubernetes 1.10+ cluster with role-based access control (RBAC) enabled. This setup will use a DigitalOcean Kubernetes cluster
      • The kubectl command-line tool installed on your local machine or development server and configured to connect to your cluster. You can read more about installing kubectl in the official documentation.
      • Docker installed on your local machine or development server. If you are working with Ubuntu 18.04, follow Steps 1 and 2 of How To Install and Use Docker on Ubuntu 18.04; otherwise, follow the official documentation for information about installing on other operating systems. Be sure to add your non-root user to the docker group, as described in Step 2 of the linked tutorial.
      • A Docker Hub account (optional). For an overview of how to set this up, refer to this introduction to Docker Hub. You’ll only need a Docker Hub account if you plan on modifying the Flask Docker image described in this tutorial.

      Step 1 — Cloning the App Repository and Building the Flask Image

      To begin, clone the demo Flask app repo onto your machine, navigate into the directory, and list the directory contents:

      • git clone https://github.com/do-community/k8s-intro-meetup-kit.git
      • cd k8s-intro-meetup-kit
      • ls

      Output

      LICENSE README.md app k8s

      The app directory contains the Flask demo app code, as well as the Dockerfile for building its container image. The k8s directory contains Kubernetes manifest files for a Pod, Deployment, and Service. To learn more about these Kubernetes objects, consult the slide deck or An Introduction to Kubernetes.

      Navigate into the app directory and print out the contents of the app.py file:

      Output

      from flask import Flask app = Flask(__name__) @app.route('/') def hello_world(): return 'Hello, World!' if __name__ == "__main__": app.run(debug=True, host='0.0.0.0')

      This code defines a single default route that will print “Hello World.” Additionally, the apps runs in debug mode to enable verbose output.

      In a similar fashion, cat out the contents of the app’s Dockerfile:

      Output

      FROM python:3-alpine WORKDIR /app COPY requirements.txt . RUN pip install -r requirements.txt COPY . . EXPOSE 5000 CMD ["python", "app.py"]

      This Dockerfile first sources a lightweight Alpine Linux Python parent image. It then copies in the Python requirements file, installs Flask, copies the app code into the container image, defines port 5000 as the container port, and finally sets the default command to python app.py.

      Next, build the app image:

      • cd app
      • docker build -t flask_demo:v0 .

      We give the image a name, flask_demo, and tag, v0 using the -t option.

      After Docker finishes the build, run the container using run:

      • docker run -p 5000:5000 flask:v0

      This command runs a container using the flask:v0 image, and forwards local port 5000 to container port 5000.

      If you’re running Docker on your local machine, navigate to http://localhost:5000 in your web browser. You should see “Hello World,” generated by the dockerized Flask app.

      If you’re running Docker on a dev server, navigate instead to http://dev_server_external_IP:5000. If you’re running a firewall like UFW, be sure to allow external access on port 5000. To learn more about doing this with UFW, consult UFW Essentials: Common Firewall Rules and Commands.

      At this point you can experiment with Docker commands like docker ps, docker top, and docker images to practice working with images and containers on your system.

      In the next step, we’ll deploy this demo app to your Kubernetes cluster. We’ll use a prebuilt image shared publicly on Docker Hub. If you’d like to customize the Flask app and use your own image, you should create a Docker Hub account and follow the steps in this introduction to push your image to a public repository. From there, Kubernetes will be able to pull and deploy the container image into your cluster.

      Step 2 — Deploying the Flask App on Kubernetes

      The app and Docker image described in the previous step have already been built and made publicly available in the flask-helloworld Docker Hub repository. You can optionally create your own repository for the app and substitute it for flask-helloworld throughout this step.

      We’ll first deploy this demo “Hello World” app into our cluster as a standalone Pod, then as a multi-pod Deployment, which we’ll finally expose as a LoadBalancer Service. At the end of this tutorial, the “Hello World” app will be publicly accessible from outside of the Kubernetes cluster.

      Before we launch any workloads into the cluster, we’ll create a Namespace in which the objects will run. Namespaces allow you to segment your cluster and limit scope for running workloads.

      Create a Namespace called flask:

      • kubectl create namespace flask

      Now, list all the Namespaces in your cluster:

      You should see your new Namespace as well as some default Namespaces like kube-system and default. In this tutorial, we are going to exclusively work within the flask Namespace.

      Navigate back out to the k8s directory in the demo repo:

      In this directory, you’ll see three Kubernetes manifest files:

      • flask-pod.yaml: The app Pod manifest
      • flask-deployment.yaml: The app Deployment manifest
      • flask-service.yaml: The app LoadBalancer Service manifest

      Let’s take a look at the Pod manifest:

      Output

      apiVersion: v1 kind: Pod metadata: name: flask-pod labels: app: flask-helloworld spec: containers: - name: flask image: hjdo/flask-helloworld:latest ports: - containerPort: 5000

      Here, we define a minimal Pod called flask-pod and label it with the app: flask-helloworld key-value pair.

      We then name the single container flask and set the image to flask-helloworld:latest from the hjdo/flask-helloworld Docker Hub repository. If you’re using an image stored in a different Docker Hub repo, you can reference it using the image field here. Finally, we open up port 5000 to accept incoming connections.

      Deploy this Pod into the flask Namespace using kubectl apply -f and the -n Namespace flag:

      • kubectl apply -f flask-pod.yaml -n flask

      After ten or so seconds, the Pod should be up and running in your cluster:

      Output

      NAME READY STATUS RESTARTS AGE flask-pod 1/1 Running 0 4s

      Since this Pod is running inside of the Kubernetes cluster, we need to forward a local port to the Pod’s containerPort to access the running app locally:

      • kubectl port-forward pods/flask-pod -n flask 5000:5000

      Here we use port-forward to forward local port 5000 to the Pod’s containerPort 5000.

      Navigate to http://localhost:5000, where you should once again see the “Hello World” text generated by the Flask app. If you’re running kubectl on a remote dev server, replace localhost with your dev server’s external IP address.

      Feel free to play around with kubectl commands like kubectl describe to explore the Pod resource. When you’re done, delete the Pod using delete:

      • kubectl delete pod flask-pod -n flask

      Next, we’ll roll out this Pod in a scalable fashion using the Deployment resource. Print out the contents of the flask-deployment.yaml manifest file:

      • cat flask-deployment.yaml

      Output

      apiVersion: apps/v1 kind: Deployment metadata: name: flask-dep labels: app: flask-helloworld spec: replicas: 2 selector: matchLabels: app: flask-helloworld template: metadata: labels: app: flask-helloworld spec: containers: - name: flask image: hjdo/flask-helloworld:latest ports: - containerPort: 5000

      Here, we define a Deployment called flask-dep with an app: flask-helloworld Label. Next, we request 2 replicas of a Pod template identical to the template we previously used to deploy the Flask app Pod. The selector field matches the app: flask-helloworld Pod template to the Deployment.

      Roll out the Deployment using kubectl apply -f:

      • kubectl apply -f flask-deployment.yaml -n flask

      After a brief moment, the Deployment should be up and running in your cluster:

      • kubectl get deploy -n flask

      Output

      NAME READY UP-TO-DATE AVAILABLE AGE flask-dep 2/2 2 2 5s

      You can also pull up the individual Pods that are managed by the Deployment controller:

      Output

      NAME READY STATUS RESTARTS AGE flask-dep-876bd7677-bl4lg 1/1 Running 0 76s flask-dep-876bd7677-jbfpb 1/1 Running 0 76s

      To access the app, we have to forward a port inside of the cluster:

      • kubectl port-forward deployment/flask-dep -n flask 5000:5000

      This will forward local port 5000 to containerPort 5000 on one of the running Pods.

      You should be able to access the app at http://localhost:5000. If you’re running kubectl on a remote dev server, replace localhost with your dev server’s external IP address.

      At this point you can play around with commands like kubectl rollout and kubectl scale to experiment with rolling back Deployments and scaling them. To learn more about these and other kubectl commands, consult a kubectl Cheat Sheet.

      In the final step, we’ll expose this app to outside users using the LoadBalancer Service type, which will automatically provision a DigitalOcean cloud Load Balancer for the Flask app Service.

      Step 3 — Creating the App Service

      A Kubernetes Deployment allows the operator to flexibly scale a Pod template up or down, as well as manage rollouts and template updates. To create a stable network endpoint for this set of running Pod replicas, you can create a Kubernetes Service, which we’ll do here.

      Begin by inspecting the Service manifest file:

      Output

      apiVersion: v1 kind: Service metadata: name: flask-svc labels: app: flask-helloworld spec: type: LoadBalancer ports: - port: 80 targetPort: 5000 protocol: TCP selector: app: flask-helloworld

      This manifest defines a Service called flask-svc. We set the type to LoadBalancer to provision a DigitalOcean cloud Load Balancer that will route traffic to the Deployment Pods. To select the already running Deployment, the selector field is set to the Deployment’s app: flask-helloworld Label. Finally, we open up port 80 on the Load Balancer and instruct it to route traffic to the Pods’ containerPort 5000.

      To create the Service, use kubectl apply -f:

      • kubectl apply -f flask-service.yaml -n flask

      It may take a bit of time for Kubernetes to provision the cloud Load Balancer. You can track progress using the -w watch flag:

      Once you see an external IP for the flask-svc Service, navigate to it using your web browser. You should see the “Hello World” Flask app page.

      Conclusion

      This brief tutorial demonstrates how to containerize a minimal Flask app and deploy it to a Kubernetes cluster. It accompanies the meetup kit’s slides and speaker notes and GitHub repository.



      Source link

      Como Escalar Automaticamente suas Cargas de Trabalho no Kubernetes da DigitalOcean


      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:

      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:

      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:

      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:

      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:

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

      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.



      Source link