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 poderia ajudar você a fazer tudo isso e até mesmo permitir a automação! Com o GKE, tudo isso é fácil e possível. Neste codelab, você assume o papel de um desenvolvedor que gerencia um site de e-commerce para uma empresa fictícia, a Fancy Store. Devido a problemas com escalonamento e interrupções, você recebeu a tarefa de implantar seu aplicativo no GKE.

A ordem das tarefas reflete uma experiência comum de desenvolvedor de nuvem:

  1. Criar um cluster do GKE.
  2. Criar um contêiner do Docker.
  3. Implantar o contêiner no GKE.
  4. Expor o contêiner por meio de um serviço.
  5. Escalonar o contêiner para várias réplicas.
  6. Modifique o site.
  7. Lançar uma nova versão sem 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.
  • Conhecimentos básicos sobre o Docker e o Kubernetes. Se você não tiver esses conhecimentos, revise o Docker e o Kubernetes agora mesmo.

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 novo projeto.

53dad2cefdae71da.png

Captura de tela de 10/02/2016 12:45:26.png

Lembre-se de que o ID do projeto é um nome exclusivo em todos os projetos do Google Cloud (o nome acima já foi usado e não vai funcionar para você). Posteriormente, ele será chamado de PROJECT_ID.

Em seguida, você precisará ativar o faturamento no console do Cloud para usar os recursos do Google Cloud. Novos usuários do Google Cloud têm direito a um teste sem custo financeiro de US$300. Se você não é um usuário novo, não se preocupe, porque o codelab não deve custar mais do que alguns dólares. No entanto, o codelab poderá gerar mais custos se você usar mais recursos ou deixá-los em execução. Consulte a seção "Limpar" no final. Para saber mais informações, consulte Preços.

Cloud Shell

É possível operar remotamente o Google Cloud e o GKE com seu laptop, mas você usará o Cloud Shell, um ambiente de linha de comando em execução no Cloud, no 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. Crie um cluster do GKE

Agora que seu ambiente de desenvolvimento está funcionando, você precisa de um cluster do GKE para implantar seu site. Antes de criar um cluster, você precisa verificar se as APIs adequadas estão ativadas. Execute o seguinte comando para ativar a API de contêineres:

gcloud services enable container.googleapis.com

Agora você já pode criar o 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 abaixo para conferir 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 ver 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. clone 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 alterá-lo para o diretório apropriado. Instale 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, altera o diretório e instala as dependências necessárias para executar localmente seu aplicativo. Pode levar alguns minutos para o script ser executado.

Faça a investigação e teste seu aplicativo. Execute o seguinte comando para iniciar o servidor da Web:

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

Saída:

Monolith listening on port 8080!

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

5869738f0e9ec386.png

Isso abrirá uma nova janela onde você pode ver sua Fancy Store em ação!

9ed25c3f0cbe62fa.png

Você pode fechar essa janela depois de visualizar 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, é necessário adotar uma abordagem de duas etapas que envolve criar um contêiner do Docker e enviá-lo para um registro para armazenar a imagem que o GKE extrai. No entanto, é possível facilitar sua vida 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 move os arquivos do diretório para um bucket do Cloud Storage. Em seguida, o processo de build pega os arquivos do bucket e usa o Dockerfile para executar o processo de build no Docker. Como você especificou a flag --tag com o host como gcr.io para a imagem do Docker, a imagem do 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, mas, depois de concluído, você verá a seguinte resposta no terminal:

-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
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 conferir seu 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, clique em Histórico. Você verá uma lista das suas versões anteriores, mas só haverá a que você criou.

4c753ede203255f6.png

Se clicar em "ID do build", você verá todos os detalhes do build, 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 conferir 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 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 o aplicativo, você precisa criar uma implantação. Uma implantação gerencia várias cópias do seu aplicativo, chamadas de réplicas, e as programa para serem executadas em nós individuais no seu cluster. Neste caso, a implantação executará apenas um pod do seu aplicativo. A implantação garante isso com a criação de um ReplicaSet. O ReplicaSet é responsável por garantir que as réplicas especificadas estejam 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

Verifique a implantação

Para verificar se a implantação foi criada, execute o comando a seguir. Pode levar alguns instantes para o status do pod mudar para "Running":

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. Você pode conferir a implantação atual, seu ReplicaSet, com uma contagem desejada de um pod. e o pod, que está em execução. Parece que você criou tudo corretamente.

Para visualizar os 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 para excluí-lo:

kubectl delete pod/<POD_NAME>

Se você for rápido o bastante, poderá executar o comando anterior para ver tudo novamente. Dois pods serão exibidos, 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 cair, os usuários não vão ter inatividade.

7. expor a implantação do GKE

Você implantou seu aplicativo no GKE, mas não tem como acessá-lo 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. Esse serviço oferece suporte de rede e IP para os pods do seu aplicativo. O GKE cria um IP externo e um balanceador de carga (sujeito a faturamento) para seu aplicativo.

Execute o seguinte comando para expor seu site na 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. Para 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. Aponte o navegador para esse URL (por exemplo, http://203.0.113.0) para verificar se o aplicativo está acessível.

9ed25c3f0cbe62fa.png

O mesmo site que você testou antes vai aparecer. Parabéns! Seu site é totalmente executado no Kubernetes.

8. escalonar a implantação do GKE

Agora que você tem uma instância do seu app em execução no GKE e a expôs na 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 a implantação para 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

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

9. Fazer mudanças no site

Sua equipe de marketing pediu para você mudar a página inicial do site. Eles acham que ela deveria ser mais informativa, explicando o que é sua empresa e o que você realmente vende. Nesta seção, você vai adicionar um texto à página inicial para atender às necessidades da equipe de marketing. Parece que um dos 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 serão aplicadas. 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 dele 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 app React e copiar no diretório público monolith:

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

Agora que o código está atualizado, é necessário recriar o contêiner do Docker e publicá-lo no Container Registry. É possível usar o mesmo comando usado anteriormente, mas, desta vez, você atualizará o identificador da versão.

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 o 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 interrupção para os usuários. Siga as instruções abaixo para atualizar seu site:

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

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

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ê verá três novos pods sendo criados e os pods antigos sendo desativados. É possível identificar pelas idades quais são novos e quais são antigos. Depois, você verá apenas três pods, que serão seus três pods atualizados.

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

Execute o seguinte comando para listar os serviços e ver o endereço IP se você tiver esquecido:

kubectl get svc

O site vai mostrar o texto que você adicionou ao 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, pode usar a mesma sintaxe para excluir essas imagens também. Este codelab presume 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 do Cloud Storage

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

# 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 serviço do GKE

kubectl delete service monolith
kubectl delete deployment monolith

Excluir cluster do GKE

gcloud container clusters delete fancy-cluster

OBSERVAÇÃO: esse comando pode demorar um pouco.

12. Parabéns!

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

Outros recursos