Como implantar, escalonar e atualizar um site com o Google Kubernetes Engine (GKE)

1. Introdução

Manter sites e aplicativos em operação não é uma tarefa simples.

Erros inesperados acontecem, servidores falham, e o aumento de demanda exige mais recursos. Além disso, fazer alterações sem causar inatividade é difícil e estressante.

Imagine uma ferramenta que possa ajudar você com tudo isso e até mesmo automatizar o processo. Com o GKE, tudo isso não é apenas possível, é fácil. Neste codelab, você vai assumir o papel de um desenvolvedor que administra um site de e-commerce para uma empresa fictícia, a Fancy Store. Devido a problemas de escalonamento e interrupções, você precisa implantar um aplicativo no GKE.

A ordem dos exercícios reflete uma experiência comum de desenvolvedor de nuvem:

  1. Criar um cluster do GKE.
  2. Crie um contêiner do Docker.
  3. Implante o contêiner no GKE.
  4. Exponha o contêiner usando um serviço.
  5. Escalone o contêiner para várias réplicas.
  6. Modifique o site.
  7. Lançar uma nova versão sem causar tempo de inatividade.

Diagrama da arquitetura

ddba666bd2b02d0d.png

O que você vai aprender

  • Como criar um cluster do GKE
  • Como criar uma imagem Docker
  • Como implantar imagens do Docker no Kubernetes
  • Como escalonar um aplicativo no Kubernetes
  • Como realizar uma atualização gradual no Kubernetes

Pré-requisitos

  • Uma Conta do Google com acesso administrativo para criar projetos ou um projeto com o papel de proprietário
  • Noções básicas do Docker e do Kubernetes. Se você não tiver esse conhecimento, revise Docker e Kubernetes agora.

2. configuração do ambiente

Configuração de ambiente personalizada

Se você ainda não tiver uma Conta do Google, crie uma. Faça login no Console do Google Cloud e crie um projeto.

53dad2cefdae71da.png

Screenshot from 2016-02-10 12:45:26.png

O ID do projeto é um nome exclusivo em todos os projetos do Google Cloud. O nome acima já foi escolhido e não servirá para você. Ele será chamado de PROJECT_ID mais tarde.

Em seguida, ative o faturamento no console do Cloud para usar os recursos do Google Cloud. Novos usuários do Google Cloud podem aproveitar um teste sem custo financeiro de US$300. Se você não for um novo usuário, não se preocupe, porque o codelab não vai custar mais do que alguns dólares. No entanto, o codelab pode custar mais dinheiro se você usar mais recursos ou deixá-los em execução. Consulte a seção "limpeza" no final. Para saber mais informações, consulte Preços.

Cloud Shell

Embora seja possível operar remotamente o Google Cloud e o GKE com seu laptop, você vai usar o Cloud Shell, um ambiente de linha de comando executado na nuvem, para o codelab.

O Cloud Shell é uma máquina virtual com base em Debian que contém todas as ferramentas de desenvolvimento necessárias. Ela oferece um diretório principal persistente de 5 GB, além de ser executada no Google Cloud. Isso aprimora o desempenho e a autenticação da rede. Isso significa que tudo que você precisa para este codelab é um navegador (sim, funciona em um Chromebook).

  1. Para ativar o Cloud Shell no Console do Cloud, basta clicar em Ativar o Cloud Shell fEbHefbRynwXpq1vj2wJw6Dr17O0np8l-WOekxAZYlZQIORsWQE_xJl-cNhogjATLn-YxLVz8CgLvIW1Ncc0yXKJsfzJGMYgUeLsVB7zSwz7p6ItNgx4tXqQjag7BfWPcZN5kP-X3Q. Leva apenas alguns instantes para provisionar e se conectar ao ambiente.

I5aEsuNurCxHoDFjZRZrKBdarPPKPoKuExYpdagmdaOLKe7eig3DAKJitIKyuOpuwmrMAyZhp5AXpmD_k66cBuc1aUnWlJeSfo_aTKPY9aNMurhfegg1CYaE11jdpSTYNNIYARe01A

Screen Shot 2017-06-14 às 10.13.43 PM.png

Depois de se conectar ao Cloud Shell, você já estará autenticado e o projeto estará configurado com seu PROJECT_ID.

gcloud auth list

Resposta ao comando

Credentialed accounts:
 - <myaccount>@<mydomain>.com (active)
gcloud config list project

Resposta ao comando

[core]
project = <PROJECT_ID>

Se, por algum motivo, o projeto não estiver definido, basta emitir o seguinte comando:

gcloud config set project <PROJECT_ID>

Quer encontrar seu PROJECT_ID? Veja qual ID você usou nas etapas de configuração ou procure-o no painel do Console do Cloud:

R7chO4PKQfLC3bvFBNZJALLTUiCgyLEq_67ECX7ohs_0ZnSjC7GxDNxWrJJUaoM53LnqABYamrBJhCuXF-J9XBzuUgaz7VvaxNrkP2TAn93Drxccyj2-5zz4AxL-G3hzxZ4PsM5HHQ

O Cloud Shell também define algumas variáveis de ambiente por padrão, o que pode ser útil ao executar comandos futuros.

echo $GOOGLE_CLOUD_PROJECT

Resposta ao comando

<PROJECT_ID>
  1. Defina a zona padrão e a configuração do projeto:
gcloud config set compute/zone us-central1-f

É possível escolher uma variedade de zonas diferentes. Para mais informações, consulte Regiões e zonas.

3. Criar um cluster do GKE

Agora que seu ambiente para desenvolvedores está funcionando, você precisa de um cluster do GKE para implantar seu site. Antes de criar um cluster, verifique se as APIs corretas estão ativadas. Execute o comando a seguir para ativar a API Containers:

gcloud services enable container.googleapis.com

Agora você pode criar seu cluster. Siga as etapas abaixo para criar um cluster chamado fancy-cluster com três nós:

gcloud container clusters create fancy-cluster --num-nodes 3

A criação do cluster pode levar vários minutos. Depois, execute o comando a seguir e confira as três instâncias de máquina virtual (VM) de worker do cluster:

gcloud compute instances list

Saída:

NAME                                          ZONE        MACHINE_TYPE   PREEMPTIBLE  INTERNAL_IP  EXTERNAL_IP    STATUS
gke-fancy-cluster-default-pool-ad92506d-1ng3  us-east4-a  n1-standard-1               10.150.0.7   XX.XX.XX.XX    RUNNING
gke-fancy-cluster-default-pool-ad92506d-4fvq  us-east4-a  n1-standard-1               10.150.0.5   XX.XX.XX.XX    RUNNING
gke-fancy-cluster-default-pool-ad92506d-4zs3  us-east4-a  n1-standard-1               10.150.0.6   XX.XX.XX.XX    RUNNING

Também é possível conferir o cluster e as informações relacionadas no console do Cloud. Clique no botão de menu no canto superior esquerdo, role para baixo até "Kubernetes Engine" e clique em "Clusters". O cluster chamado fancy-cluster deve aparecer aqui.

795c794b03c5d2b0.png

6b394dfb8a6031f2.png

Parabéns! Você criou seu primeiro cluster!

4. clonar o repositório de origem

Como o site já existe, você só precisa clonar a origem do repositório para se concentrar na criação de imagens do Docker e na implantação no GKE.

Execute os comandos a seguir para clonar o repositório de origem na sua instância do Cloud Shell e mudar para o diretório apropriado. Você também vai instalar as dependências do Node.js para testar o aplicativo antes da implantação.

cd ~
git clone https://github.com/googlecodelabs/monolith-to-microservices.git
cd ~/monolith-to-microservices
./setup.sh

Isso clona o repositório, muda o diretório e instala as dependências necessárias para executar o aplicativo localmente. Pode levar alguns minutos para o script ser executado.

Faça a auditoria e teste seu aplicativo. Execute o comando a seguir para iniciar o servidor da Web:

cd ~/monolith-to-microservices/monolith
npm start

Saída:

Monolith listening on port 8080!

Para ver o aplicativo, clique no ícone de visualização da Web no menu do Cloud Shell e selecione "Visualizar na porta 8080".

5869738f0e9ec386.png

Isso vai abrir uma nova janela onde você pode ver a Fancy Store em ação.

9ed25c3f0cbe62fa.png

Você pode fechar essa janela depois de acessar o site. Pressione Control+C (Windows ou Mac) na janela do terminal para interromper o processo do servidor da Web.

5. criar o contêiner do Docker com o Cloud Build

Agora que os arquivos de origem estão prontos, é hora de colocar o aplicativo no Docker.

Normalmente, você teria que seguir uma abordagem de duas etapas que envolve a criação de um contêiner do Docker e o envio dele para um registro para armazenar a imagem que o GKE extrai. No entanto, você pode facilitar as coisas usando o Cloud Build para criar o contêiner do Docker e colocar a imagem no Container Registry com um único comando. Para ver o processo manual de criação e envio de um arquivo do Docker, consulte o guia de início rápido do Container Registry.

O Cloud Build compacta e envia os arquivos do diretório para um bucket do Cloud Storage. Em seguida, o processo de build usa os arquivos do bucket e o Dockerfile para executar o processo de build do Docker. Como você especificou a flag --tag com o host gcr.io para a imagem Docker, a imagem Docker resultante é enviada ao Container Registry.

Primeiro, ative a API Cloud Build executando o seguinte comando:

gcloud services enable cloudbuild.googleapis.com

Depois de ativar a API, execute o seguinte comando no Cloud Shell para iniciar o processo de build:

cd ~/monolith-to-microservices/monolith
gcloud builds submit --tag gcr.io/${GOOGLE_CLOUD_PROJECT}/monolith:1.0.0 .

Esse processo leva alguns minutos. Quando a compilação estiver pronta, o terminal vai mostrar o seguinte:

-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
ID                                    CREATE_TIME                DURATION  SOURCE                                                                                  IMAGES                              STATUS
1ae295d9-63cb-482c-959b-bc52e9644d53  2019-08-29T01:56:35+00:00  33S       gs://<PROJECT_ID>_cloudbuild/source/1567043793.94-abfd382011724422bf49af1558b894aa.tgz  gcr.io/<PROJECT_ID>/monolith:1.0.0  SUCCESS

Para acessar o histórico de builds ou acompanhar o processo em tempo real, acesse o Console do Cloud. Clique no botão de menu no canto superior esquerdo, role para baixo até "Ci/CD", clique em "Cloud Build" e, por fim, em "Histórico". Essa tela apresenta uma lista dos builds anteriores. Por enquanto, haverá apenas um (o que você acabou de criar).

4c753ede203255f6.png

Se clicar em "ID do build", você verá todos os detalhes dele, incluindo a saída do registro.

Na página de detalhes do build, clique no nome da imagem na seção de informações do build para ver a imagem do contêiner criada.

6e88ed1643dfe629.png

6. Implantar o contêiner no GKE

Agora que você já fez a conteinerização do site e enviou o contêiner para o Container Registry, é possível implantá-lo no Kubernetes.

Para implantar e gerenciar aplicativos em um cluster do GKE, você precisa se comunicar com o sistema de gerenciamento de clusters do Kubernetes. Normalmente, isso é feito com a ferramenta de linha de comando kubectl.

O Kubernetes representa aplicativos como pods, que são unidades que representam um contêiner ou um grupo de contêineres estreitamente associados. O pod é a menor unidade implantável no Kubernetes. Aqui, cada pod contém apenas o contêiner monolítico.

Para implantar seu aplicativo, crie uma implantação. Uma implantação gerencia várias cópias do aplicativo, chamadas de réplicas, e as programa para serem executadas em nós individuais do cluster. Neste caso, a implantação vai executar apenas um pod do seu aplicativo. Para isso, o recurso de implantação cria um ReplicaSet. O ReplicaSet é responsável por garantir que o número de réplicas especificado esteja sempre em execução.

O comando kubectl create deployment faz com que o Kubernetes crie uma implantação chamada monolith no cluster com 1 réplica.

Execute o comando abaixo para implantar seu aplicativo:

kubectl create deployment monolith --image=gcr.io/${GOOGLE_CLOUD_PROJECT}/monolith:1.0.0

Verificar implantação

Para verificar se a implantação foi criada, execute o seguinte comando. Pode levar alguns instantes para que o status do pod seja "Em execução":

kubectl get all

Saída:

NAME                            READY   STATUS    RESTARTS   AGE
pod/monolith-7d8bc7bf68-htm7z   1/1     Running   0          6m21s

NAME                 TYPE        CLUSTER-IP    EXTERNAL-IP   PORT(S)   AGE
service/kubernetes   ClusterIP   10.27.240.1   <none>        443/TCP   24h

NAME                       DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/monolith   1         1         1            1           20m

NAME                                  DESIRED   CURRENT   READY   AGE
replicaset.apps/monolith-7d8bc7bf68   1         1         1       20m

Essa saída mostra várias informações: É possível conferir a implantação atual, o ReplicaSet com a contagem desejada de apenas um pod e o pod em execução. Parece que você criou tudo corretamente.

Para conferir seus recursos individualmente, execute os seguintes comandos:

# Show pods
kubectl get pods

# Show deployments
kubectl get deployments

# Show replica sets
kubectl get rs

#You can also combine them
kubectl get pods,deployments

Para conhecer todos os benefícios do Kubernetes, simule uma falha no servidor, exclua o pod e veja o que acontece!

Copie o nome do pod do comando anterior e execute o seguinte comando para excluí-lo:

kubectl delete pod/<POD_NAME>

Se você for ágil, poderá executar o comando anterior para ver tudo de novo. Dois pods vão aparecer, um sendo encerrado e outro sendo criado ou executado:

kubectl get all

Saída:

NAME                            READY   STATUS        RESTARTS   AGE
pod/monolith-7d8bc7bf68-2bxts   1/1     Running       0          4s
pod/monolith-7d8bc7bf68-htm7z   1/1     Terminating   0          9m35s

NAME                 TYPE        CLUSTER-IP    EXTERNAL-IP   PORT(S)   AGE
service/kubernetes   ClusterIP   10.27.240.1   <none>        443/TCP   24h

NAME                       DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/monolith   1         1         1            1           24m

NAME                                  DESIRED   CURRENT   READY   AGE
replicaset.apps/monolith-7d8bc7bf68   1         1         1       24m

Por que isso aconteceu? O ReplicaSet notou que o pod estava sendo encerrado e acionou um novo para manter a quantidade de réplicas escolhida. Mais adiante, você vai aprender a escalonar para garantir que haja várias instâncias em execução. Assim, se uma delas falhar, os usuários não vão perceber nenhuma inatividade.

7. expor a implantação do GKE

Você implantou o aplicativo no GKE, mas não é possível acessá-lo de fora do cluster. Por padrão, os contêineres executados no GKE não podem ser acessados pela Internet porque não têm endereços IP externos. Exponha explicitamente o aplicativo ao tráfego da Internet usando o recurso Serviço. Um serviço oferece suporte de rede e IP para os pods do seu app. O GKE cria um IP externo e um balanceador de carga (sujeito a faturamento) para seu app.

Execute o comando a seguir para expor o site à Internet:

kubectl expose deployment monolith --type=LoadBalancer --port 80 --target-port 8080

Saída:

service/monolith exposed

Como acessar o serviço

O GKE atribui o endereço IP externo ao recurso de serviço, não à implantação. Se você quiser encontrar o IP externo provisionado pelo GKE para seu aplicativo, inspecione o Serviço com o comando kubectl get service:

kubectl get service

Saída:

NAME         CLUSTER-IP      EXTERNAL-IP     PORT(S)          AGE
monolith     10.3.251.122    203.0.113.0     80:30877/TCP     3d

Depois de determinar o endereço IP externo do app, copie-o. Acesse esse URL (por exemplo, http://203.0.113.0) no navegador para verificar se o app está acessível.

9ed25c3f0cbe62fa.png

O mesmo site que você testou antes vai aparecer. Parabéns! Seu site está sendo executado integralmente no Kubernetes.

8. escalonar a implantação do GKE

Agora que você tem uma instância em execução do seu app no GKE e o expôs à Internet, seu site ficou muito famoso. Você precisa escalonar seu app para várias instâncias e lidar com o tráfego. Aprenda a escalonar seu aplicativo para até três réplicas.

Execute o comando a seguir para escalonar sua implantação em até três réplicas:

kubectl scale deployment monolith --replicas=3

Saída:

deployment.apps/monolith scaled

Verificar a implantação escalonada

Para verificar se a implantação foi escalonada corretamente, execute o seguinte comando:

kubectl get all

Saída:

NAME                            READY   STATUS    RESTARTS   AGE
pod/monolith-7d8bc7bf68-2bxts   1/1     Running   0          36m
pod/monolith-7d8bc7bf68-7ds7q   1/1     Running   0          45s
pod/monolith-7d8bc7bf68-c5kxk   1/1     Running   0          45s

NAME                 TYPE           CLUSTER-IP     EXTERNAL-IP    PORT(S)        AGE
service/kubernetes   ClusterIP      10.27.240.1    <none>         443/TCP        25h
service/monolith     LoadBalancer   10.27.253.64   XX.XX.XX.XX   80:32050/TCP   6m7s

NAME                       DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/monolith   3         3         3            3           61m

NAME                                  DESIRED   CURRENT   READY   AGE
replicaset.apps/monolith-7d8bc7bf68   3         3         3       61m

Três instâncias do seu pod vão estar em execução. Além disso, observe que a implantação e o ReplicaSet agora têm uma contagem desejada de três.

9. Faça mudanças no site

Sua equipe de marketing pediu que você mudasse a página inicial do site. Ela acha que o site deve oferecer mais informações sobre sua empresa e os produtos vendidos. Nesta seção, você vai adicionar um texto à página inicial para atender ao pedido da equipe de marketing. Parece que um dos nossos desenvolvedores já criou as mudanças com o nome de arquivo index.js.new. Você pode copiar o arquivo para index.js, e as mudanças vão aparecer. Siga as instruções abaixo para fazer as mudanças apropriadas.

Execute os comandos a seguir, copie o arquivo atualizado no arquivo com o nome correto e imprima o conteúdo para verificar as mudanças:

cd ~/monolith-to-microservices/react-app/src/pages/Home
mv index.js.new index.js
cat ~/monolith-to-microservices/react-app/src/pages/Home/index.js

O código resultante será parecido com este:

/*
Copyright 2019 Google LLC

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    https://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

import React from "react";
import { makeStyles } from "@material-ui/core/styles";
import Paper from "@material-ui/core/Paper";
import Typography from "@material-ui/core/Typography";
const useStyles = makeStyles(theme => ({
  root: {
    flexGrow: 1
  },
  paper: {
    width: "800px",
    margin: "0 auto",
    padding: theme.spacing(3, 2)
  }
}));
export default function Home() {
  const classes = useStyles();
  return (
    <div className={classes.root}>
      <Paper className={classes.paper}>
        <Typography variant="h5">
          Fancy Fashion &amp; Style Online
        </Typography>
        <br />
        <Typography variant="body1">
          Tired of mainstream fashion ideas, popular trends and societal norms?
          This line of lifestyle products will help you catch up with the Fancy trend and express your personal style.
          Start shopping Fancy items now!
        </Typography>
      </Paper>
    </div>
  );
}

Os componentes do React foram atualizados, mas você precisa criar o app React para gerar os arquivos estáticos. Execute o comando a seguir para criar o aplicativo React e copiar ele no diretório público monolith:

cd ~/monolith-to-microservices/react-app
npm run build:monolith

Agora que o código foi atualizado, é necessário recriar o contêiner do Docker e publicá-lo no Container Registry. Use o mesmo comando de antes, mas atualize o indicador de versão desta vez.

Execute este comando para acionar o Cloud Build de novo com a imagem atualizada na versão 2.0.0:

cd ~/monolith-to-microservices/monolith

#Feel free to test your application
npm start

gcloud builds submit --tag gcr.io/${GOOGLE_CLOUD_PROJECT}/monolith:2.0.0 .

Pressione Control+C (Windows ou Mac) na janela do terminal para interromper o processo do servidor da Web.

Na próxima seção, você vai usar essa imagem para atualizar seu aplicativo sem inatividade.

10. atualizar o site sem inatividade

As alterações foram feitas, e a equipe de marketing adorou a nova versão. É hora de atualizar o site sem interromper o serviço para os usuários. Siga as instruções abaixo para atualizar seu site:

As atualizações graduais do GKE garantem que o aplicativo permaneça ativo e disponível, mesmo quando o sistema substitui instâncias da imagem de contêiner antiga pela nova em todas as réplicas em execução.

Na linha de comando, informe ao Kubernetes que você quer atualizar a imagem da implantação para uma nova versão com o seguinte comando:

kubectl set image deployment/monolith monolith=gcr.io/${GOOGLE_CLOUD_PROJECT}/monolith:2.0.0

Saída:

deployment.apps/monolith image updated

Verifique a implantação

Para validar a atualização da implantação, execute o seguinte comando:

kubectl get pods

Saída:

NAME                        READY   STATUS              RESTARTS   AGE
monolith-584fbc994b-4hj68   1/1     Terminating         0          60m
monolith-584fbc994b-fpwdw   1/1     Running             0          60m
monolith-584fbc994b-xsk8s   1/1     Terminating         0          60m
monolith-75f4cf58d5-24cq8   1/1     Running             0          3s
monolith-75f4cf58d5-rfj8r   1/1     Running             0          5s
monolith-75f4cf58d5-xm44v   0/1     ContainerCreating   0          1s

Você vai ver três novos pods sendo criados e os antigos sendo desativados. É possível identificar os pods novos e os antigos pela idade deles. Depois, você verá apenas os três pods atualizados.

Para verificar as mudanças, acesse o IP externo do balanceador de carga novamente e note que o app foi atualizado.

Execute o comando a seguir para listar os serviços e ver o endereço IP, caso tenha esquecido:

kubectl get svc

O site agora mostra o texto que você acabou de incluir no componente da página inicial.

8006c9938dbd5aa5.png

11. Limpar

Exclua o repositório do Git:

cd ~
rm -rf monolith-to-microservices

Excluir imagens do Container Registry

OBSERVAÇÃO: se você criou outras versões, use a mesma sintaxe para excluir essas imagens também. Este codelab pressupõe que você tem apenas duas tags.

# Delete the container image for version 1.0.0 of our monolith
gcloud container images delete gcr.io/${GOOGLE_CLOUD_PROJECT}/monolith:1.0.0 --quiet

# Delete the container image for version 2.0.0 of our monolith
gcloud container images delete gcr.io/${GOOGLE_CLOUD_PROJECT}/monolith:2.0.0 --quiet

Excluir artefatos do Cloud Build no Cloud Storage

OBSERVAÇÃO: se você usou o Cloud Build para artefatos diferentes deste codelab, será necessário excluir manualmente a origem do bucket do Cloud Storage gs://<PROJECT_ID>_cloudbuild/source.

# The following command will take all source archives from all builds and delete them from cloud storage

# Run this command to print all sources:
# gcloud builds list | awk 'NR > 1 {print $4}'

gcloud builds list | awk 'NR > 1 {print $4}' | while read line; do gsutil rm $line; done

Excluir o serviço do GKE

kubectl delete service monolith
kubectl delete deployment monolith

Excluir o cluster do GKE

gcloud container clusters delete fancy-cluster

OBSERVAÇÃO: esse comando pode levar alguns minutos.

12. Parabéns!

Você implantou, escalonou e atualizou seu site no GKE. Agora você já sabe usar o Docker e o Kubernetes.

Outros recursos