存储事件函数应用

架构

Storage Event Function App 是一个图片目录和缩略图制作工具。它由 以下组件:

  • 可供用户上传图片的客户端应用。
    • 容器托管的 API 和静态网站 - Golang - Cloud Run
    • 存储 - 文件存储 - Cloud Storage
  • 用于创建图片缩略图的图像处理器。
    • 函数即服务 - Golang - Cloud Functions
  • 部署流水线。
    • 部署 - Cloud Build

开始使用

点击以下链接,获取 Cloud Shell 中的源代码副本。一次 在那里,只需一个命令,即可启动 项目...

在 Cloud Shell 中打开

在 GitHub 上查看源代码


存储事件函数应用组件

存储事件函数应用架构使用多种产品。 下面列出了这些组件,以及有关 包括指向相关视频、产品文档和 互动演示。
视频 文档 演示
Cloud Run Cloud Run 可让您在容器中运行应用,但以无服务器方式配置,而无需配置实例数、处理器数或内存数。上传容器,获取网址。
Cloud Storage Cloud Storage 通过 http(s) 提供文件存储和公共传送图片。
Cloud Functions Cloud Functions 是一个函数是一个服务平台,可用于监听 Cloud Storage 文件上传事件并运行代码创建这些文件的缩略图。
Cloud Build Cloud Build 是工具,可将容器打包并部署为 Cloud Run 服务。

脚本

安装脚本使用以 go 和 Terraform CLI 工具编写的可执行文件 选取一个空项目并在其中安装应用。输出应为一个正常运行的应用和负载均衡 IP 地址的网址。

./main.tf

启用服务

默认情况下,Google Cloud 服务在项目中处于停用状态。要使用 我们必须激活以下内容:

  • Cloud Build - 创建容器映像并部署到 Cloud Run
  • Cloud Storage - 托管静态文件
  • Cloud Functions - 函数即服务平台
  • Cloud Run - 一款无服务器工具,用于托管容器和 提供用于访问应用程序的网址。
  • Artifact Registry - 存储要与 Cloud Build 搭配使用的 Docker 映像。
variable "gcp_service_list" {
    description = "The list of apis necessary for the project"
    type        = list(string)
    default = [
        "cloudbuild.googleapis.com",
        "storage.googleapis.com",
        "cloudfunctions.googleapis.com",
        "run.googleapis.com",
        "artifactregistry.googleapis.com",
    ]
}

resource "google_project_service" "all" {
    for_each                   = toset(var.gcp_service_list)
    project                    = var.project_number
    service                    = each.key
    disable_dependent_services = false
    disable_on_destroy         = false
}

设置权限

设置允许 Cloud Build 部署所有服务的 IAM 角色和权限。

  • 允许 Cloud Build 服务账号部署到 Cloud Run
  • 启用 Cloud Build 服务账号以执行服务账号活动
  • 启用 Cloud Build 服务账号以发布到 Cloud Run
  • 启用 Cloud Build 服务账号以在 Artifact Registry 中存储容器
variable "build_roles_list" {
    description = "The list of roles that build needs for"
    type        = list(string)
    default = [
        "roles/run.developer",
        "roles/iam.serviceAccountUser",
        "roles/run.admin",
        "roles/cloudfunctions.admin",
        "roles/artifactregistry.admin",
    ]
}

resource "google_project_iam_member" "allbuild" {
    for_each   = toset(var.build_roles_list)
    project    = var.project_number
    role       = each.key
    member     = "serviceAccount:${local.sabuild}"
    depends_on = [google_project_service.all]
}

创建存储分区

为上传的图片和缩略图创建存储位置,并为 Cloud Functions 上传提供临时存储位置。

resource "google_storage_bucket" "target_bucket" {
    name     = var.bucket
    project  = var.project_number
    location = var.location
}

resource "google_storage_bucket" "function_bucket" {
    name     = "${var.project_id}-function-deployer"
    project  = var.project_number
    location = var.location
}

创建 Artifact Registry 代码库

以下代码概述了 Artifact Registry 的参数 用于保存容器的代码库

resource "google_artifact_registry_repository" "app" {
    provider      = google-beta
    format        = "DOCKER"
    location      = var.region
    project       = var.project_id
    repository_id = "${var.basename}-app"
    depends_on    = [google_project_service.all]
}

为 Cloud Run 应用构建容器

以下脚本会构建映像并将其上传到 Artifact Registry,以便与 Cloud Build 搭配使用。

resource "null_resource" "cloudbuild_app" {
    provisioner "local-exec" {
        working_dir = "${path.module}/code/app"
        command     = "gcloud builds submit . --substitutions=_REGION=${var.region},_BASENAME=${var.basename}"
    }

    depends_on = [
        google_artifact_registry_repository.app,
        google_project_service.all
    ]
}

部署到 Cloud Run

以下命令使用 Cloud Build 将客户端 Web 应用部署到 Cloud Run。

resource "google_cloud_run_service" "app" {
    name     = "${var.basename}-app"
    location = var.region
    project  = var.project_id

    template {
        spec {
            containers {
                image = "${var.region}-docker.pkg.dev/${var.project_id}/${var.basename}-app/prod"
                env {
                name  = "BUCKET"
                value = var.bucket
                }
            }
        }

        metadata {
            annotations = {
                "autoscaling.knative.dev/maxScale" = "1000"
                "run.googleapis.com/client-name"   = "terraform"
            }
        }
    }
    autogenerate_revision_name = true
    depends_on = [
        null_resource.cloudbuild_app,
    ]
}

data "google_iam_policy" "noauth" {
    binding {
        role = "roles/run.invoker"
        members = [
        "allUsers",
        ]
    }
}

resource "google_cloud_run_service_iam_policy" "noauth_app" {
    location    = google_cloud_run_service.app.location
    project     = google_cloud_run_service.app.project
    service     = google_cloud_run_service.app.name
    policy_data = data.google_iam_policy.noauth.policy_data
}

将函数代码部署到 Cloud Functions

直接推送到函数并激活。

resource "google_storage_bucket_object" "archive" {
    name   = "index.zip"
    bucket = google_storage_bucket.function_bucket.name
    source = "index.zip"
    depends_on = [
        google_project_service.all,
        google_storage_bucket.function_bucket,
        null_resource.cloudbuild_function
    ]
}

resource "google_cloudfunctions_function" "function" {
    name    = var.basename
    project = var.project_id
    region  = var.region
    runtime = "go116"

    available_memory_mb   = 128
    source_archive_bucket = google_storage_bucket.function_bucket.name
    source_archive_object = google_storage_bucket_object.archive.name
    entry_point           = "OnFileUpload"
    event_trigger {
        event_type = "google.storage.object.finalize"
        resource   = google_storage_bucket.target_bucket.name
    }

    depends_on = [
        google_storage_bucket.function_bucket,
        google_storage_bucket.target_bucket,
        google_storage_bucket_object.archive,
        google_project_service.all
    ]
}

./code/app/cloudbuild.yaml

构建 API 容器

以下命令会为 Web 应用创建 Docker 映像。

- name: "gcr.io/cloud-builders/docker"
  args: [ "build", "-t", "$_REGION-docker.pkg.dev/$PROJECT_ID/$_BASENAME-app/prod", ".", ]

将 API 容器推送到 Artifact Registry

将容器推送到 Artifact Registry 后,Cloud Run 便可以获取映像并进行分发。

- name: "gcr.io/cloud-builders/docker"
  args: ["push", "$_REGION-docker.pkg.dev/$PROJECT_ID/$_BASENAME-app/prod"]

替换内容

创建一个具有默认值的变量,以便在部署时可以更改这些值。

substitutions:
  _REGION: us-central1
  _BASENAME: scaler

总结

现在,您的 使用 Cloud Functions 响应 Storage 存储分区中的更改。 您还拥有修改或扩展此解决方案所需的全部代码