Como implantar um aplicativo da Web em contêiner

Neste tutorial, mostramos como empacotar um aplicativo da Web em uma imagem de contêiner do Docker e como executar essa imagem em um Cluster do Google Kubernetes Engine (GKE). Você implantará o aplicativo da Web como um conjunto de réplicas com balanceamento de carga que pode ser escalonado de acordo com as necessidades dos usuários.

Objetivos

  • Empacotar um aplicativo da Web de amostra em uma imagem do Docker.
  • Fazer o upload da imagem do Docker no Container Registry.
  • Criar um cluster do GKE.
  • Implantar o app de amostra no cluster.
  • Gerenciar o escalonamento automático da implantação.
  • Publicar o app de amostra na Internet.
  • Implantar uma nova versão do app de amostra.

Antes de começar

Siga estas etapas para ativar a API do Kubernetes Engine:
  1. Acesse a página do Kubernetes Engine no Console do Google Cloud.
  2. Crie ou selecione um projeto.
  3. Aguarde a ativação da API e dos serviços relacionados. Isso pode levar alguns minutos.
  4. Verifique se a cobrança está ativada para o seu projeto do Google Cloud. Saiba como confirmar se a cobrança está ativada para o seu projeto.

Opção A: usar o Cloud Shell

Siga este tutorial usando o Cloud Shell, que vem pré-instalado com as ferramentas de linha de comando gcloud, docker e kubectl usadas neste tutorial. Se você usa o Cloud Shell, não precisa instalar essas ferramentas de linha de comando na sua estação de trabalho.

Para usar o Cloud Shell:

  1. Acesse o Console do Google Cloud.
  2. Clique no botão Ativar o Cloud Shell Botão na parte superior da janela do Console do Cloud.

    Uma sessão do Cloud Shell é aberta dentro de um novo frame na parte inferior do Console do Cloud, e exibe um prompt de linha de comando.

    Sessão do Cloud Shell

Opção B: usar ferramentas de linha de comando localmente

Se você preferir seguir este tutorial na sua estação de trabalho, será preciso instalar as seguintes ferramentas:

  1. Instale o SDK do Google Cloud, que inclui a ferramenta de linha de comando gcloud.
  2. Instale a ferramenta de linha de comando Kubernetes usando a ferramenta gcloud. A ferramenta kubectl é usada para se comunicar com o Kubernetes, que é o sistema de orquestração de clusters do GKE:

    gcloud components install kubectl
  3. Instale o Docker Community Edition (CE) na estação de trabalho. Use-o para criar uma imagem do contêiner para o aplicativo.

  4. Instale a ferramenta de controle de origem Git para buscar a amostra de aplicativo do GitHub.

Etapa 1: criar a imagem do contêiner

Neste tutorial, você implantará um aplicativo da Web de amostra chamado hello-app, isto é, um servidor da Web escrito em Go que responde a todas as solicitações com a mensagem Hello, World! na porta 8080.

O GKE aceita imagens do Docker como o formato de implantação do aplicativo. Antes de implantar hello-app no GKE, você precisará empacotar o código-fonte hello-app como uma imagem do Docker.

Para criar uma imagem do Docker, é necessário ter um código-fonte e um Dockerfile (em inglês). Um Dockerfile contém instruções relacionadas à construção da imagem.

  1. Faça o download do código-fonte hello-app e do Dockerfile executando estes comandos:

    git clone https://github.com/GoogleCloudPlatform/kubernetes-engine-samples
    cd kubernetes-engine-samples/hello-app
    
  2. Defina a variável de ambiente PROJECT_ID como o ID do projeto do Google Cloud (project-id). A variável PROJECT_ID será usada para associar a imagem do contêiner ao Container Registry do projeto.

    export PROJECT_ID=project-id
    
  3. Crie e atribua uma tag à imagem do Docker para hello-app:

    docker build -t gcr.io/${PROJECT_ID}/hello-app:v1 .
    

    Este comando instrui o Docker a construir a imagem usando Dockerfile no diretório atual e a marcá-la com um nome, como gcr.io/my-project/hello-app:v1. O prefixo gcr.io refere-se ao Container Registry, em que a imagem será hospedada. A execução desse comando ainda não carrega a imagem.

  4. Execute o comando docker images para verificar se a compilação foi bem-sucedida:

    docker images
    
    Saída:
    REPOSITORY                     TAG                 IMAGE ID            CREATED             SIZE
    gcr.io/my-project/hello-app    v1                  25cfadb1bf28        10 seconds ago      54 MB
    

Etapa 2: executar o contêiner localmente (opcional)

  1. Teste a imagem do contêiner usando o mecanismo local do Docker:

    docker run --rm -p 8080:8080 gcr.io/${PROJECT_ID}/hello-app:v1
    
  2. Se você estiver usando o Cloud Shell, clique no botão Visualização da Web Botão de visualização da Web e selecione o número da porta 8080. O GKE abre o URL de visualização no serviço de proxy em uma nova janela do navegador.

  3. Caso contrário, abra uma nova janela do terminal ou uma guia do Cloud Shell e execute para verificar se o contêiner funciona e responde às solicitações com "Hello, World!":

    curl http://localhost:8080

    Depois de ver uma resposta bem-sucedida, desligue o contêiner pressionando Ctrl + C na guia em que o comando docker run está sendo executado.

Etapa 3: enviar a imagem do Docker para o Container Registry

Você precisa fazer o upload da imagem do contêiner em um registro para que o Cluster do GKE possa fazer o download e executá-la.

  1. Configure a ferramenta de linha de comando do Docker para autenticar no Container Registry:

    gcloud auth configure-docker
    
  2. Envie a imagem do Docker que você acabou de criar para o Container Registry:

    docker push gcr.io/${PROJECT_ID}/hello-app:v1
    

Etapa 4: criar um Cluster do GKE

Agora que a imagem do Docker está armazenada no Container Registry, você precisa criar um Cluster do GKE para executar hello-app. Um Cluster do GKE consiste em um pool de instâncias de VM do Compute Engine executando o Kubernetes (em inglês), isto é, o sistema de orquestração de cluster de código aberto que alimenta o GKE.

Cloud Shell

  1. Defina as opções do ID do projeto e zona do Compute Engine para a ferramenta gcloud:

    gcloud config set project $PROJECT_ID
    gcloud config set compute/zone compute-zone
  2. Crie um cluster chamado hello-cluster:

    gcloud container clusters create hello-cluster
    

    Levará alguns minutos para que o Cluster do GKE seja criado e submetido à verificação de integridade.

  3. Depois que o comando for concluído, execute o comando a seguir para ver as duas instâncias de VM do worker do cluster:

    gcloud compute instances list
    
    Saída:
    NAME                                           ZONE        MACHINE_TYPE   PREEMPTIBLE  INTERNAL_IP  EXTERNAL_IP    STATUS
    gke-hello-cluster-default-pool-d8b498d3-0d6r  us-east1-b  n1-standard-1               10.142.0.4   35.237.4.149   RUNNING
    gke-hello-cluster-default-pool-d8b498d3-k29m  us-east1-b  n1-standard-1               10.142.0.3   34.75.248.193  RUNNING
    gke-hello-cluster-default-pool-d8b498d3-vcrj  us-east1-b  n1-standard-1               10.142.0.2   35.196.51.235  RUNNING
    

Console

  1. Acesse o menu do Google Kubernetes Engine no Console do Cloud.

    Acessar o menu do Google Kubernetes Engine

  2. Clique no botão Criar cluster.

  3. Na seção Noções básicas do cluster, insira o nome hello-cluster.

  4. Defina a zona escolhendo uma zona do Compute Engine no menu suspenso.

  5. Clique em Criar. Isso criará um Cluster do GKE com três nós.

  6. Aguarde a criação do cluster. Quando o cluster estiver pronto, uma marca de seleção verde será exibida ao lado do nome do cluster.

Etapa 5: implantar o app de amostra no GKE

Agora está tudo pronto para implantar no cluster do GKE a imagem do Docker que você criou.

O Kubernetes representa aplicativos como pods (em inglês), que são unidades escalonáveis com um ou mais contêineres. O pod é a menor unidade implantável no Kubernetes. Normalmente, você implanta pods como um conjunto de réplicas que podem ser escalonadas e distribuídas juntas no cluster. Uma maneira de implantar um conjunto de réplicas é por meio de uma implantação do Kubernetes (em inglês).

Você criará uma implantação do Kubernetes para executar hello-app no cluster. Essa implantação terá três réplicas (pods). Um pod de implantação conterá apenas um contêiner: a imagem do Docker hello-app. Você também criará um recurso HorizontalPodAutoscaler (em inglês) que escalonará o número de pods de três para um número entre um e cinco, com base na carga da CPU.

Cloud Shell

  1. Crie uma implantação do Kubernetes para a imagem do Docker hello-app.

    kubectl create deployment hello-app --image=gcr.io/${PROJECT_ID}/hello-app:v1
    
  2. Defina como três o número de valor de referência das réplicas de implantação.

    kubectl scale deployment hello-app --replicas=3
    
  3. Crie um recurso HorizontalPodAutoscaler para a implantação.

    kubectl autoscale deployment hello-app --cpu-percent=80 --min=1 --max=5
    
  4. Para ver os pods criados, execute este comando:

    kubectl get pods
    
    Saída:
    NAME                         READY   STATUS    RESTARTS   AGE
    hello-app-784d7569bc-hgmpx   1/1     Running   0          10s
    hello-app-784d7569bc-jfkz5   1/1     Running   0          10s
    hello-app-784d7569bc-mnrrl   1/1     Running   0          15s
    

Console

  1. Acesse o menu Cargas de trabalho do Google Kubernetes Engine no Console do Cloud.

    Acessar o menu "Cargas de trabalho"

  2. No menu "Cargas de trabalho", clique em Implantar.

  3. Na janela "Criar implantação", clique em Imagem de contêiner atual.

  4. Usando o menu suspenso, clique na imagem hello-app enviada ao Container Registry.

  5. Clique em Ver YAML. Isso abrirá um arquivo de configuração YAML que representa os dois recursos da API Kubernetes a serem implantados no cluster: uma implantação e um HorizontalPodAutoscaler para essa implantação.

  6. Clique em Implantar.

  7. Aguarde até que os pods de implantação estejam prontos. Você verá lemes azuis girando à medida que o cluster do GKE realiza a implantação dos três pods hello-app, e verá marcas de seleção verdes quando os pods forem implantados com sucesso.

  8. Aguarde até que os pods estejam prontos navegando para o Kubernetes Engine e, depois, para as cargas de trabalho. Clique em hello-app e role para baixo até a seção Pods gerenciados. Você verá três pods hello-app.

Etapa 6: publicar o app de amostra na Internet

Embora os pods tenham endereços IP atribuídos individualmente, esses IPs só podem ser acessados de dentro do cluster. Além disso, os pods do GKE são projetados para serem temporários, realizando aumentos ou reduções com base nas necessidades de escalonamento. E quando um pod falha devido a um erro, o GKE o reimplanta automaticamente, atribuindo um novo endereço IP de pod toda vez.

Isso significa que, para qualquer implantação, o conjunto de endereços IP correspondente ao conjunto ativo de pods é dinâmico. Precisamos de uma maneira para 1) Agrupar pods em um nome de host estático e 2) Expor um grupo de pods, fora do cluster, na Internet.

Os Serviços do Kubernetes resolvem esses dois problemas. Serviços agrupam pods em um endereço IP estático e acessível a partir de qualquer pod dentro do cluster. O GKE também atribui um nome de host DNS a esse IP estático, como hello-app.default.svc.cluster.local.

O tipo de Serviço padrão no GKE é chamado de ClusterIP, em que o Serviço recebe um endereço IP acessível somente de dentro do cluster. Para expor um Serviço do Kubernetes fora do cluster, será preciso criar um Serviço do tipo LoadBalancer. Esse tipo de Serviço gera um IP do balanceador de carga externo para um conjunto de pods, acessíveis por meio da Internet.

Agora você publicará a implantação do hello-app na Internet usando um Serviço do tipo LoadBalancer.

Cloud Shell

  1. Use o comando kubectl expose para gerar um Serviço do Kubernetes para a implantação do hello-app.

    kubectl expose deployment hello-app --name=hello-app-service --type=LoadBalancer --port 80 --target-port 8080
    

    Aqui, a sinalização --port especifica o número da porta configurada no balanceador de carga, e a sinalização --target-port especifica o número da porta em que o contêiner hello-app está realizando detecções.

  2. Execute o comando a seguir para receber os detalhes do Serviço de hello-app-service.

    kubectl get service
    
    Saída:
    NAME                 CLUSTER-IP      EXTERNAL-IP     PORT(S)          AGE
    hello-app-service    10.3.251.122    203.0.113.0     80:30877/TCP     10s
    
  3. Copie o endereço EXTERNAL_IP na área de transferência (por exemplo: 203.0.113.0).

Console

  1. Acesse o menu Cargas de trabalho do Google Kubernetes Engine no Console do Cloud.

    Acessar o menu "Cargas de trabalho"

  2. Clique em hello-app.

  3. Na página "Detalhes da implantação", clique em Expor.

  4. No menu "Expor uma implantação", defina a Porta de destino como 8080. Essa é a porta em que o contêiner hello-app realiza detecções.

  5. Clique em Expor para gerar um Serviço do Kubernetes para o hello-app, chamado hello-app-service.

  6. Aguarde a criação do balanceador de carga externo. Você verá um leme azul girando no Console do Google Cloud, e assim que o balanceador de carga estiver pronto, acontecerá o redirecionamento para a página "Detalhes do Serviço" de hello-app-service.

  7. Role para baixo até o campo Endpoints externos, e copie o endereço para a área de transferência.

Agora que os pods hello-app estão expostos na Internet por meio de um Serviço do Kubernetes, é possível abrir uma nova guia do navegador e navegar até o endereço IP do Serviço copiado para a área de transferência. Você verá uma mensagem Hello, World! junto a um campo Hostname. O Hostname corresponde a um dos três pods hello-app que veiculam a solicitação HTTP para o navegador.

Etapa 7: implantar uma nova versão do app de amostra

Nesta seção, você fará o upgrade do hello-app para uma nova versão ao criar e implantar uma nova imagem do Docker no Cluster do GKE.

O recurso de atualização gradual do GKE permite que você atualize as implantações sem inatividade. Durante uma atualização gradual, o Cluster do GKE substitui os pods hello-app atuais por pods que contêm a imagem do Docker para a nova versão. Durante a atualização, o serviço do balanceador de carga encaminhará o tráfego apenas para os pods disponíveis.

  1. Retorne ao Cloud Shell, onde você clonou o código-fonte do app hello e o Dockerfile. Crie uma nova versão do código-fonte hello-app atualizando main.go para relatar uma nova versão, 2.0.0.

  2. Crie e atribua uma tag à nova imagem do Docker hello-app.

    docker build -t gcr.io/${PROJECT_ID}/hello-app:v2 .
    
  3. Envie a imagem para o Container Registry

    docker push gcr.io/${PROJECT_ID}/hello-app:v2
    

Agora está tudo pronto para atualizar a implantação do Kubernetes hello-app e usar uma nova imagem do Docker.

Cloud Shell

  1. Aplique uma atualização contínua à implantação atual com uma atualização de imagem:

    kubectl set image deployment/hello-app hello-app=gcr.io/${PROJECT_ID}/hello-app:v2
    
  2. Veja os pods atuais executando a imagem v1 serem encerrados e os novos pods executando a imagem v2 serem gerados.

    watch kubectl get pods
    
    Saída:
    NAME                        READY   STATUS    RESTARTS   AGE
    hello-app-89dc45f48-5bzqp   1/1     Running   0          2m42s
    hello-app-89dc45f48-scm66   1/1     Running   0          2m40s
    
  3. Em uma guia separada, navegue novamente para o IP externo hello-app-service. Você verá a Version definida como 2.0.0.

Console

  1. Acesse o menu Cargas de trabalho do Google Kubernetes Engine no Console do Cloud.

    Acessar o menu "Cargas de trabalho"

  2. Clique em hello-app.

  3. Em Ações, clique em Atualização gradual.

  4. Na janela exibida, defina o campo Imagem como gcr.io/[YOUR_PROJECT_ID]/hello-app:v2.

  5. Clique em Atualizar para iniciar a atualização gradual.

  6. Volte para a visualização de implantação em hello-app e, depois, role para baixo até Revisões ativas. Agora você verá duas Revisões, a 1 e a 2. A Revisão 1 corresponde à Implantação inicial criada anteriormente. A Revisão 2 é a atualização gradual que você acabou de iniciar.

  7. Após alguns instantes, atualize a página. Em Pods gerenciados, você verá que agora todas as réplicas de hello-app correspondem à Revisão 2.

  8. Em uma guia separada, navegue novamente para o IP externo hello-app-service. Você verá a Version definida como 2.0.0.

Como fazer a limpeza

Para evitar cobranças na conta do Google Cloud Platform, referentes aos recursos usados neste tutorial:

  1. Exclua o serviço: isso desaloca o Cloud Load Balancer criado para o serviço:

    kubectl delete service hello-app-service
  2. Exclua o cluster: exclui os recursos que compõem o cluster, como instâncias de computação, discos e recursos de rede:

    gcloud container clusters delete hello-cluster

A seguir