O que é Kubernetes? Um guia para conteinerização e implantação

Publicados: 2022-03-11

Há pouco tempo, usávamos a aplicação web monolith: enormes bases de código que cresceram em novas funções e recursos até se transformarem em gigantes enormes, lentos e difíceis de gerenciar. Agora, um número crescente de desenvolvedores, arquitetos e especialistas em DevOps estão chegando à opinião de que é melhor usar microsserviços do que um monólito gigante. Normalmente, usar uma arquitetura baseada em microsserviços significa dividir seu monólito em pelo menos dois aplicativos: o aplicativo de front-end e um aplicativo de back-end (a API). Após a decisão de usar microsserviços, surge uma pergunta: Em qual ambiente é melhor executar microsserviços? O que devo escolher para tornar meu serviço estável e fácil de gerenciar e implantar? A resposta curta é: Use o Docker!

Neste artigo, apresentarei os contêineres, explicarei o Kubernetes e ensinarei como conteinerizar e implantar um aplicativo em um cluster Kubernetes usando o CircleCI.

Docker? O que é Docker?

O Docker é uma ferramenta projetada para facilitar o DevOps (e sua vida). Com o Docker, um desenvolvedor pode criar, implantar e executar aplicativos em contêineres . Os contêineres permitem que um desenvolvedor empacote um aplicativo com todas as partes necessárias, como bibliotecas e outras dependências, e envie tudo como um pacote.

Comparando aplicativos implantados em um host versus um aplicativo empacotado em um contêiner

Comparando aplicativos implantados em um host versus um aplicativo empacotado em um contêiner

Usando contêineres, os desenvolvedores podem facilmente (re)implantar uma imagem em qualquer sistema operacional. Basta instalar o Docker, executar um comando e seu aplicativo estará funcionando. Ah, e não se preocupe com qualquer inconsistência com a nova versão das bibliotecas no sistema operacional host. Além disso, você pode iniciar mais contêineres no mesmo host - será o mesmo aplicativo ou outro? Não importa.

Parece que o Docker é uma ferramenta incrível. Mas como e onde devo lançar containers?

Há muitas opções de como e onde executar contêineres: AWS Elastic Container Service (AWS Fargate ou uma instância reservada com dimensionamento automático horizontal e vertical); uma instância de nuvem com imagem Docker predefinida no Azure ou Google Cloud (com modelos, grupos de instâncias e dimensionamento automático); em seu próprio servidor com o Docker; ou, claro, Kubernetes! O Kubernetes foi criado especialmente para virtualização e contêineres pelos engenheiros do Google em 2014.

Kubernetes? O que é aquilo?

O Kubernetes é um sistema de código aberto que permite executar contêineres, gerenciá-los, automatizar implantações, dimensionar implantações, criar e configurar entradas, implantar aplicativos sem estado ou com estado e muitas outras coisas. Basicamente, você pode iniciar uma ou mais instâncias e instalar o Kubernetes para operá-las como um cluster Kubernetes. Em seguida, obtenha o endpoint da API do cluster Kubernetes, configure kubectl (uma ferramenta para gerenciar clusters Kubernetes) e o Kubernetes está pronto para servir.

Então, por que devo usá-lo?

Com o Kubernetes, você pode utilizar ao máximo os recursos computacionais. Com o Kubernetes, você será o capitão do seu navio (infraestrutura) com o Kubernetes enchendo suas velas. Com o Kubernetes, seu serviço será HA. E o mais importante, com o Kubernetes, você economizará muito dinheiro.

Parece promissor! Especialmente se isso economizar dinheiro! Vamos falar mais sobre isso!

O Kubernetes está ganhando popularidade dia após dia. Vamos aprofundar e investigar o que está por baixo do capô.

Sob o capô: o que é Kubernetes?

O que é Kubernetes? Os componentes que compõem o Kubernetes sob o capô

Os componentes que compõem o Kubernetes

Kubernetes é o nome de todo o sistema, mas como seu carro, existem muitas pequenas peças que trabalham juntas em perfeita harmonia para fazer o Kubernetes funcionar. Vamos aprender quais são.

Master Node – Um painel de controle para todo o cluster Kubernetes. Os componentes do mestre podem ser executados em qualquer nó do cluster. Os principais componentes são:

  • Servidor API: O ponto de entrada para todos os comandos REST, o único componente do Master Node que pode ser acessado pelo usuário.
  • Datastore: armazenamento de chave-valor forte, consistente e altamente disponível usado pelo cluster Kubernetes.
  • Agendador: observa os pods recém-criados e os atribui aos nós. A implantação de pods e serviços nos nós acontece por causa do agendador.
  • Gerenciador de controlador: Executa todos os controladores que tratam de tarefas de rotina no cluster.
  • Nós de trabalho: Agente de nó primário, também chamado de nós de servo. Os pods são executados aqui. Os nós de trabalho contêm todos os serviços necessários para gerenciar a rede entre os contêineres, comunicar-se com o nó mestre e atribuir recursos aos contêineres agendados.
  • Docker: é executado em cada nó do trabalhador e faz download de imagens e contêineres iniciais.
  • Kubelet: monitora o estado de um pod e garante que os contêineres estejam funcionando. Ele também se comunica com o armazenamento de dados, obtendo informações sobre serviços e escrevendo detalhes sobre os recém-criados.
  • Kube-proxy: um proxy de rede e balanceador de carga para um serviço em um único nó do trabalhador. É responsável pelo roteamento de tráfego.
  • Kubectl: Uma ferramenta CLI para os usuários se comunicarem com o servidor da API Kubernetes.

O que são pods e serviços?

Pods são a menor unidade do cluster Kubernetes, é como um tijolo na parede de um enorme edifício. Um pod é um conjunto de contêineres que precisam ser executados juntos e podem compartilhar recursos (espaços de nomes Linux, cgroups, endereços IP). Pods não se destinam a viver muito.

Os serviços são uma abstração no topo de vários pods, normalmente exigindo um proxy no topo para que outros serviços se comuniquem com ele por meio de um endereço IP virtual.

Exemplo de implantação simples

Como diferentes partes interessadas interagem com um aplicativo com tecnologia Kubernetes

Como diferentes partes interessadas interagem com um aplicativo com tecnologia Kubernetes

Usarei um aplicativo Ruby on Rails simples e o GKE como plataforma para executar o Kubernetes. Na verdade, você pode usar o Kubernetes na AWS ou Azure ou até mesmo criar um cluster em seu próprio hardware ou executar o Kubernetes localmente usando minikube — todas as opções que você encontrará nesta página.

Os arquivos de origem para este aplicativo podem ser encontrados neste repositório do GitHub.

Para criar um novo aplicativo Rails, execute:

 rails new blog

Para configurar a conexão MySQL para produção no config/database.yml file :

 production: adapter: mysql2 encoding: utf8 pool: 5 port: 3306 database: <%= ENV['DATABASE_NAME'] %> host: 127.0.0.1 username: <%= ENV['DATABASE_USERNAME'] %> password: <%= ENV['DATABASE_PASSWORD'] %>

Para criar um modelo de artigo, controlador, visualizações e migração, execute:

 rails g scaffold Article title:string description:text

Para adicionar gems ao Gemfile:

 gem 'mysql2', '< 0.6.0', '>= 0.4.4' gem 'health_check'

Para criar a imagem do Docker, pegue meu Dockerfile e execute:

 docker build -t REPO_NAME/IMAGE_NAME:TAG . && docker push REPO_NAME/IMAGE_NAME:TAG

É hora de criar um cluster Kubernetes. Abra a página do GKE e crie o cluster Kubernetes. Quando o cluster for criado, clique no “botão Conectar” e copie o comando – certifique-se de ter a ferramenta gCloud CLI (como fazer) e o kubectl instalados e configurados. Execute o comando copiado em seu PC e verifique a conexão com o cluster Kubernetes; execute kubectl cluster-info .

O aplicativo está pronto para ser implantado no cluster k8s. Vamos criar um banco de dados MySQL. Abra a página SQL no console do gCloud e crie uma instância de banco de dados MySQL para o aplicativo. Quando a instância estiver pronta, crie o usuário e o banco de dados e copie o nome da conexão da instância .

Além disso, precisamos criar uma chave de conta de serviço na página API & Services para acessar um banco de dados MySQL de um contêiner sidecar. Você pode encontrar mais informações sobre esse processo aqui. Renomeie o arquivo baixado para service-account.json . Voltaremos mais tarde a esse arquivo.

Estamos prontos para implantar nosso aplicativo no Kubernetes, mas primeiro devemos criar segredos para nosso aplicativo - um objeto secreto no Kubernetes criado para armazenar dados confidenciais. Faça upload do arquivo service-account.json baixado anteriormente:

 kubectl create secret generic mysql-instance-credentials \ --from-file=credentials.json=service-account.json

Crie segredos para o aplicativo:

 kubectl create secret generic simple-app-secrets \ --from-literal=username=$MYSQL_PASSWORD \ --from-literal=password=$MYSQL_PASSWORD \ --from-literal=database-name=$MYSQL_DB_NAME \ --from-literal=secretkey=$SECRET_RAILS_KEY

Não se esqueça de substituir valores ou definir variáveis ​​de ambiente com seus valores.

Antes de criar uma implantação, vamos dar uma olhada no arquivo de implantação. Eu concatenei três arquivos em um; a primeira parte é um serviço que irá expor a porta 80 e encaminhar todas as conexões que chegam à porta 80 para a 3000. O serviço tem um seletor com o qual o serviço sabe para quais pods ele deve encaminhar as conexões.

A próxima parte do arquivo é a implantação, que descreve a estratégia de implantação — contêineres que serão lançados dentro do pod, variáveis ​​de ambiente, recursos, sondagens, montagens para cada contêiner e outras informações.

A última parte é o Horizontal Pod Autoscaler. HPA tem uma configuração bastante simples. Lembre-se de que, se você não definir recursos para o contêiner na seção de implantação, o HPA não funcionará.

Você pode configurar o autoescalador vertical para seu cluster Kubernetes na página de edição do GKE. Ele também tem uma configuração bastante simples.

É hora de enviá-lo para o cluster do GKE. Antes de tudo, devemos executar as migrações via job. Executar:

kubectl apply -f rake-tasks-job.yaml – Este trabalho será útil para o processo de CI/CD.

kubectl apply -f deployment.yaml – para criar serviço, implantação e HPA.

E, em seguida, verifique seu pod executando o comando: kubectl get pods -w

 NAME READY STATUS RESTARTS AGE sample-799bf9fd9c-86cqf 2/2 Running 0 1m sample-799bf9fd9c-887vv 2/2 Running 0 1m sample-799bf9fd9c-pkscp 2/2 Running 0 1m

Agora vamos criar uma entrada para o aplicativo:

  1. Crie um IP estático: gcloud compute addresses create sample-ip --global
  2. Crie a entrada (arquivo): kubectl apply -f ingress.yaml
  3. Verifique se o ingresso foi criado e pegue o IP: kubectl get ingress -w
  4. Crie o domínio/subdomínio para seu aplicativo.

CI/CD

Vamos criar um pipeline CI/CD usando CircleCI. Na verdade, é fácil criar um pipeline de CI/CD usando o CircleCI, mas lembre-se de que um processo de implantação totalmente automatizado rápido e sujo, sem testes como esse, funcionará para pequenos projetos, mas não faça isso para nada sério porque , se algum novo código tiver problemas na produção, você perderá dinheiro. É por isso que você deve pensar em projetar um processo de implantação robusto, iniciar tarefas canário antes da distribuição completa, verificar erros nos logs após o início do canário e assim por diante.

Atualmente, temos um projeto pequeno e simples, então vamos criar um processo de implantação de CI/CD totalmente automatizado e sem testes. Primeiro, você deve integrar o CircleCI ao seu repositório - você pode encontrar todas as instruções aqui. Então devemos criar um arquivo de configuração com instruções para o sistema CircleCI. A configuração parece bem simples. Os pontos principais são que existem duas ramificações no repositório do GitHub: master e production .

  1. O branch master é para desenvolvimento, para o código novo. Quando alguém envia um novo código para o branch master, o CircleCI inicia um fluxo de trabalho para o branch master—construir e testar o código.
  2. A ramificação de produção é para implantar uma nova versão no ambiente de produção. O fluxo de trabalho para a ramificação de produção é o seguinte: enviar novo código (ou melhor ainda, abrir PR da ramificação mestre para produção) para acionar um novo processo de compilação e implantação; durante a compilação, o CircleCI cria novas imagens do Docker, envia-as para o GCR e cria uma nova distribuição para a implantação; se a distribuição falhar, o CircleCI acionará o processo de reversão.

Antes de executar qualquer compilação, você deve configurar um projeto no CircleCI. Crie uma nova conta de serviço na API e uma página de Serviços no GCloud com estes papéis: acesso total ao GCR e GKE, abra o arquivo JSON baixado e copie o conteúdo, depois crie uma nova variável de ambiente nas configurações do projeto no CircleCI com o nome GCLOUD_SERVICE_KEY e cole o conteúdo do arquivo de conta de serviço como um valor. Além disso, você precisa criar as próximas variáveis ​​de ambiente: GOOGLE_PROJECT_ID (você pode encontrá-lo na página inicial do console do GCloud), GOOGLE_COMPUTE_ZONE (uma zona para seu cluster do GKE) e GOOGLE_CLUSTER_NAME (nome do cluster do GKE).

A última etapa (implantação) no CircleCI será semelhante a:

 kubectl patch deployment sample -p '{"spec":{"template":{"spec":{"containers":[{"name":"sample","image":"gcr.io/test-d6bf8/simple:'"$CIRCLE_SHA1"'"}]}}}}' if ! kubectl rollout status deploy/sample; then echo "DEPLOY FAILED, ROLLING BACK TO PREVIOUS" kubectl rollout undo deploy/sample # Deploy failed -> notify slack else echo "Deploy succeeded, current version: ${CIRCLE_SHA1}" # Deploy succeeded -> notify slack fi deployment.extensions/sample patched Waiting for deployment "sample" rollout to finish: 2 out of 3 new replicas have been updated... Waiting for deployment "sample" rollout to finish: 2 out of 3 new replicas have been updated... Waiting for deployment "sample" rollout to finish: 2 out of 3 new replicas have been updated... Waiting for deployment "sample" rollout to finish: 1 old replicas are pending termination... Waiting for deployment "sample" rollout to finish: 1 old replicas are pending termination... Waiting for deployment "sample" rollout to finish: 1 old replicas are pending termination... Waiting for deployment "sample" rollout to finish: 2 of 3 updated replicas are available... Waiting for deployment "sample" rollout to finish: 2 of 3 updated replicas are available... deployment "sample" successfully rolled out Deploy succeeded, current version: 512eabb11c463c5431a1af4ed0b9ebd23597edd9

Conclusão

Parece que o processo de criação de um novo cluster Kubernetes não é tão difícil! E o processo de CI/CD é realmente incrível!

Sim! Kubernetes é incrível! Com o Kubernetes, seu sistema será mais estável, facilmente gerenciável e fará de você o capitão do seu sistema. Sem falar que o Kubernetes gamifica um pouco o sistema e dará +100 pontos para o seu marketing!

Agora que você já sabe o básico, pode ir além e transformar isso em uma configuração mais avançada. Estou planejando cobrir mais em um artigo futuro, mas, enquanto isso, aqui está um desafio: crie um cluster Kubernetes robusto para seu aplicativo com um banco de dados com estado localizado dentro do cluster (incluindo Pod sidecar para fazer backups), instale o Jenkins dentro do mesmo cluster Kubernetes para o pipeline CI/CD e permitir que o Jenkins use pods como escravos para as compilações. Use certmanager para adicionar/obter um certificado SSL para sua entrada. Crie um sistema de monitoramento e alerta para seu aplicativo usando o Stackdriver.

O Kubernetes é ótimo porque escala facilmente, não há dependência de fornecedor e, como você está pagando pelas instâncias, economiza dinheiro. No entanto, nem todo mundo é especialista em Kubernetes ou tem tempo para configurar um novo cluster - para uma visão alternativa, o colega Toptaler Amin Shah Gilani usa Heroku, GitLab CI e uma grande quantidade de automação que ele já descobriu para escrever mais código e fazer menos tarefas de operação em Como construir um pipeline de implantação inicial eficaz .

Relacionado:
  • Faça as contas: aplicativos de microsserviços de dimensionamento automático com orquestradores
  • K8s/Kubernetes: AWS vs. GCP vs. Azure
  • Uma comparação de malha de serviço do Kubernetes