Save the date - Google I/O returns May 18-20. Register to get the most out of the digital experience: Build your schedule, reserve space, participate in Q&As, earn Google Developer profile badges, and more. Register now
Эта страница переведена с помощью Cloud Translation API.
Switch to English

Обслуживайте динамический контент и размещайте микросервисы с помощью Cloud Run

Соедините Cloud Run с Firebase Hosting, чтобы создавать и обслуживать динамический контент или создавать REST API как микросервисы.

Используя Cloud Run , вы можете развернуть приложение, упакованное в образ контейнера. Затем, используя Firebase Hosting, вы можете направлять HTTPS-запросы для запуска вашего контейнерного приложения.

  • Cloud Run поддерживает несколько языков (включая Go, Node.js, Python и Java), что дает вам гибкость в использовании языка программирования и фреймворка по вашему выбору.
  • Cloud Run автоматически и горизонтально масштабирует образ вашего контейнера для обработки полученных запросов, а затем масштабируется при уменьшении спроса.
  • Вы платите только за процессор, память и сеть, потребляемые во время обработки запроса.

Например, примеры использования и примеры для Cloud Run, интегрированного с хостингом Firebase, см. В нашем обзоре бессерверных приложений .


В этом руководстве показано, как:

  1. Напишите простое приложение Hello World
  2. Поместите приложение в контейнер и загрузите его в Реестр контейнеров.
  3. Разверните образ контейнера в Cloud Run
  4. Прямые запросы хостинга к вашему контейнерному приложению

Обратите внимание, что для повышения производительности обслуживания динамического содержимого вы можете дополнительно настроить параметры кеширования .

Прежде чем вы начнете

Перед использованием Cloud Run вам необходимо выполнить некоторые начальные задачи, включая настройку учетной записи Cloud Billing, включение Cloud Run API и установку gcloud командной строки gcloud .

Настройте биллинг для вашего проекта

Cloud Run предлагает бесплатную квоту на использование , но вы все равно должны иметь учетную запись Cloud Billing, связанную с вашим проектом Firebase, чтобы использовать или опробовать Cloud Run.

Включите API и установите SDK

  1. Включите Cloud Run API в консоли Google API:

    1. Откройте страницу Cloud Run API в консоли Google API.

    2. При появлении запроса выберите проект Firebase.

    3. Нажмите Включить на странице Cloud Run API.

  2. Установите и инициализируйте Cloud SDK.

Установите бета-компонент gcloud

  1. Выполните следующую команду, чтобы установить бета-компонент gcloud :

    gcloud components install beta
  2. Компоненты обновления:

    gcloud components update
  3. Убедитесь, что инструмент gcloud настроен для правильного проекта:

    gcloud config list

Шаг 1. Напишите образец приложения

Обратите внимание, что Cloud Run поддерживает множество других языков в дополнение к языкам, показанным в следующем примере.

Идти

  1. Создайте новый каталог с именем helloworld-go , затем перейдите в него:

    mkdir helloworld-go
    cd helloworld-go
  2. Создайте новый файл с именем helloworld.go и добавьте следующий код:

    package main
    
    import (
    	"fmt"
    	"log"
    	"net/http"
    	"os"
    )
    
    func handler(w http.ResponseWriter, r *http.Request) {
    	log.Print("helloworld: received a request")
    	target := os.Getenv("TARGET")
    	if target == "" {
    		target = "World"
    	}
    	fmt.Fprintf(w, "Hello %s!\n", target)
    }
    
    func main() {
    	log.Print("helloworld: starting server...")
    
    	http.HandleFunc("/", handler)
    
    	port := os.Getenv("PORT")
    	if port == "" {
    		port = "8080"
    	}
    
    	log.Printf("helloworld: listening on port %s", port)
    	log.Fatal(http.ListenAndServe(fmt.Sprintf(":%s", port), nil))
    }
    

    Этот код создает базовый веб-сервер, который прослушивает порт, определенный переменной среды PORT .

Ваше приложение готово и готово к контейнерной обработке и загрузке в Реестр контейнеров.

Node.js

  1. Создайте новый каталог с именем helloworld-nodejs , затем перейдите в него:

    mkdir helloworld-nodejs
    cd helloworld-nodejs
  2. Создайте файл package.json со следующим содержимым:

    {
      "name": "knative-serving-helloworld",
      "version": "1.0.0",
      "description": "Simple hello world sample in Node",
      "main": "index.js",
      "scripts": {
        "start": "node index.js"
      },
      "author": "",
      "license": "Apache-2.0",
      "dependencies": {
        "express": "^4.16.4"
      }
    }
    
  3. Создайте новый файл с именем index.js и добавьте следующий код:

    const express = require('express');
    const app = express();
    
    app.get('/', (req, res) => {
      console.log('Hello world received a request.');
    
      const target = process.env.TARGET || 'World';
      res.send(`Hello ${target}!\n`);
    });
    
    const port = process.env.PORT || 8080;
    app.listen(port, () => {
      console.log('Hello world listening on port', port);
    });
    

    Этот код создает базовый веб-сервер, который прослушивает порт, определенный переменной среды PORT .

Ваше приложение готово и готово к контейнеризации и загрузке в Реестр контейнеров.

Python

  1. Создайте новый каталог с именем helloworld-python , затем перейдите в него:

    mkdir helloworld-python
    cd helloworld-python
  2. Создайте новый файл с именем app.py и добавьте следующий код:

    import os
    
    from flask import Flask
    
    app = Flask(__name__)
    
    @app.route('/')
    def hello_world():
        target = os.environ.get('TARGET', 'World')
        return 'Hello {}!\n'.format(target)
    
    if __name__ == "__main__":
        app.run(debug=True,host='0.0.0.0',port=int(os.environ.get('PORT', 8080)))
    

    Этот код создает базовый веб-сервер, который прослушивает порт, определенный переменной среды PORT .

Ваше приложение готово и готово к контейнеризации и загрузке в Реестр контейнеров.

Ява

  1. Установите Java SE 8 или новее JDK и CURL .

    Обратите внимание, что нам нужно сделать это только для создания нового веб-проекта на следующем шаге. Dockerfile, описанный ниже, загрузит все зависимости в контейнер.

  2. Из консоли создайте новый пустой веб-проект, используя cURL, затем распакуйте команды:

    curl https://start.spring.io/starter.zip \
        -d dependencies=web \
        -d name=helloworld \
        -d artifactId=helloworld \
        -o helloworld.zip
    unzip helloworld.zip

    Это создает проект SpringBoot.

  3. Обновите класс SpringBootApplication в src/main/java/com/example/helloworld/HelloworldApplication.java , добавив @RestController для обработки / сопоставления, а также добавьте поле @Value для предоставления переменной среды TARGET :

    package com.example.helloworld;
    
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    @SpringBootApplication
    public class HelloworldApplication {
    
      @Value("${TARGET:World}")
      String target;
    
      @RestController
      class HelloworldController {
        @GetMapping("/")
        String hello() {
          return "Hello " + target + "!";
        }
      }
    
      public static void main(String[] args) {
        SpringApplication.run(HelloworldApplication.class, args);
      }
    }
    

    Этот код создает базовый веб-сервер, который прослушивает порт, определенный переменной среды PORT .

Ваше приложение готово и готово к контейнеризации и загрузке в Реестр контейнеров.

Шаг 2. Создайте приложение в контейнере и загрузите его в реестр контейнеров.

  1. Dockerfile контейнер для примера приложения, создав новый файл с именем Dockerfile в том же каталоге, что и исходные файлы. Скопируйте следующий контент в свой файл.

    Идти

    # Use the official Golang image to create a build artifact.
    # This is based on Debian and sets the GOPATH to /go.
    FROM golang:1.13 as builder
    
    # Create and change to the app directory.
    WORKDIR /app
    
    # Retrieve application dependencies using go modules.
    # Allows container builds to reuse downloaded dependencies.
    COPY go.* ./
    RUN go mod download
    
    # Copy local code to the container image.
    COPY . ./
    
    # Build the binary.
    # -mod=readonly ensures immutable go.mod and go.sum in container builds.
    RUN CGO_ENABLED=0 GOOS=linux go build -mod=readonly -v -o server
    
    # Use the official Alpine image for a lean production container.
    # https://hub.docker.com/_/alpine
    # https://docs.docker.com/develop/develop-images/multistage-build/#use-multi-stage-builds
    FROM alpine:3
    RUN apk add --no-cache ca-certificates
    
    # Copy the binary to the production image from the builder stage.
    COPY --from=builder /app/server /server
    
    # Run the web service on container startup.
    CMD ["/server"]
    

    Node.js

    # Use the official lightweight Node.js 12 image.
    # https://hub.docker.com/_/node
    FROM node:12-slim
    
    # Create and change to the app directory.
    WORKDIR /usr/src/app
    
    # Copy application dependency manifests to the container image.
    # A wildcard is used to ensure both package.json AND package-lock.json are copied.
    # Copying this separately prevents re-running npm install on every code change.
    COPY package*.json ./
    
    # Install production dependencies.
    RUN npm install --only=production
    
    # Copy local code to the container image.
    COPY . ./
    
    # Run the web service on container startup.
    CMD [ "npm", "start" ]
    

    Python

    # Use the official lightweight Python image.
    # https://hub.docker.com/_/python
    FROM python:3.7-slim
    
    # Allow statements and log messages to immediately appear in the Knative logs
    ENV PYTHONUNBUFFERED True
    
    # Copy local code to the container image.
    ENV APP_HOME /app
    WORKDIR $APP_HOME
    COPY . ./
    
    # Install production dependencies.
    RUN pip install Flask gunicorn
    
    # Run the web service on container startup. Here we use the gunicorn
    # webserver, with one worker process and 8 threads.
    # For environments with multiple CPU cores, increase the number of workers
    # to be equal to the cores available.
    CMD exec gunicorn --bind :$PORT --workers 1 --threads 8 --timeout 0 app:app
    

    Ява

    # Use the official maven/Java 8 image to create a build artifact.
    # https://hub.docker.com/_/maven
    FROM maven:3.5-jdk-8-alpine as builder
    
    # Copy local code to the container image.
    WORKDIR /app
    COPY pom.xml .
    COPY src ./src
    
    # Build a release artifact.
    RUN mvn package -DskipTests
    
    # Use the Official OpenJDK image for a lean production stage of our multi-stage build.
    # https://hub.docker.com/_/openjdk
    # https://docs.docker.com/develop/develop-images/multistage-build/#use-multi-stage-builds
    FROM openjdk:8-jre-alpine
    
    # Copy the jar to the production image from the builder stage.
    COPY --from=builder /app/target/helloworld-*.jar /helloworld.jar
    
    # Run the web service on container startup.
    CMD ["java", "-Djava.security.egd=file:/dev/./urandom", "-jar", "/helloworld.jar"]
    

  2. Создайте образ контейнера с помощью Cloud Build, выполнив следующую команду из каталога, содержащего ваш Dockerfile:

    gcloud builds submit --tag gcr.io/PROJECT_ID/helloworld

    В случае успеха вы увидите сообщение УСПЕХ, содержащее имя изображения.
    ( gcr.io/ PROJECT_ID /helloworld ).

Образ контейнера теперь хранится в Реестре контейнеров и при желании может быть использован повторно.

Обратите внимание, что вместо Cloud Build вы можете использовать локально установленную версию Docker для локальной сборки вашего контейнера .

Шаг 3. Разверните образ контейнера в Cloud Run

  1. Разверните с помощью следующей команды:

    gcloud beta run deploy --image gcr.io/PROJECT_ID/helloworld

  2. При появлении запроса:

  3. Подождите несколько секунд, пока не завершится развертывание. В случае успеха в командной строке отображается URL-адрес службы. Например: https://helloworld- RANDOM_HASH -us-central1.a.run.app

  4. Посетите развернутый контейнер, открыв URL-адрес службы в веб-браузере.

На следующем шаге вы узнаете, как получить доступ к этому контейнерному приложению с URL-адреса хостинга Firebase, чтобы оно могло создавать динамический контент для вашего сайта, размещенного в Firebase.

Шаг 4. Направляйте запросы на хостинг вашему контейнерному приложению

С помощью правил перезаписи вы можете направлять запросы, соответствующие определенным шаблонам, в одно место назначения.

В следующем примере показано, как направить все запросы со страницы /helloworld на вашем хостинг-сайте для запуска и запуска вашего helloworld контейнера helloworld .

  1. Убедись в том, что:

    Подробные инструкции по установке интерфейса командной строки и инициализации хостинга см. В Руководстве по началу работы с хостингом .

  2. Откройте файл firebase.json .

  3. Добавьте следующую конфигурацию rewrite в раздел hosting :

    "hosting": {
      // ...
    
      // Add the "rewrites" attribute within "hosting"
      "rewrites": [ {
        "source": "**",
        "run": {
          "serviceId": "helloworld",  // "service name" (from when you deployed the container image)
          "region": "us-central1"     // optional (if omitted, default is us-central1)
        }
      } ]
    }
    
  4. Разверните конфигурацию хостинга на своем сайте, выполнив следующую команду из корня каталога проекта:

    firebase deploy

Теперь ваш контейнер доступен по следующим URL-адресам:

Посетите страницу конфигурации хостинга для получения более подробной информации о правилах перезаписи . Вы также можете узнать о порядке приоритета ответов для различных конфигураций хостинга.

Протестируйте локально

Во время разработки вы можете запустить и протестировать свой образ контейнера локально. Подробные инструкции см. В документации Cloud Run .

Следующие шаги