1. Visão geral
Introdução
Neste codelab, você vai aprender a implantar um serviço do Cloud Run que usa vários contêineres. Você vai criar um app node.js que será usado como o contêiner de entrada do Cloud Run e outro app node.js que será usado como um sidecar.
Visão geral técnica
Ao usar vários contêineres em uma instância do Cloud Run, um deles é usado como o principal para entrada da Web. Os contêineres adicionais são chamados de sidecars.
Há duas maneiras de vários contêineres se comunicarem entre si:
- Os contêineres compartilham a interface de rede localhost. Assim, todos podem escutar uma porta, por exemplo, localhost:porta.
- Também é possível usar volumes na memória e montá-los nos contêineres para compartilhar arquivos.
Casos de uso
Como todos os contêineres na instância do Cloud Run compartilham a interface de rede localhost, é possível usar um sidecar na frente do contêiner principal para fazer proxy de solicitações. Esses proxies podem fornecer uma camada extra de abstração para um fluxo de tráfego mais eficiente para o aplicativo entre o cliente e os servidores, interceptando solicitações e encaminhando-as para o endpoint apropriado. Por exemplo, use a imagem oficial do Nginx do DockerHub, conforme mostrado aqui.
Como vários contêineres podem se comunicar compartilhando arquivos por volumes compartilhados, você adiciona vários aplicativos secundários ao seu serviço. Por exemplo, é possível instrumentar o serviço do Cloud Run para usar agentes personalizados, como o OpenTelemetry, e exportar registros, métricas e rastreamentos (exemplo do OpenTelemetry). Outro exemplo é usar um sidecar para se conectar a um banco de dados PostgreSQL do Cloud Spanner (exemplo do Cloud Spanner Postgress).
Exemplos neste codelab
Neste codelab, você vai implantar um serviço do Cloud Run em que o contêiner de entrada se comunica com um sidecar por uma porta localhost. Em seguida, você vai atualizar o contêiner de entrada e o arquivo secundário para compartilhar um arquivo usando uma montagem de volume.
O que você vai aprender
- Como criar um contêiner que usa um sidecar
- Como um contêiner de entrada pode se comunicar com um arquivo secundário usando o localhost
- Como um contêiner de entrada e um secundário podem compartilhar um arquivo por um volume montado
2. Configuração e requisitos
Pré-requisitos
- Você fez login no console do Cloud.
- Você já implantou um serviço do Cloud Run. Por exemplo, siga o guia de início rápido para implantar um serviço da Web usando o código-fonte.
Ativar o Cloud Shell
- No Console do Cloud, clique em Ativar o Cloud Shell
.

Se esta for a primeira vez que você inicia o Cloud Shell, uma tela intermediária vai aparecer com a descrição dele. Se isso acontecer, clique em Continuar.

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

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. Neste codelab, quase todo o trabalho pode ser feito com um navegador.
Depois de se conectar ao Cloud Shell, você vai ver que sua conta já está autenticada e que o projeto está configurado com o ID do seu projeto.
- Execute o seguinte comando no Cloud Shell para confirmar se a conta está autenticada:
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`
- 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].
3. Criar o app de entrada
Definir variáveis de ambiente
Neste codelab, você vai criar algumas variáveis de ambiente para melhorar a legibilidade dos comandos gcloud usados.
REGION=<YOUR-REGION> PROJECT_ID=<YOUR-PROJECT-ID> SERVICE_NAME=sidecar-codelab REPO_NAME=sidecar-codelab
Crie um repositório do Artifact Registry para armazenar as imagens de contêiner.
Você pode criar um repositório no Artifact Registry para armazenar as imagens de contêiner deste codelab.
gcloud artifacts repositories create $REPO_NAME --repository-format=docker \ --location=$REGION --description="sidecar codelab"
Em seguida, crie um arquivo package.json com o seguinte conteúdo:
{
"name": "sidecar-codelab",
"version": "1.0.0",
"private": true,
"description": "demonstrates how to use sidecars in cloud run",
"main": "index.js",
"author": "Google LLC",
"license": "Apache-2.0",
"scripts": {
"start": "node ingress.js"
},
"dependencies": {
"axios": "^1.6.2",
"express": "^4.18.2"
}
}
Agora crie um arquivo chamado ingress.js com o conteúdo a seguir:
const express = require('express');
const app = express();
const axios = require("axios");
app.get('/', async (req, res) => {
let response = await axios.get("http://localhost:5000");
res.send("The sidecar says: " + response.data);
});
const port = parseInt(process.env.PORT) || 8080;
app.listen(port, () => {
console.log(`Ingress container listening on port ${port}`);
});
Criar um Dockerfile para o contêiner de entrada
FROM node:20.10.0-slim WORKDIR /usr/src/app COPY package*.json ./ RUN npm install --production # Copy local code to the container image. COPY . . # Run the web service on container startup. ENV PORT=8080 CMD [ "npm", "start" ]
E crie um arquivo ``.dockerignore` para o contêiner de entrada.
# Exclude locally installed dependencies node_modules/ # Exclude "build-time" ignore files. .dockerignore .gcloudignore # Exclude git history and configuration. .gitignore
Agora você pode criar a imagem do contêiner de entrada executando o seguinte comando:
gcloud builds submit --tag $REGION-docker.pkg.dev/$PROJECT_ID/$REPO_NAME/ingress:latest
4. Criar o app sidecar
Nesta seção, você vai criar um segundo app Node.js que será usado como sidecar no serviço do Cloud Run.
Navegue até o diretório do sidecar.
cd ../sidecar
Crie um arquivo package.json com o seguinte conteúdo:
{
"name": "sidecar-codelab",
"version": "1.0.0",
"private": true,
"description": "demonstrates how to use sidecars in cloud run",
"main": "index.js",
"author": "Google LLC",
"license": "Apache-2.0",
"scripts": {
"start": "node sidecar.js"
},
"dependencies": {
"axios": "^1.6.2",
"express": "^4.18.2"
}
}
Agora crie um arquivo chamado sidecar.js com o conteúdo a seguir:
const express = require('express');
const app = express();
app.get('/', async (req, res) => {
res.send("Hello ingress container! I'm the sidecar.");
});
const port = parseInt(process.env.PORT || 5000);
app.listen(port, () => {
console.log(`Sidecar container listening on port ${port}`);
});
Criar um Dockerfile para o contêiner secundário
FROM node:20.10.0-slim WORKDIR /usr/src/app COPY package*.json ./ RUN npm install --production # Copy local code to the container image. COPY . . # Run the web service on container startup. ENV PORT=5000 CMD [ "npm", "start" ]
E crie um arquivo ``.dockerignore` para o contêiner secundário.
# Exclude locally installed dependencies node_modules/ # Exclude "build-time" ignore files. .dockerignore .gcloudignore # Exclude git history and configuration. .gitignore
Agora você pode criar a imagem do contêiner de entrada executando o seguinte comando:
gcloud builds submit --tag $REGION-docker.pkg.dev/$PROJECT_ID/$REPO_NAME/sidecar:latest
Implantar o serviço do Cloud Run
Você vai implantar o serviço do Cloud Run usando um arquivo YAML.
Navegue até o diretório principal.
cd ..
Crie um arquivo chamado sidecar-codelab.yaml com o conteúdo a seguir.
apiVersion: serving.knative.dev/v1
kind: Service
metadata:
annotations:
name: sidecar-codelab
labels:
cloud.googleapis.com/location: "<YOUR_REGION>"
spec:
template:
spec:
containers:
- image: "<YOUR_REGION>-docker.pkg.dev/<YOUR_PROJECT_ID>/sidecar-codelab/ingress:latest"
ports:
- containerPort: 8080
- image: "<YOUR_REGION>-docker.pkg.dev/<YOUR_PROJECT_ID>/sidecar-codelab/sidecar:latest"
env:
- name: PORT
value: "5000"
Em seguida, implante o serviço usando o seguinte comando. É necessário usar o gcloud beta porque as montagens de volume estão em prévia pública.
gcloud beta run services replace sidecar-codelab.yaml
Depois da implantação, salve o URL do serviço em uma variável de ambiente.
SERVICE_URL=$(gcloud run services describe $SERVICE_NAME --platform managed --region $REGION --format 'value(status.url)')
5. Chamar o serviço do Cloud Run
Agora você pode chamar seu serviço fornecendo o token de identidade.
curl -X GET -H "Authorization: Bearer $(gcloud auth print-identity-token)" ${SERVICE_URL}
Os resultados serão parecidos com este exemplo:
The sidecar says: Hello ingress container! I'm the sidecar.
6. Compartilhar um arquivo usando uma montagem de volume
Nesta seção, você vai atualizar os contêineres para compartilhar um arquivo usando uma montagem de volume. Neste exemplo, o contêiner de entrada vai gravar em um arquivo em um volume compartilhado. O sidecar vai ler o arquivo e retornar o conteúdo dele ao contêiner de entrada.
Primeiro, atualize o código do contêiner de entrada. Navegue até o diretório "ingress".
cd ../ingress
e substitua o conteúdo do arquivo ingress.js pelo seguinte:
const express = require('express');
const app = express();
const fs = require('fs');
const axios = require("axios");
const filename = "test.txt"
let path = "/my-volume-mount";
app.use(path, express.static(path));
try {
fs.writeFileSync(`${path}/${filename}`, "The ingress container created this file.");
} catch (err) {
console.error(err);
}
app.get('/', async (req, res) => {
let response = await axios.get("http://localhost:5000");
res.send("The sidecar says: " + response.data);
});
const port = parseInt(process.env.PORT) || 8080;
app.listen(port, () => {
console.log(`Ingress container listening on port ${port}`);
});
E crie a nova imagem para o contêiner de entrada executando o seguinte comando:
gcloud builds submit --tag $REGION-docker.pkg.dev/$PROJECT_ID/$REPO_NAME/ingress:latest
Agora, navegue até o diretório sidecar:
cd ../sidecar
Atualize sidecar.js com o seguinte conteúdo:
const express = require('express');
const app = express();
const fs = require('fs');
const filename = "test.txt"
let path = "/my-volume-mount";
app.use(path, express.static(path));
async function readFile() {
try {
return await fs.readFileSync(`${path}/${filename}`, { encoding: 'utf8' });
} catch (err) {
console.log(err);
}
}
app.get('/', async (req, res) => {
let contents = await readFile();
res.send(contents);
});
const port = parseInt(process.env.PORT || 5000);
app.listen(port, () => {
console.log(`Sidecar container listening on port ${port}`);
});
E crie a nova imagem para o contêiner secundário executando o seguinte comando:
gcloud builds submit --tag $REGION-docker.pkg.dev/$PROJECT_ID/$REPO_NAME/sidecar:latest
Atualize o sidecar-codelab.yaml com o seguinte para compartilhar um volume:
apiVersion: serving.knative.dev/v1
kind: Service
metadata:
annotations:
name: sidecar-codelab
labels:
cloud.googleapis.com/location: "<YOUR_REGION>"
spec:
template:
spec:
containers:
- image: "<YOUR_REGION>-docker.pkg.dev/<YOUR_PROJECT_ID>/sidecar-codelab/ingress:latest"
ports:
- containerPort: 8080
volumeMounts:
- mountPath: /my-volume-mount
name: in-memory-1
- image: "<YOUR_REGION>-docker.pkg.dev/<YOUR_PROJECT_ID>/sidecar-codelab/sidecar:latest"
env:
- name: PORT
value: "5000"
volumeMounts:
- mountPath: /my-volume-mount
name: in-memory-1
volumes:
- emptyDir:
medium: Memory
name: in-memory-1
Implante o arquivo sidecar-codelab.yaml atualizado
gcloud beta run services replace sidecar-codelab.yaml
Agora você pode chamar seu serviço fornecendo o token de identidade.
curl -X GET -H "Authorization: Bearer $(gcloud auth print-identity-token)" ${SERVICE_URL}
Os resultados serão parecidos com este exemplo:
The sidecar says: the ingress container created this file.
7. Parabéns!
Parabéns por concluir o codelab!
Recomendamos revisar a documentação do Cloud Run, especificamente sobre implantação de multicontêineres e uso de montagens de volume na memória.
O que vimos
- Como criar um contêiner que usa um sidecar
- Como um contêiner de entrada pode se comunicar com um arquivo secundário usando o localhost
- Como um contêiner de entrada e um secundário podem compartilhar um volume montado
8. Limpar
Para evitar cobranças acidentais, por exemplo, se essa função do Cloud for invocada mais vezes do que sua alocação mensal de invocações do Cloud Run no nível sem custo financeiro, exclua o serviço do Cloud Run ou o projeto criado na etapa 2.
Para excluir a função do Cloud, acesse o console do Cloud Functions em https://console.cloud.google.com/run/ e exclua o serviço sidecar-codelab (ou $SERVICE_NAME se você usou um nome diferente).
Se você quiser excluir todo o projeto, acesse https://console.cloud.google.com/cloud-resource-manager, selecione o projeto criado na Etapa 2 e escolha "Excluir". Se você excluir o projeto, vai precisar mudar de projeto no SDK Cloud. Para conferir a lista de todos os projetos disponíveis, execute gcloud projects list.