De desenvolvimento para produção em três etapas fáceis com o Cloud Run

1. Introdução

Por que é tão difícil gerenciar aplicativos?

Um dos principais motivos é que os desenvolvedores geralmente precisam ser administradores de sistemas em tempo parcial. Considere esta lista (parcial) de preocupações para desenvolver, implantar e gerenciar um aplicativo da Web moderno de nível de produção :

4d018476b4a73b47.png

Não sei você, mas essas são todas as coisas com que não quero me preocupar! O que eu realmente quero pensar é na lógica do meu aplicativo:

6dfd143d20e5548b.png

Em resumo, é isso que o Cloud Run faz: permite que você se concentre no app e deixe toda a administração e manutenção para outra pessoa, ou seja, o Google, que investiu milhões de horas no refinamento e aperfeiçoamento das habilidades nesse domínio.

Além dos desafios administrativos mencionados acima, você também precisa lidar com:

  • Dependências: o ambiente em que o app é executado deve, sempre que possível, corresponder exatamente ao ambiente em que ele foi testado. Isso pode abranger várias dimensões, incluindo sistema operacional, bibliotecas de suporte, interpretador ou compilador de linguagem, configuração de hardware e muitos outros fatores.
  • Distribuição: passar de uma encarnação local de um app para uma compartilhada na Internet geralmente exige uma mudança no ambiente de execução, um salto quântico na complexidade e uma curva de aprendizado acentuada.

O Cloud Run cuida dessas e de muitas outras questões para você. Em vez de acreditar em mim, vamos criar um app juntos e ver como é fácil fazer a transição de um ambiente de desenvolvimento local para um app de nuvem de nível de produção em apenas algumas etapas simples.

O que você vai fazer…

  • Você vai criar um app da Web simples e verificar se ele é executado conforme o esperado no ambiente de desenvolvimento.
  • Em seguida, você vai passar para uma versão conteinerizada do mesmo app. Ao longo do caminho, você vai entender o que significa conteinerização e por que ela é tão útil.
  • Por fim, você vai implantar seu app na nuvem e conferir como é fácil gerenciar o serviço do Cloud Run usando a linha de comando e o console do Google Cloud.

O que você vai aprender…

  • Como criar um app de servidor da Web simples em Python
  • Como empacotar seu app em um contêiner do Docker que pode ser executado em qualquer lugar
  • Como implantar seu app na nuvem para que qualquer pessoa possa testar sua nova criação
  • Como simplificar ainda mais as etapas acima usando buildpacks
  • Como usar a ferramenta de linha de comando do Google Cloud e a interface da Web do console do Cloud

O que é necessário…

  • Um navegador da Web
  • Uma Conta do Google

Este laboratório é voltado para desenvolvedores com todos os níveis de conhecimento, inclusive iniciantes. Embora você use Python, não é necessário conhecer esse tipo de programação para entender o que está acontecendo, porque vamos explicar todo o código usado.

2. Começar a configuração

5110b5081a1e1c49.png

Nesta seção, você vai encontrar tudo o que precisa fazer para começar o laboratório.

Configuração de ambiente autoguiada

  1. Faça login no console do Cloud e crie um novo projeto ou reutilize um existente. Crie uma conta do Gmail ou do Google Workspace, se ainda não tiver uma.

96a9c957bc475304.png

b9a10ebdf5b5a448.png

a1e3c01a38fa61c2.png

Lembre-se do código do projeto, um nome exclusivo em todos os projetos do Google Cloud. O nome acima já foi escolhido e não servirá para você. Faremos referência a ele mais adiante neste codelab como PROJECT_ID.

  1. Em seguida, será necessário ativar o faturamento no Console do Cloud para usar os recursos do Google Cloud.

A execução deste codelab não será muito cara, se for o caso. Siga todas as instruções na seção "Limpeza", que orienta você sobre como encerrar recursos para não incorrer em cobranças além deste tutorial. Novos usuários do Google Cloud estão qualificados para o programa de US$300 de avaliação sem custos.

Inicie o Cloud Shell

Neste laboratório, você vai trabalhar em uma sessão do Cloud Shell, que é um interpretador de comandos hospedado por uma máquina virtual em execução na nuvem do Google. A sessão também pode ser executada localmente no seu computador, mas se você usar o Cloud Shell, todas as pessoas vão ter acesso a uma experiência reproduzível em um ambiente consistente. Após concluir o laboratório, é uma boa ideia testar a sessão no seu computador.

704a7b7491bd157.png

Ativar o Cloud Shell

  1. No Console do Cloud, clique em Ativar o Cloud Shell4292cbf4971c9786.png.

bce75f34b2c53987.png

Se você nunca iniciou o Cloud Shell, vai ver uma tela intermediária abaixo da dobra com a descrição dele. Se esse for o caso, clique em Continuar e você não a verá novamente. Esta é a aparência dessa tela única:

70f315d7b402b476.png

Leva apenas alguns instantes para provisionar e se conectar ao Cloud Shell.

fbe3a0674c982259.png

Essa máquina virtual 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. Praticamente todo o seu trabalho neste codelab pode ser feito em um navegador ou no seu Chromebook.

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

  1. Execute o seguinte comando no Cloud Shell para confirmar que você está autenticado:
gcloud auth list

Resposta ao comando

 Credentialed Accounts
ACTIVE  ACCOUNT
*       <my_account>@<my_domain.com>

To set the active account, run:
    $ gcloud config set account `ACCOUNT`
  1. Execute o comando a seguir no Cloud Shell para confirmar se o comando gcloud sabe sobre seu projeto:
gcloud config list project

Resposta ao comando

[core]
project = <PROJECT_ID>

Se o projeto não estiver configurado, configure-o usando este comando:

gcloud config set project <PROJECT_ID>

Resposta ao comando

Updated property [core/project].

Defina algumas variáveis de ambiente no terminal para facilitar as etapas subsequentes:

export PROJ=$GOOGLE_CLOUD_PROJECT 
export APP=hello 
export PORT=8080
export REGION="us-central1"
export TAG="gcr.io/$PROJ/$APP"

Ative as APIs

Nas próximas etapas, você vai entender onde e por que esses serviços são necessários. Por enquanto, apenas execute este comando para conceder ao seu projeto acesso aos serviços do Cloud Build, Container Registry e Cloud Run:

gcloud services enable cloudbuild.googleapis.com         \
                       containerregistry.googleapis.com  \
                       run.googleapis.com          

Uma mensagem semelhante a esta vai aparecer:

Operation "operations/acf.cc11852d-40af-47ad-9d59-477a12847c9e" finished successfully.

3. Criar um app da Web simples

eef530b56b8e93a3.png

Clique no botão Open Editor na parte de cima do painel do Cloud Shell. Esta é a aparência dela:

9b81c8a37a6bcdd8.png

Você vai estar em um ambiente de IDE semelhante ao Visual Studio Code, em que é possível criar projetos, editar código-fonte, executar programas etc. Se a tela estiver muito apertada, expanda ou reduza a linha divisória entre o console e a janela de edição/terminal arrastando a barra horizontal entre essas duas regiões, destacada aqui:

8dea35450851af53.png

Clique nos botões Open Editor e Open Terminal para alternar entre o editor e o terminal, respectivamente. Tente alternar entre esses dois ambientes agora.

Em seguida, crie uma pasta para armazenar seu trabalho neste laboratório. Para isso, selecione "Arquivo" > "Nova pasta", insira hello e clique em OK. Todos os arquivos criados neste laboratório e todo o trabalho feito no Cloud Shell serão realizados nessa pasta.

Agora, crie um arquivo requirements.txt. Isso informa ao Python de quais bibliotecas seu app depende. Para este app da Web simples, você vai usar um módulo Python conhecido para criar servidores da Web chamado Flask e um framework de servidor da Web chamado gunicorn. Na janela do Cloud Editor, clique no menu Arquivo > Novo arquivo para criar um arquivo. Quando for solicitado o nome do novo arquivo, insira requirements.txt e pressione o botão OK. Verifique se o novo arquivo está na pasta do projeto hello.

Insira as seguintes linhas no novo arquivo para especificar que seu app depende do pacote Flask do Python e do servidor da Web gunicorn.

Flask
gunicorn

Não é necessário salvar explicitamente esse arquivo porque o Cloud Editor salva automaticamente as mudanças para você.

Versão 1: Hello world!

Usando a mesma técnica, crie outro arquivo chamado main.py. Esse será o arquivo de origem principal (e único) do seu app em Python. De novo, confira se o novo arquivo está na pasta do projeto hello.

Insira o seguinte código no arquivo:

from flask import Flask
import os
import random

app = Flask(__name__)  # Create a Flask object.
PORT = os.environ.get("PORT")  # Get PORT setting from the environment.

# The app.route decorator routes any GET requests sent to the root path
# to this function, which responds with a "Hello world!" HTML document.
@app.route("/", methods=["GET"])
def say_hello():
    html = "<h1>Hello world!</h1>"
    return html


# This code ensures that your Flask app is started and listens for
# incoming connections on the local interface and port 8080.
if __name__ == "__main__":
    app.run(host="0.0.0.0", port=PORT)

Volte ao terminal e mude para a pasta do projeto com este comando:

cd hello

Execute o comando a seguir para instalar as dependências do projeto:

pip3 install -r requirements.txt

Agora inicie o app executando este comando no terminal:

python3 main.py

Neste ponto, seu app está sendo executado na máquina virtual dedicada à sua sessão do Cloud Shell. O Cloud Shell inclui um mecanismo de proxy que permite acessar servidores da Web (como o que você acabou de iniciar) em execução na sua máquina virtual de qualquer lugar da Internet global.

Clique no botão web preview e no item de menu Preview on Port 8080, assim:

fe45e0192080efd6.png

Isso vai abrir uma guia do navegador da Web com o app em execução, que deve ter esta aparência:

b1f06501509aefb9.png

Versão 2: ecoando o caminho do URL

Volte ao Cloud Editor (pelo botão Open Editor) e adicione suporte para repetir um sufixo de URL opcional atualizando o arquivo main.py da seguinte maneira:

from flask import Flask
import os
import random

app = Flask(__name__)  # Create a Flask object.
PORT = os.environ.get("PORT")  # Get PORT setting from environment.

# The app.route decorator routes any GET requests sent to the root path
# to this function, which responds with a "Hello world!" HTML document.
# If something is specified as the URL path (after the '/'), say_hello()
# responds with "Hello X", where X is the string at the end of the URL.
@app.route("/", methods=["GET"])
@app.route("/<name>", methods=["GET"])     # ← NEW
def say_hello(name="world"):               # ← MODIFIED
    html = f"<h1>Hello {name}!</h1>"       # ← MODIFIED
    return html


# This code ensures that your Flask app is started and listens for
# incoming connections on the local interface and port 8080.
if __name__ == "__main__":
    app.run(host="0.0.0.0", port=PORT)

Volte para o terminal (pelo botão Open Terminal) e digite control-C (mantenha pressionada a tecla "Control" enquanto pressiona "C") para interromper o app em execução e reinicie-o digitando:

python3 main.py

Clique novamente no botão web preview e depois no item de menu Preview on Port 8080 para abrir uma guia do navegador da Web com o app em execução. A mensagem "Hello world!" vai aparecer de novo. Agora, substitua o texto do URL após a barra por qualquer string da sua escolha (por exemplo, /your-name) e verifique se algo assim aparece:

93b87996f88fa370.png

Versão 3: cores aleatórias

Agora, adicione suporte para cores de plano de fundo aleatórias voltando ao Cloud Editor (pelo botão Open Editor) e atualizando o arquivo main.py da seguinte maneira:

from flask import Flask
import os
import random

app = Flask(__name__)  # Create a Flask object.
PORT = os.environ.get("PORT")  # Get PORT setting from the environment.

# This function decides whether foreground text should be
# displayed in black or white, to maximize fg/bg contrast.
def set_text_color(rgb):                      # ← NEW
    sum = round(                              # ← NEW
        (int(rgb[0]) * 0.299)                 # ← NEW
        + (int(rgb[1]) * 0.587)               # ← NEW
        + (int(rgb[2]) * 0.114)               # ← NEW
    )                                         # ← NEW
    return "black" if sum > 186 else "white"  # ← NEW


# The app.route decorator routes any GET requests sent to the root path
# to this function, which responds with a "Hello world!" HTML document.
# If something is specified as the URL path (after the '/'), say_hello()
# responds with "Hello X", where X is the string at the end of the URL.
# To verify each new invocation of these requests, the HTML document
# includes CSS styling to produce a randomly colored background.
@app.route("/", methods=["GET"])
@app.route("/<name>", methods=["GET"])
def say_hello(name="world"):
    bg = random.sample(range(1, 255), 3)                       # ← NEW
    hex = (int(bg[0]) * 256) + (int(bg[1]) * 16) + int(bg[2])  # ← NEW
    fg_color = set_text_color(bg)                              # ← NEW
    bg_color = f"#{hex:06x}"                                   # ← NEW
    style = f"color:{fg_color}; background-color:{bg_color}"   # ← NEW
    html = f'<h1 style="{style}">Hello {name}!</h1>'           # ← MODIFIED
    return html


# This code ensures that your Flask app is started and listens for
# incoming connections on the local interface and port 8080.
if __name__ == "__main__":
    app.run(host="0.0.0.0", port=PORT)

Volte para o terminal (pelo botão Open Terminal) e digite control-C (mantenha pressionada a tecla "Control" enquanto pressiona "C") para interromper o app em execução e reinicie-o digitando:

python3 main.py

Clique novamente no botão web preview e depois no item de menu Preview on Port 8080 para abrir uma guia do navegador da Web com o app em execução. O texto gerado vai aparecer com o sufixo especificado ou a string padrão "Hello world!", em frente a um plano de fundo colorido aleatoriamente, assim:

baf8d028f15ea7f4.png

Atualize a página algumas vezes para ver que a cor aleatória do plano de fundo muda a cada vez que você acessa o app.

E assim seu app está pronto. Parabéns! Na próxima etapa, você vai aprender a empacotar seu app em um contêiner e por que isso é útil.

4. Contentorização do aplicativo

17cc234ec3325a8a.png

O que é um contêiner?

Os contêineres em geral, e o Docker em particular, nos dão a capacidade de criar uma caixa modular em que um aplicativo pode ser executado com todas as dependências agrupadas. Chamamos o resultado de imagem do contêiner. Nesta seção, você vai criar uma imagem de contêiner, que será usada para encapsular o aplicativo e todas as dependências dele.

Falando em dependências, em uma etapa anterior, quando você estava executando o app em um ambiente de desenvolvimento, precisou executar pip3 install -r requirements.txt e garantir que o arquivo requirements.txt continha todas as bibliotecas dependentes e as versões correspondentes. Com os contêineres, você instala esses requisitos ao gerar a imagem do contêiner. Assim, o consumidor do contêiner não precisa se preocupar em instalar nada.

Essa imagem de contêiner vai formar o elemento básico para implantar seu aplicativo no Cloud Run. Como os contêineres podem ser usados em quase qualquer servidor virtual ou real, isso nos dá uma maneira de implantar seu aplicativo em qualquer lugar e movê-lo de um provedor de serviços para outro ou de um ambiente local para a nuvem.

Os contêineres ajudam a tornar seus aplicativos:

  • reproduzíveis: os contêineres são independentes e completos
  • portátil: os contêineres são blocos de construção intersetoriais que permitem a portabilidade de aplicativos entre provedores de nuvem e ambientes.

Em resumo, os contêineres oferecem a capacidade de, finalmente, "escrever uma vez e executar em qualquer lugar". Uma exceção a essa regra é que o contêiner gerado é restrito à execução no tipo de processador em que foi criado, mas há maneiras de gerar versões de contêiner para outras configurações de hardware também.

Vamos ao que interessa: criar um contêiner! Você vai usar uma tecnologia específica para criar um contêiner chamado Docker.

No Cloud Editor, crie um arquivo chamado Dockerfile. Esse arquivo é um blueprint para construir sua imagem. Ele informa ao Docker sobre seu ambiente operacional e código-fonte, como instalar dependências, criar o app e executar o código.

# Use an official lightweight Python image.
FROM python:3.9-slim

# Copy local code to the container image.
WORKDIR /app
COPY main.py .
COPY requirements.txt .

# Install dependencies into this container so there's no need to 
# install anything at container run time.
RUN pip install -r requirements.txt

# Service must listen to $PORT environment variable.
# This default value facilitates local development.
ENV PORT 8080

# Run the web service on container startup. Here you use the gunicorn
# server, with one worker process and 8 threads. For environments 
# with multiple CPU cores, increase the number of workers to match 
# the number of cores available.
CMD exec gunicorn --bind 0.0.0.0:$PORT --workers 1 --threads 8 --timeout 0 main:app

No terminal da nuvem, crie a imagem do contêiner usando o Cloud Build com o seguinte comando:

gcloud builds submit --tag $TAG

Depois de enviado para o registro, você verá uma mensagem SUCCESS contendo o nome da imagem, que deve ser algo assim: gcr.io/<project-id>/hello. A imagem agora está armazenada no Google Container Registry e pode ser reutilizada quando e onde você quiser.

Liste todas as imagens do contêiner associadas ao projeto atual usando este comando:

gcloud container images list

Agora, execute e teste o aplicativo localmente no Cloud Shell usando estes comandos docker:

docker run -p $PORT:$PORT -e PORT=$PORT $TAG

A opção -p $PORT:$PORT informa ao Docker para mapear a porta externa $PORT (definida como 8080 acima) no ambiente do host para o mesmo número de porta dentro do contêiner em execução. Isso facilita as coisas porque o código do servidor que você escreve e o número da porta externa a que você se conecta ao testar o app serão os mesmos (8080). No entanto, você pode usar a opção -p para mapear qualquer porta externa arbitrária no host para qualquer porta interna desejada dentro do contêiner.

A opção -e PORT=$PORT informa ao Docker para disponibilizar a variável de ambiente $PORT (definida como 8080 acima) ao app em execução no contêiner.

Agora você pode testar o app direcionando um navegador da Web para o código Python em execução no contêiner. Na janela do Cloud Shell, clique no ícone "Visualização na Web" e selecione "Visualizar na porta 8080", como fez na etapa anterior.

O resultado deve ser familiar. Você vai ver o texto gerado na frente de um plano de fundo colorido aleatoriamente, assim como quando executou o app diretamente no terminal do Cloud Shell. Atualize a página algumas vezes para ver que a cor aleatória do plano de fundo muda a cada vez que você acessa o app.

Parabéns! Agora você executou uma versão conteinerizada do seu app. Na próxima seção, sem tocar em uma linha de código, você vai transformar a imagem do contêiner em um app da Web de qualidade de produção.

5. Para a nuvem...

1b0665d94750ded6.gif

Agora que você já colocou o app em um contêiner, é hora de compartilhar essa maravilha com o resto do mundo. Por isso, vamos implantá-lo na nuvem. Mas você quer fazer mais do que apenas compartilhar. Você quer garantir que ele:

  • executa de maneira confiável: você recebe tolerância a falhas automática caso um computador que esteja executando seu app falhe
  • escalona automaticamente: seu app acompanha grandes níveis de tráfego e reduz automaticamente a pegada quando não está em uso.
  • minimiza seus custos, já que não cobra pelos recursos que você não está usando. Você paga apenas pelos recursos consumidos ao responder ao tráfego.
  • está acessível por um nome de domínio personalizado: você tem acesso a uma solução com um clique para atribuir um nome de domínio personalizado ao seu serviço
  • oferece um excelente tempo de resposta. As inicializações a frio são razoavelmente responsivas, mas é possível ajustar isso especificando uma configuração de instância mínima.
  • compatível com criptografia de ponta a ponta usando a segurança da Web SSL/TLS padrão. Ao implantar um serviço, você recebe criptografia da Web padrão e os certificados necessários correspondentes sem custo financeiro e automática.

Ao implantar seu app no Google Cloud Run, você tem tudo isso e muito mais.

Implantar o app no Cloud Run

Primeiro, vamos modificar o app para que você possa distinguir a revisão nova da antiga. Para isso, modifique o arquivo main.py para que a mensagem padrão mude de "Hello world!" para "Hello from Cloud Run!". Em outras palavras, mude esta linha em main.py de:

def say_hello(name="world"):

para isto:

def say_hello(name="from Cloud Run"):

O Cloud Run é regional, o que significa que a infraestrutura que executa seus serviços do Cloud Run está localizada em uma região específica e é gerenciada pelo Google para estar disponível de maneira redundante em todas as zonas dessa região. Na seção "Configurar" acima, você definiu uma região padrão usando a variável de ambiente REGION.

Recrie a imagem do contêiner e implante o aplicativo conteinerizado no Cloud Run com o seguinte comando:

gcloud builds submit --tag $TAG
gcloud run deploy "$APP"   \
  --image "$TAG"           \
  --platform "managed"     \
  --region "$REGION"       \
  --allow-unauthenticated
  • Também é possível definir uma região padrão com gcloud config set run/region $REGION.
  • A opção --allow-unauthenticated torna o serviço disponível publicamente. Para evitar solicitações não autenticadas, use --no-allow-unauthenticated.

A imagem especificada aqui é a imagem do Docker criada na última etapa. Graças ao serviço do Cloud Build, que armazenou a imagem resultante no Google Container Registry, o serviço do Cloud Run pode encontrá-la e implantá-la para você.

Aguarde alguns instantes até a implantação terminar. Em caso de sucesso, a linha de comando vai exibir o URL de serviço:

Deploying container to Cloud Run service [hello] in project [PROJECT_ID...
✓ Deploying new service... Done.                                   
  ✓ Creating Revision... Revision deployment finished. Waiting for health check...
  ✓ Routing traffic...
  ✓ Setting IAM Policy...
Done.
Service [hello] revision [hello-...] has been deployed and is serving 100 percent of traffic.
Service URL: https://hello-....a.run.app

Também é possível recuperar o URL do serviço com este comando:

gcloud run services describe hello  \
  --platform managed                \
  --region $REGION                  \
  --format "value(status.url)"

Algo assim vai aparecer:

https://hello-....a.run.app

Esse link é um URL dedicado, com segurança TLS, para seu serviço do Cloud Run. Esse link é permanente (desde que você não desative o serviço) e pode ser usado em qualquer lugar na Internet. Ele não usa o mecanismo de proxy do Cloud Shell mencionado anteriormente, que dependia de uma máquina virtual temporária.

Clique no Service URL destacado para abrir uma guia do navegador da Web com o app em execução. O resultado vai mostrar a mensagem "Hello from Cloud Run!" em frente a um plano de fundo colorido aleatoriamente.

Parabéns! Agora seu app está sendo executado na nuvem do Google. Sem precisar pensar nisso, seu app fica disponível publicamente, com criptografia TLS (HTTPS) e escalonamento automático para níveis incríveis de tráfego.

Mas acho que esse processo pode ser ainda mais fácil...

6. Criar o contêiner automaticamente

Isso tudo é muito legal, mas e se eu não quiser pensar em Dockerfiles e contêineres? E se, como a maioria dos desenvolvedores, eu quiser me concentrar em escrever o código do aplicativo e deixar que outra pessoa se preocupe em contêinerizar? Você está com sorte, porque o Cloud Run oferece suporte a um padrão de código aberto chamado Buildpacks, que existe exatamente para automatizar o processo de fabricação de um contêiner com base em uma coleção de arquivos de origem.

Em alguns casos, um desenvolvedor pode preferir usar um Dockerfile explícito, por exemplo, se quiser um alto grau de personalização na forma como o contêiner é criado. Mas, para casos comuns como este exercício, os buildpacks funcionam bem e evitam a necessidade de criar um Dockerfile manualmente. Vamos modificar seu código para usar buildpacks.

Primeiro, vamos modificar o app para que você possa distinguir a revisão nova da antiga. Para isso, modifique o arquivo main.py para que a mensagem padrão mude de "Hello from Cloud Run!" para "Hello from Cloud Run with Buildpacks!". Em outras palavras, mude esta linha em main.py de:

def say_hello(name="from Cloud Run"):

para isto:

def say_hello(name="from Cloud Run with Buildpacks"):

Agora vamos aproveitar os buildpacks criando um novo arquivo chamado Procfile. Crie esse arquivo no Cloud Editor e insira esta linha de texto:

web: python3 main.py

Isso informa ao sistema buildpack como executar seu app no contêiner gerado automaticamente. Com essa instrução, você nem precisa mais de um Dockerfile. Para verificar isso, exclua o Dockerfile e execute o seguinte comando no terminal do Cloud Shell:

gcloud beta run deploy "$APP"  \
    --source .                 \
    --platform "managed"       \
    --region "$REGION"         \
    --allow-unauthenticated

Isso é semelhante ao comando que você executou para implantar o app na última etapa, mas desta vez você substituiu a opção --image pela opção --source .. Isso informa ao comando gcloud que você quer usar buildpacks para criar a imagem do contêiner com base nos arquivos de origem encontrados no diretório atual (dot em --source . é uma abreviação do diretório atual). Como o serviço cuida da imagem do contêiner implicitamente, não é necessário especificar uma imagem nesse comando gcloud.

Mais uma vez, verifique se essa implantação funcionou clicando no Service URL destacado para abrir uma guia do navegador da Web no seu app em execução e confira se o serviço está mostrando "Hello from Cloud Run with Buildpacks!" em frente a um plano de fundo colorido aleatoriamente.

Ao usar buildpacks para fabricar seu Dockerfile, você reduziu as três etapas fáceis para duas:

  1. Crie um app no ambiente de desenvolvimento.
  2. Implante o mesmo código na nuvem com um comando.

7. Preciso usar a linha de comando?

Não! Como quase todos os serviços do Google Cloud, há três maneiras de interagir com o Cloud Run:

  • A ferramenta de linha de comando gcloud, que você acabou de conhecer.
  • Uma interface de usuário da Web avançada, pelo console do Cloud, que oferece suporte a um estilo de interação intuitivo de apontar e clicar.
  • Programaticamente, usando as bibliotecas de cliente do Google disponíveis para muitas linguagens conhecidas, incluindo Java, C#, Python, Go, Javascript, Ruby, C/C++ e outras.

Vamos implantar outra instância do seu app do Cloud Run usando a interface do console. Acesse a página de destino do serviço do Cloud Run pelo menu no canto superior esquerdo:

e2b4983b38c81796.png

Em seguida, você vai ver um resumo dos seus serviços do Cloud Run, como este:

b335e7bf0a3af845.png

Clique no link "Criar serviço" para iniciar o processo de implantação:

51f61a8ddc7a4c0b.png

Insira "hello-again" como o nome do serviço, aceite a plataforma e a região de implantação padrão e clique em "Próxima".

8a17baa45336c4c9.png

Insira este URL para a imagem do contêiner: gcr.io/cloudrun/hello, que é um contêiner criado pelo Google para fins de teste. Clique no menu suspenso "Configurações avançadas" para conferir algumas das muitas configurações disponíveis. Para destacar apenas alguns que você pode personalizar:

  • número da porta e ponto de entrada do contêiner (que vai substituir o ponto de entrada especificado ao criar o contêiner)
  • hardware: memória e número de CPUs
  • escalonamento: instâncias mínimas e máximas
  • variáveis de ambiente
  • outros: configuração de tempo limite da solicitação, número máximo de solicitações por contêiner, HTTP/2

Clique no botão "Próxima" para avançar a caixa de diálogo. A próxima caixa de diálogo permite especificar como o serviço é acionado. Em "Entrada", selecione "Permitir todo o tráfego" e, em "Autenticação", selecione "Permitir tráfego não autenticado".

e78281d1cff3418.png

Essas são as configurações mais permissivas, já que permitem que qualquer pessoa acesse seu app do Cloud Run de qualquer lugar na Internet pública, sem especificar credenciais de autenticação. Talvez você queira configurações mais restritivas para seu app, mas vamos simplificar para este exercício de aprendizado.

Agora clique no botão Create para criar o serviço do Cloud Run. Depois de alguns segundos, o novo serviço vai aparecer na lista de resumo dos serviços do Cloud Run. A linha de resumo fornece a implantação mais recente (data/hora e por quem) junto com algumas configurações principais. Clique no link do nome do serviço para acessar os detalhes do novo serviço.

Para verificar seu serviço, clique no URL mostrado na parte de cima da página de resumo, como destacado no exemplo abaixo:

6c35cf0636dddc51.png

Você verá algo como:

3ba6ab4fe0da1f84.png

Agora que você implantou um novo serviço do Cloud Run, selecione a guia REVISIONS para conferir algumas maneiras de gerenciar várias implantações.

2351ee7ec4a356f0.png

Para implantar novas revisões diretamente do console, clique no botão EDIT & DEPLOY NEW REVISION, conforme destacado na captura de tela de exemplo abaixo:

a599fa88d00d6776.png

Clique nesse botão agora para criar uma nova revisão. Perto do URL do contêiner, clique no botão SELECT, como mostrado abaixo:

5fd1b1f8e1f11d40.png

Na caixa de diálogo que aparece, encontre o app da Web simples que você implantou no Cloud Build usando Buildpacks e clique em "Selecionar". Escolha a imagem do contêiner em

gcr.io/<project>/cloud-run-source-deploy

pasta , assim:

8a756c6157face3a.png

Depois de selecionar, role a tela para baixo e clique no botão DEPLOY. Agora você implantou uma nova revisão do app. Para verificar, acesse novamente o URL do serviço e confira se o web app colorido "Hello from Cloud Run with Buildpacks!" está aparecendo.

Como você pode ver, a guia "Revisões" fornece um resumo de cada revisão implantada, e agora você verá duas revisões para esse serviço. Para selecionar uma revisão, clique no botão de opção à esquerda do nome dela. Um resumo dos detalhes vai aparecer no lado direito da tela. Ao selecionar esses botões, você pode ver que as duas revisões são derivadas de duas imagens de contêiner diferentes.

O botão MANAGE TRAFFIC permite modificar a distribuição de solicitações recebidas enviadas a uma determinada revisão. Essa capacidade de ajustar a quantidade de tráfego enviada a uma determinada revisão permite vários casos de uso valiosos:

  • teste canário de uma nova versão do app com uma pequena parte do tráfego de entrada
  • reverter o tráfego de uma versão problemática para uma revisão anterior
  • Teste A/B

Encontre o botão MANAGE TRAFFIC aqui:

519d3c22ae028287.png

Configure uma divisão de tráfego de 50/50 entre as duas revisões especificando uma divisão de tráfego de 50/50 assim:

8c37d4f115d9ded4.png

Agora clique no botão "SALVAR" e verifique a divisão 50/50 acessando o URL do serviço repetidamente. Confira se, em média, metade das solicitações é atendida pela revisão atual ("Hello from Cloud Run with Buildpacks!") e metade pela revisão anterior ("It's running!").

Outras guias na página de detalhes do serviço oferecem a capacidade de monitorar a performance, o tráfego e os registros, que fornecem insights valiosos sobre o desempenho do serviço. Você também pode ajustar o acesso ao serviço na guia "Permissões". Reserve alguns minutos para explorar as guias nesta página e conhecer os recursos disponíveis.

Interface programática

Como observado anteriormente, também é possível criar, implantar e gerenciar os serviços do Cloud Run de maneira programática. Para tarefas manuais, essa opção é mais avançada do que a linha de comando ou o console da Web, mas é definitivamente a melhor maneira de automatizar os serviços do Cloud Run. Você pode usar as bibliotecas de cliente do Google em várias linguagens de programação conhecidas.

8. Testar o app

198ada162d1f0bf1.png

Nesta etapa final, você vai executar um teste de carga artificial para teste de estresse do app e observar como ele é escalonado com a demanda recebida. Você vai usar uma ferramenta chamada hey, que vem pré-instalada no Cloud Shell e permite executar testes de carga e apresentar os resultados.

Executar o teste

No terminal do Cloud Shell, execute este comando para fazer um teste de carga:

hey -q 1000 -c 200 -z 30s https://hello-...run.app

Os argumentos de comando são interpretados da seguinte forma:

  • -q 1000: tente direcionar a carga para aproximadamente 1.000 solicitações por segundo.
  • -c 200: alocar 200 trabalhadores paralelos
  • -z 30s: execute o teste de carga por 30 segundos.
  • use o URL do serviço como o último argumento nesta linha de comando

Os resultados do teste vão ficar assim:

 Summary:
 Total:        30.2767 secs
 Slowest:      3.3633 secs
 Fastest:      0.1071 secs
 Average:      0.1828 secs
 Requests/sec: 1087.2387
 Total data:   3028456 bytes
 Size/request: 92 bytes

Response time histogram:
 0.107 [1]     |
 0.433 [31346] |■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
 0.758 [1472]  |■■
 1.084 [82]    |
 1.410 [4]     |
...

Latency distribution:
...
 50% in 0.1528 secs
 75% in 0.1949 secs
 90% in 0.2442 secs
 95% in 0.4052 secs
 99% in 0.7062 secs

Details (average, fastest, slowest):
...
 req write:    0.0000 secs, 0.0000 secs, 0.0232 secs
 resp wait:    0.1824 secs, 0.1070 secs, 3.2953 secs
 resp read:    0.0000 secs, 0.0000 secs, 0.0010 secs
Status code distribution:
 [200] 32918 responses

Esse resumo informa vários itens de interesse:

  • 32.918 solicitações foram enviadas a aproximadamente 1.000 por segundo durante 30 segundos.
  • Não houve erros (apenas respostas HTTP 200).
  • A latência média foi de 180 ms.
  • A latência mínima foi de 107 ms, e o pior caso foi de 3,3 s
  • A latência do 90º percentil foi de 244 ms.

Se você marcar a guia METRICS no console do Cloud Run, poderá ver o lado do servidor da história de desempenho:

e635c6831c468dd3.png

9. Como fazer a limpeza

O Cloud Run não gera custos quando o serviço não está em uso, mas você ainda vai receber cobranças pelo armazenamento da imagem de contêiner que você criou.

Para evitar cobranças, exclua seu projeto do GCP para interromper o faturamento de todos os recursos usados nesse projeto ou exclua sua imagem de contêiner usando este comando:

gcloud container images delete $TAG

Para excluir os serviços do Cloud Run, use estes comandos:

gcloud run services delete hello --platform managed --region $REGION --quiet
gcloud run services delete hello-again --platform managed --region $REGION --quiet

10. Você conseguiu!

9a31f4fdbbf1ddcb.png

Parabéns! Você criou e implantou um app de produção do Cloud Run. Ao longo do processo, você aprendeu sobre contêineres e como criar o seu próprio. Você também viu como é fácil implantar seu app com o Cloud Run usando a ferramenta de linha de comando gcloud e o Console do Cloud. Agora você sabe como compartilhar suas criações incríveis com o mundo todo.

Quero deixar uma pergunta importante:

Depois que o app começou a funcionar no ambiente de desenvolvimento, quantas linhas de código você precisou modificar para implantá-lo na nuvem, com todos os atributos de nível de produção oferecidos pelo Cloud Run?

A resposta, é claro, é zero. :)

Codelabs para conferir...

Outros recursos legais para conhecer...

Documentos de referência…

11. Call-to-action

Logotipo do Google Cloud

Se você gostou deste codelab e quer passar mais tempo praticando com o Google Cloud, participe do Google Cloud Innovators hoje mesmo!

Logotipo do selo de membro do programa Innovators

O Google Cloud Innovators é sem custo financeiro e inclui:

  • Discussões ao vivo, AMAs e sessões de roteiro para saber as últimas novidades direto dos Googlers
  • as últimas notícias do Google Cloud direto na sua caixa de entrada
  • Selo digital e plano de fundo de videoconferência
  • 500 créditos de laboratórios e aprendizado no Skills Boost

Clique aqui para se inscrever.