Tworzenie usługi Cloud Run przy użyciu pliku pomocniczego

1. Omówienie

Wprowadzenie

Z tego ćwiczenia w Codelabs dowiesz się, jak wdrożyć usługę Cloud Run, która korzysta z wielu kontenerów. Utworzysz aplikację node.js, która będzie używana jako kontener ruchu przychodzącego w Cloud Run, oraz dodatkową aplikację node.js, która będzie używana jako aplikacja pomocnicza.

Omówienie techniczne

Jeśli w instancji Cloud Run używasz wielu kontenerów, 1 kontener jest używany jako główny kontener dla ruchu przychodzącego z internetu. Jeden lub więcej dodatkowych kontenerów są nazywane elementami pomocniczymi.

Kontenery mogą komunikować się ze sobą na 2 sposoby:

  1. Kontenery współdzielą interfejs sieciowy hosta lokalnego, więc wszystkie kontenery mogą nasłuchiwać portu, np. localhost:port.
  2. Aby udostępniać pliki, możesz też używać woluminów w pamięci i podłączać je w kontenerach.

Przypadki użycia

Wszystkie kontenery w instancji Cloud Run współdzielą interfejs sieciowy hosta lokalnego, dlatego do obsługi żądań do serwera proxy możesz używać pliku pomocniczego przed głównym kontenerem. Takie serwery proxy mogą zapewnić dodatkową warstwę abstrakcji, aby usprawnić przepływ ruchu do aplikacji między klientem a serwerami przez przechwytywanie żądań i przekazywanie ich do odpowiedniego punktu końcowego. Możesz na przykład użyć oficjalnego obrazu Nginx z DockerHub (jak pokazano tutaj).

Ponieważ wiele kontenerów może się komunikować przez udostępnianie plików za pomocą udostępnionych woluminów, musisz dodać do swojej usługi różne aplikacje pomocnicze. Możesz na przykład dostosować usługę Cloud Run do używania agentów niestandardowych, takich jak OpenTelemetry, do eksportowania logów, wskaźników i logów czasu (przykład OpenTelemetry). Innym przykładem jest użycie pomocniczego połączenia z bazą danych PostgreSQL Cloud Spanner (przykład Postgres w Cloud Spanner).

Przykłady w tym ćwiczeniu z programowania

W ramach tego ćwiczenia w Codelabs wdrożysz najpierw usługę Cloud Run, w której jej kontener ruchu przychodzącego komunikuje się z plikiem pomocniczym przez port lokalnego hosta. Następnie zaktualizujesz kontener ruchu przychodzącego i plik pomocniczy, aby udostępnić plik przez punkt montowania woluminu.

Czego się nauczysz

  • Jak utworzyć kontener wykorzystujący pomoc
  • Jak kontener ruchu przychodzącego może komunikować się z plikiem pomocniczym za pomocą lokalnego hosta
  • Jak kontener ruchu przychodzącego i plik pomocniczy mogą udostępniać plik za pomocą podłączonego woluminu

2. Konfiguracja i wymagania

Wymagania wstępne

Aktywowanie Cloud Shell

  1. W konsoli Cloud kliknij Aktywuj Cloud Shell d1264ca30785e435.png.

cb81e7c8e34bc8d.png

Jeśli uruchamiasz Cloud Shell po raz pierwszy, zobaczysz ekran pośredni z opisem tej usługi. Jeśli wyświetlił się ekran pośredni, kliknij Dalej.

d95252b003979716.png

Uzyskanie dostępu do Cloud Shell i połączenie się z nim powinno zająć tylko kilka chwil.

7833d5e1c5d18f54.png

Ta maszyna wirtualna ma wszystkie potrzebne narzędzia dla programistów. Zawiera stały katalog domowy o pojemności 5 GB i działa w Google Cloud, co znacznie zwiększa wydajność sieci i uwierzytelnianie. Większość zadań w ramach tego ćwiczenia z programowania można wykonać w przeglądarce.

Po nawiązaniu połączenia z Cloud Shell powinno pojawić się potwierdzenie, że użytkownik jest uwierzytelniony, a projekt jest ustawiony na identyfikator Twojego projektu.

  1. Uruchom to polecenie w Cloud Shell, aby potwierdzić, że jesteś uwierzytelniony:
gcloud auth list

Dane wyjściowe polecenia

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

To set the active account, run:
    $ gcloud config set account `ACCOUNT`
  1. Uruchom to polecenie w Cloud Shell, aby sprawdzić, czy polecenie gcloud zna Twój projekt:
gcloud config list project

Dane wyjściowe polecenia

[core]
project = <PROJECT_ID>

Jeśli tak nie jest, możesz go ustawić za pomocą tego polecenia:

gcloud config set project <PROJECT_ID>

Dane wyjściowe polecenia

Updated property [core/project].

3. Tworzenie aplikacji Ingress

Ustawianie zmiennych środowiskowych

W ramach tego ćwiczenia w Codelabs utworzysz kilka zmiennych środowiskowych, aby poprawić czytelność poleceń gcloud używanych w tym ćwiczeniu.

REGION=<YOUR-REGION>
PROJECT_ID=<YOUR-PROJECT-ID>

SERVICE_NAME=sidecar-codelab
REPO_NAME=sidecar-codelab

Tworzenie repozytorium ArtifactRegistry do przechowywania obrazów kontenerów

W tym ćwiczeniu z programowania możesz utworzyć repozytorium w Artifact Registry, w którym będziesz przechowywać obrazy kontenerów.

gcloud artifacts repositories create $REPO_NAME --repository-format=docker \
--location=$REGION --description="sidecar codelab"

Następnie utwórz plik package.json z tą zawartością:

{
  "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"
  }
}

Teraz utwórz plik o nazwie ingress.js z tą zawartością:

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}`);
});

Utwórz plik dockerfile dla kontenera ruchu przychodzącego

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" ]

Utwórz plik „.dockerignore” dla kontenera ruchu przychodzącego.

# Exclude locally installed dependencies
node_modules/

# Exclude "build-time" ignore files.
.dockerignore
.gcloudignore

# Exclude git history and configuration.
.gitignore

Teraz możesz utworzyć obraz kontenera ruchu przychodzącego, uruchamiając to polecenie:

gcloud builds submit --tag $REGION-docker.pkg.dev/$PROJECT_ID/$REPO_NAME/ingress:latest

4. Utwórz aplikację pomocniczą

W tej sekcji utworzysz drugą aplikację w Node.js, która będzie używana jako aplikacja pomocnicza w usłudze Cloud Run.

Przejdź do katalogu pomocniczego.

cd ../sidecar

Utwórz plik package.json o takiej zawartości:

{
  "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"
  }
}

Teraz utwórz plik o nazwie sidecar.js z tą zawartością:

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}`);
});

Utwórz plik Dockerfile dla kontenera pomocniczego

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" ]

Utwórz plik „.dockerignore” dla kontenera pomocniczego.

# Exclude locally installed dependencies
node_modules/

# Exclude "build-time" ignore files.
.dockerignore
.gcloudignore

# Exclude git history and configuration.
.gitignore

Teraz możesz utworzyć obraz kontenera ruchu przychodzącego, uruchamiając to polecenie:

gcloud builds submit --tag $REGION-docker.pkg.dev/$PROJECT_ID/$REPO_NAME/sidecar:latest

Wdrażanie usługi Cloud Run

Wdrożysz usługę Cloud Run za pomocą pliku yaml.

Przejdź do katalogu nadrzędnego.

cd ..

Utwórz plik o nazwie sidecar-codelab.yaml z tą zawartością:

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"

Następnie wdróż usługę za pomocą tego polecenia. Musisz użyć gcloud w wersji beta, ponieważ punkty montowania woluminu są dostępne w publicznej wersji przedpremierowej.

gcloud beta run services replace sidecar-codelab.yaml

Po wdrożeniu zapisz adres URL usługi w zmiennej środowiskowej.

SERVICE_URL=$(gcloud run services describe $SERVICE_NAME --platform managed --region $REGION --format 'value(status.url)') 

5. Wywoływanie usługi Cloud Run

Teraz możesz wywołać usługę, podając token tożsamości.

curl -X GET -H "Authorization: Bearer $(gcloud auth print-identity-token)" ${SERVICE_URL}

Twoje wyniki powinny wyglądać podobnie do tych poniżej:

The sidecar says: Hello ingress container! I'm the sidecar.

6. Udostępnianie pliku przez punkt montowania woluminu

W tej sekcji zaktualizujesz kontenery tak, aby udostępniały plik przez punkt montowania woluminu. W tym przykładzie kontener ruchu przychodzącego zapisze dane do pliku na woluminie współdzielonym. Plik pomocniczy odczyta plik i zwróci jego zawartość z powrotem do kontenera ruchu przychodzącego.

Najpierw zaktualizuj kod kontenera ruchu przychodzącego. Przejdź do katalogu ruchu przychodzącego.

cd ../ingress

, a następnie zastąp zawartość pliku ingress.js taką:

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}`);
});

Utwórz nowy obraz kontenera ruchu przychodzącego, uruchamiając to polecenie:

gcloud builds submit --tag $REGION-docker.pkg.dev/$PROJECT_ID/$REPO_NAME/ingress:latest

Teraz przejdź do katalogu pomocniczego:

cd ../sidecar

Zaktualizuj plik sidecar.js, dodając tę treść:

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}`);
});

Utwórz nowy obraz kontenera pomocniczego, uruchamiając to polecenie:

gcloud builds submit --tag $REGION-docker.pkg.dev/$PROJECT_ID/$REPO_NAME/sidecar:latest

Aby udostępnić wolumin, w sidecar-codelab.yaml podaj te dane:

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

Wdróż zaktualizowany plik sidecar-codelab.yaml

gcloud beta run services replace sidecar-codelab.yaml

Teraz możesz wywołać usługę, podając token tożsamości.

curl -X GET -H "Authorization: Bearer $(gcloud auth print-identity-token)" ${SERVICE_URL}

Twoje wyniki powinny wyglądać podobnie do tych poniżej:

The sidecar says: the ingress container created this file.

7. Gratulacje!

Gratulujemy ukończenia ćwiczeń z programowania.

Zalecamy zapoznanie się z dokumentacją Cloud Run, w szczególności dotyczącą wdrażania wielokontenerów i używania punktów montowania woluminów działających w pamięci.

Omówione zagadnienia

  • Jak utworzyć kontener wykorzystujący pomoc
  • Jak kontener ruchu przychodzącego może komunikować się z plikiem pomocniczym za pomocą lokalnego hosta
  • Jak kontener ruchu przychodzącego i plik pomocniczy mogą współdzielić podłączony wolumin

8. Czyszczenie danych

Aby uniknąć niezamierzonych opłat (na przykład jeśli ta funkcja w Cloud Functions została przypadkowo wywołana więcej razy niż miesięczna alokacja wywołań Cloud Run na poziomie bezpłatnym), możesz usunąć usługę Cloud Run lub projekt utworzony w kroku 2.

Aby usunąć funkcję w Cloud Functions, otwórz konsolę Cloud Functions w Cloud Functions na https://console.cloud.google.com/run/ i usuń usługę sidecar-codelab (lub nazwę usługi $SERVICE_NAME w przypadku użycia innej nazwy).

Jeśli zdecydujesz się usunąć cały projekt, możesz otworzyć stronę https://console.cloud.google.com/cloud-resource-manager, wybrać projekt utworzony w kroku 2 i kliknąć Usuń. Jeśli usuniesz projekt, musisz zmienić projekty w pakiecie SDK Cloud. Aby wyświetlić listę wszystkich dostępnych projektów, uruchom polecenie gcloud projects list.