构建和部署 Shell 服务

了解如何创建简单的 Hello World 应用,将该应用打包到容器映像中,然后将该映像上传到 Container Registry 并部署到 Cloud Run。除了所示语言之外,您还可以使用其他语言。

准备工作

  1. 登录您的 Google Cloud 帐号。如果您是 Google Cloud 新手,请创建一个帐号来评估我们的产品在实际场景中的表现。新客户还可获享 $300 赠金,用于运行、测试和部署工作负载。
  2. 在 Google Cloud Console 的项目选择器页面上,选择或创建一个 Google Cloud 项目。

    转到“项目选择器”

  3. 确保您的 Cloud 项目已启用结算功能。 了解如何确认您的项目是否已启用结算功能

  4. 安装并初始化 Cloud SDK

编写示例应用

如需编写 Shell 应用,请执行以下操作:

  1. 创建名为 helloworld-shell 的新目录,并转到此目录中:

    mkdir helloworld-shell
    cd helloworld-shell
    
  2. 初始化 go.mod 文件以声明 go 模块

    module github.com/GoogleCloudPlatform/cloud-run-samples/helloworld-shell
    
    go 1.14
    

    您可以按上述格式直接创建 go.mod 文件,也可以使用以下命令从项目目录初始化此文件:

    go mod init
    
  3. 创建一个包含以下内容的 script.sh 文件:

    
    set -e
    echo "Hello ${NAME:-World}!"
    

    为了对每个传入请求执行此 shell 脚本,本示例使用一个小型 Go 程序,该程序会启动一个基本 Web 服务器并侦听 PORT 环境变量定义的端口。

  4. 创建一个包含以下内容的 invoke.go 文件:

    
    // Sample helloworld-shell is a Cloud Run shell-script-as-a-service.
    package main
    
    import (
    	"log"
    	"net/http"
    	"os"
    	"os/exec"
    )
    
    func main() {
    	http.HandleFunc("/", scriptHandler)
    
    	// Determine port for HTTP service.
    	port := os.Getenv("PORT")
    	if port == "" {
    		port = "8080"
    		log.Printf("Defaulting to port %s", port)
    	}
    
    	// Start HTTP server.
    	log.Printf("Listening on port %s", port)
    	if err := http.ListenAndServe(":"+port, nil); err != nil {
    		log.Fatal(err)
    	}
    }
    
    func scriptHandler(w http.ResponseWriter, r *http.Request) {
    	cmd := exec.CommandContext(r.Context(), "/bin/sh", "script.sh")
    	cmd.Stderr = os.Stderr
    	out, err := cmd.Output()
    	if err != nil {
    		w.WriteHeader(500)
    	}
    	w.Write(out)
    }
    

您的应用已编写完毕,可以进行容器化并上传到 Container Registry。

将应用容器化并将其上传到 Container Registry

如需将示例应用容器化,请在与源文件相同的目录中创建一个名为 Dockerfile 的新文件,并将以下内容复制到此文件中:


# Use the offical golang image to create a binary.
# This is based on Debian and sets the GOPATH to /go.
# https://hub.docker.com/_/golang
FROM golang:1.14-buster as builder

# Create and change to the app directory.
WORKDIR /app

# Retrieve application dependencies.
# This allows the container build to reuse cached dependencies.
# Expecting to copy go.mod and if present go.sum.
COPY go.* ./
RUN go mod download

# Copy local code to the container image.
COPY invoke.go ./

# Build the binary.
RUN go build -mod=readonly -v -o server

# Use the official Debian slim image for a lean production container.
# https://hub.docker.com/_/debian
# https://docs.docker.com/develop/develop-images/multistage-build/#use-multi-stage-builds
FROM debian:buster-slim
RUN set -x && apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y \
    --no-install-recommends \
    ca-certificates && \
    rm -rf /var/lib/apt/lists/*

# Copy the binary to the production image from the builder stage.
COPY --from=builder /app/server /app/server
COPY script.sh ./

# Run the web service on container startup.
CMD ["/app/server"]

使用 Cloud Build 构建容器映像,方法是从包含 Dockerfile 的目录中运行以下命令:

gcloud builds submit --tag gcr.io/PROJECT-ID/helloworld

其中 PROJECT-ID 是您的 GCP 项目 ID。 您可以通过运行 gcloud config get-value project 获取该 ID。

成功后,您会看到一条包含映像名称 (gcr.io/PROJECT-ID/helloworld) 的 SUCCESS 消息。该映像存储在 Container Registry 中,并可根据需要重复使用。

部署到 Cloud Run

要部署容器映像,请执行以下操作:

  1. 使用以下命令进行部署:

    gcloud run deploy --image gcr.io/PROJECT-ID/helloworld

    如果系统提示您启用 API,请回复 y 进行启用。

    PROJECT-ID 替换为您的 GCP 项目 ID。您可以通过运行 gcloud config get-value project 命令来查看项目 ID。

    1. 系统会提示您输入服务名称:按 Enter 接受默认名称 helloworld
    2. 系统会提示您输入区域:选择所需的区域,例如 us-central1
    3. 系统会提示您允许未通过身份验证的调用:响应 y

    然后等待部署完成。成功完成时,命令行会显示服务网址。

  2. 通过在网络浏览器中打开该服务网址来访问已部署的容器。

Cloud Run 位置

Cloud Run 是地区级的,这意味着运行 Cloud Run 服务的基础架构位于特定地区,并且由 Google 代管,以便在该地区内的所有区域以冗余方式提供。

选择用于运行 Cloud Run 服务的地区时,主要考虑该地区能否满足您的延迟时间、可用性或耐用性要求。通常,您可以选择距离用户最近的地区,但除此之外,您还应该考虑 Cloud Run 服务使用的其他 Google Cloud 产品的位置。跨多个位置使用 Google Cloud 产品可能会影响服务的延迟时间和费用。

Cloud Run 可在以下地区使用:

基于层级 1 价格

基于层级 2 价格

  • asia-east2(香港)
  • asia-northeast3(韩国首尔)
  • asia-southeast1(新加坡)
  • asia-southeast2 (雅加达)
  • asia-south1(印度孟买)
  • asia-south2(印度德里)
  • australia-southeast1(悉尼)
  • australia-southeast2(墨尔本)
  • europe-central2(波兰,华沙)
  • europe-west2(英国伦敦)
  • europe-west3(德国法兰克福)
  • europe-west6(瑞士苏黎世) 叶形图标 二氧化碳排放量低
  • northamerica-northeast1(蒙特利尔) 叶形图标 二氧化碳排放量低
  • southamerica-east1(巴西圣保罗) 叶形图标 二氧化碳排放量低
  • us-west2(洛杉矶)
  • us-west3(拉斯维加斯)
  • us-west4(盐湖城)

如果您已创建 Cloud Run 服务,则可以在 Cloud Console 的 Cloud Run 信息中心查看相应的地区。

恭喜!您刚刚将容器映像中打包的应用部署到了 Cloud Run。Cloud Run 会在需要处理收到的请求时自动横向扩容您的容器映像,并在需要处理的请求数量减少时自动横向缩容您的容器映像。您只需为在请求处理期间消耗的 CPU、内存和网络流量付费。

清理

移除测试项目

虽然 Cloud Run 不会对未在使用中的服务计费,但您可能仍然需要支付将容器映像存储在 Container Registry 中而产生的相关费用。 为避免产生费用,您可以删除映像或删除 Cloud 项目。删除 Cloud 项目后,系统即会停止对该项目中使用的所有资源计费。

  1. 在 Cloud Console 中,转到管理资源页面。

    转到“管理资源”

  2. 在项目列表中,选择要删除的项目,然后点击删除
  3. 在对话框中输入项目 ID,然后点击关闭以删除项目。

后续步骤

如需详细了解如何使用代码源构建容器并推送到 Container Registry,请参阅以下内容: