Создайте сервис Cloud Run с коляской

1. Обзор

Введение

В этом практическом занятии вы узнаете, как развернуть сервис Cloud Run , использующий несколько контейнеров . Вы создадите приложение Node.js, которое будет использоваться в качестве контейнера Ingress для Cloud Run, и дополнительное приложение Node.js, которое будет использоваться в качестве сайдкара.

Технический обзор

При использовании нескольких контейнеров в рамках экземпляра Cloud Run один контейнер используется в качестве основного контейнера для входящего веб-трафика. Один или несколько дополнительных контейнеров называются сайдкарами.

Существует два способа взаимодействия нескольких контейнеров друг с другом:

  1. Контейнеры используют общий сетевой интерфейс localhost, поэтому все контейнеры могут прослушивать порт, например, localhost:port.
  2. Также можно использовать тома в оперативной памяти и монтировать их на контейнеры для обмена файлами.

Варианты использования

Поскольку все контейнеры в экземпляре Cloud Run используют общий сетевой интерфейс localhost, вы можете использовать sidecar-контейнер перед основным контейнером для проксирования запросов. Такие прокси могут обеспечить дополнительный уровень абстракции для более эффективного потока трафика к приложению между клиентом и серверами, перехватывая запросы и перенаправляя их на соответствующую конечную точку. В качестве примера можно использовать официальный образ Nginx из DockerHub (как показано здесь ).

Поскольку несколько контейнеров могут взаимодействовать, обмениваясь файлами через общие тома , вы можете добавить к своему сервису различные вспомогательные приложения. Например, вы можете настроить свой сервис Cloud Run на использование пользовательских агентов, таких как OpenTelemetry, для экспорта журналов, метрик и трассировок ( пример OpenTelemetry ). Другой пример — использование вспомогательного приложения для подключения к базе данных Cloud Spanner PostgreSQL ( пример Cloud Spanner PostgreSQL ).

Примеры в этом практическом занятии.

В этом практическом задании вы сначала развернете сервис Cloud Run, в котором его контейнер ingress будет взаимодействовать с контейнером sidecar через порт localhost. Затем вы обновите контейнер ingress и контейнер sidecar, чтобы они совместно использовали файл через монтирование тома.

Что вы узнаете

  • Как создать контейнер, использующий сайдкар
  • Как контейнер Ingress может взаимодействовать с сайдкаром, используя localhost
  • Как контейнер ingress и sidecar могут совместно использовать файл через смонтированный том

2. Настройка и требования

Предварительные требования

Активировать Cloud Shell

  1. В консоли Cloud нажмите «Активировать Cloud Shell» . d1264ca30785e435.png .

cb81e7c8e34bc8d.png

Если вы запускаете Cloud Shell впервые, вам будет показан промежуточный экран с описанием его возможностей. Если вам был показан промежуточный экран, нажмите «Продолжить» .

d95252b003979716.png

Подготовка и подключение к Cloud Shell займут всего несколько минут.

7833d5e1c5d18f54.png

Эта виртуальная машина оснащена всеми необходимыми инструментами разработки. Она предоставляет постоянный домашний каталог объемом 5 ГБ и работает в облаке Google, что значительно повышает производительность сети и аутентификацию. Большая часть, если не вся, ваша работа в этом практическом задании может быть выполнена с помощью браузера.

После подключения к Cloud Shell вы увидите, что прошли аутентификацию и что проект настроен на ваш идентификатор проекта.

  1. Выполните следующую команду в Cloud Shell, чтобы подтвердить свою аутентификацию:
gcloud auth list

вывод команды

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

To set the active account, run:
    $ gcloud config set account `ACCOUNT`
  1. Выполните следующую команду в Cloud Shell, чтобы убедиться, что команда gcloud знает о вашем проекте:
gcloud config list project

вывод команды

[core]
project = <PROJECT_ID>

Если это не так, вы можете установить это с помощью следующей команды:

gcloud config set project <PROJECT_ID>

вывод команды

Updated property [core/project].

3. Создайте приложение Ingress.

Установка переменных среды

В этом практическом задании вы создадите несколько переменных окружения для улучшения читаемости команд gcloud , используемых в этом задании.

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

SERVICE_NAME=sidecar-codelab
REPO_NAME=sidecar-codelab

Создайте репозиторий ArtifactRegistry для хранения образов ваших контейнеров.

Вы можете создать репозиторий в Artifact Registry для хранения образов контейнеров, необходимых для этого практического занятия.

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

Затем создайте файл package.json со следующим содержимым:

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

Теперь создайте файл с именем ingress.js со следующим содержимым:

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

Создайте Dockerfile для контейнера Ingress.

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

И создайте файл `.dockerignore` для контейнера ingress.

# Exclude locally installed dependencies
node_modules/

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

# Exclude git history and configuration.
.gitignore

Теперь вы можете создать образ для своего контейнера Ingress, выполнив следующую команду:

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

4. Создайте вспомогательное приложение.

В этом разделе вы создадите второе приложение Node.js, которое будет использоваться в качестве вспомогательного приложения (sidecar) в сервисе Cloud Run.

Перейдите в каталог sidecar.

cd ../sidecar

Создайте файл package.json со следующим содержимым:

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

Теперь создайте файл с именем sidecar.js со следующим содержимым:

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

Создайте Dockerfile для контейнера sidecar.

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

И создайте файл `.dockerignore` для контейнера sidecar.

# Exclude locally installed dependencies
node_modules/

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

# Exclude git history and configuration.
.gitignore

Теперь вы можете создать образ для своего контейнера Ingress, выполнив следующую команду:

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

Разверните службу Cloud Run.

Развертывание сервиса Cloud Run будет осуществляться с помощью YAML-файла.

Перейдите в родительский каталог.

cd ..

Создайте файл с именем sidecar-codelab.yaml со следующим содержимым:

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"

Затем разверните службу, используя следующую команду. Вам необходимо использовать бета-версию gcloud, поскольку функция монтирования томов находится в стадии публичного предварительного просмотра.

gcloud beta run services replace sidecar-codelab.yaml

После развертывания сохраните URL-адрес сервиса в переменной среды.

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

5. Вызовите службу Cloud Run.

Теперь вы можете вызвать свою службу, предоставив свой идентификационный токен.

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

Ваши результаты должны выглядеть примерно так, как в приведенном ниже примере:

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

6. Предоставьте общий доступ к файлу через монтирование тома.

В этом разделе вы обновите контейнеры, чтобы они могли совместно использовать файл через монтирование тома. В этом примере контейнер ingress будет записывать данные в файл на общем томе. Sidecar будет читать файл и возвращать его содержимое обратно контейнеру ingress.

Сначала обновите код контейнера ingress. Перейдите в каталог ingress.

cd ../ingress

Затем замените содержимое файла ingress.js следующим:

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

Создайте новый образ для вашего контейнера Ingress, выполнив следующую команду:

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

Теперь перейдите в каталог sidecar:

cd ../sidecar

И обновите sidecar.js , добавив следующее содержимое:

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

Создайте новый образ для вашего контейнера-сайдкара, выполнив следующую команду:

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

Чтобы использовать общий том, обновите файл sidecar-codelab.yaml следующим образом:

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

Разверните обновленный файл sidecar-codelab.yaml

gcloud beta run services replace sidecar-codelab.yaml

Теперь вы можете вызвать свою службу, предоставив свой идентификационный токен.

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

Ваши результаты должны выглядеть примерно так, как в приведенном ниже примере:

The sidecar says: the ingress container created this file.

7. Поздравляем!

Поздравляем с завершением практического занятия!

Мы рекомендуем ознакомиться с документацией по Cloud Run , в частности, по развертыванию многоконтейнерных систем и использованию монтирования томов в оперативной памяти.

Что мы рассмотрели

  • Как создать контейнер, использующий сайдкар
  • Как контейнер Ingress может взаимодействовать с сайдкаром, используя localhost
  • Как въездной контейнер и боковой контейнер могут совместно использовать установленный объем

8. Уборка

Чтобы избежать непреднамеренных списаний средств (например, если эта облачная функция будет случайно вызвана больше раз, чем предусмотрено вашим ежемесячным лимитом вызовов Cloud Run в бесплатном тарифе ), вы можете либо удалить службу Cloud Run, либо удалить проект, созданный на шаге 2.

Чтобы удалить облачную функцию, перейдите в консоль облачных функций по адресу https://console.cloud.google.com/run/ и удалите службу sidecar-codelab (или переменную $SERVICE_NAME, если вы использовали другое имя).

Если вы решите удалить весь проект, перейдите по ссылке https://console.cloud.google.com/cloud-resource-manager , выберите проект, созданный на шаге 2, и нажмите «Удалить». После удаления проекта вам потребуется изменить проекты в вашем Cloud SDK. Список всех доступных проектов можно просмотреть, выполнив gcloud projects list .