本页面介绍在生成与 OCI 兼容的应用映像时重现 Cloud Foundry 构建流程所需的构建基础架构。如果您已完成 Spring Music 迁移指南,则可以通过本文深入了解应用的具体迁移配置。
前期准备
- 确保您已按照 Cloud Run 设置页面中的说明为 Cloud Run 设置了新项目。
- 确保您拥有用于存储容器的
REGISTRY_URI
。Cloud Run 建议使用 Artifact Registry。Docker 用于创建中间映像以构建项目。
设置与 Cloud Foundry 兼容的构建流程
您必须创建两个基础 OCI 容器以支持此新流程:
- 构建器映像,镜像 Cloud Foundry 的构建过程,并能够将应用源代码构建到 Cloud Foundry Droplet 中。
- 镜像 Cloud Foundry 应用运行时的运行时映像。
此流程需要由平台管理员至少完成一次。建立该流程后,所有需要迁移到 Cloud Run 的 Cloud Foundry 应用都可以共享构建和运行映像。
创建构建器映像
本部分使用 cflinux3
作为基础映像来创建构建映像。该构建映像用作创建应用映像的构建环境。
创建名为
build/
的目录并通过cd
命令进入该目录:mkdir build && cd build
在
build/
文件夹中,创建一个名为Dockerfile
的新文件并粘贴以下代码:ARG CF_LINUX_FS=cloudfoundry/cflinuxfs3 FROM golang:1.20-bullseye AS builder_build WORKDIR /build RUN ["git", "clone", "--depth=1", "https://github.com/cloudfoundry/buildpackapplifecycle.git"] WORKDIR /build/buildpackapplifecycle RUN ["go", "mod", "init", "code.cloudfoundry.org/buildpackapplifecycle"] RUN ["go", "mod", "tidy"] RUN CGO_ENABLD=0 go build -o /builder ./builder/ FROM $CF_LINUX_FS # Set up container tools related to building applications WORKDIR /lifecycle COPY --from=builder_build /builder /lifecycle/builder # Set up environment to match Cloud Foundry's build. # https://docs.cloudfoundry.org/devguide/deploy-apps/environment-variable.html#app-system-env WORKDIR /staging/app WORKDIR /tmp ENV CF_INSTANCE_ADDR=127.0.0.1:8080 \ CF_INSTANCE_IP=127.0.0.1 \ CF_INSTANCE_INTERNAL_IP=127.0.0.1 \ VCAP_APP_HOST=127.0.0.1 \ CF_INSTANCE_PORT=8080 \ LANG=en_US.UTF-8 \ INSTANCE_GUID=00000000-0000-0000-0000-000000000000 \ VCAP_APPLICATION={} \ VCAP_SERVICES={} \ CF_STACK=cflinuxfs3
使用 Cloud Build 构建和发布
builder
映像gcloud builds \ submit --tag "REGISTRY_URI/builder:stable"
将
REGISTRY_URI
替换为要发布构建映像的 Artifact Registry 的地址。例如:REGION-docker.pkg.dev/PROJECT_ID/REPOSITORY/builder:stable
。
创建运行时映像
本部分使用 cflinux3
作为基础映像来创建运行映像。当您创建最终应用映像时,运行映像被用作基础映像。
创建名为
run/
的目录并通过cd
命令进入该目录:mkdir run && cd run
在
run/
文件夹中,使用以下代码创建名为entrypoint.bash
的新 Shell 脚本:#!/usr/bin/env bash set -e if [[ "$@" == "" ]]; then exec /lifecycle/launcher "/home/vcap/app" "" "" else exec /lifecycle/launcher "/home/vcap/app" "$@" "" fi
在
run/
文件夹中,创建一个名为Dockerfile
的新文件并粘贴以下代码:ARG CF_LINUX_FS=cloudfoundry/cflinuxfs3 FROM golang:1.20-bullseye AS launcher_build WORKDIR /build RUN ["git", "clone", "--depth=1", "https://github.com/cloudfoundry/buildpackapplifecycle.git"] WORKDIR /build/buildpackapplifecycle RUN ["go", "mod", "init", "code.cloudfoundry.org/buildpackapplifecycle"] RUN ["go", "mod", "tidy"] RUN CGO_ENABLD=0 go build -o /launcher ./launcher/ FROM $CF_LINUX_FS # Set up container tools related to launching the application WORKDIR /lifecycle COPY entrypoint.bash /lifecycle/entrypoint.bash RUN ["chmod", "+rx", "/lifecycle/entrypoint.bash"] COPY --from=launcher_build /launcher /lifecycle/launcher # Set up environment to match Cloud Foundry WORKDIR /home/vcap USER vcap:vcap ENTRYPOINT ["/lifecycle/entrypoint.bash"] # Expose 8080 to allow app to be run on Cloud Foundry, # and PORT so the container can be run locally. # These do nothing on Cloud Run. EXPOSE 8080/tcp # Set up environment variables similar to Cloud Foundry. ENV CF_INSTANCE_ADDR=127.0.0.1:8080 \ CF_INSTANCE_IP=127.0.0.1 \ INSTANCE_IP=127.0.0.1 \ CF_INSTANCE_INTERNAL_IP=127.0.0.1 \ VCAP_APP_HOST=127.0.0.1 \ CF_INSTANCE_PORT=80 \ LANG=en_US.UTF-8 \ CF_INSTANCE_GUID=00000000-0000-0000-0000-000000000000 \ INSTANCE_GUID=00000000-0000-0000-0000-000000000000 \ CF_INSTANCE_INDEX=0 \ INSTANCE_INDEX=0 \ PORT=8080 \ VCAP_APP_PORT=8080 \ VCAP_APPLICATION={} \ VCAP_SERVICES={}
使用 Cloud Build 构建和发布
runtime
映像:gcloud builds submit \ --tag "REGISTRY_URI/runtime:stable"
将
REGISTRY_URI
替换为要发布构建映像的 Artifact Registry 的地址例如:REGION-docker.pkg.dev/PROJECT_ID/REPOSITORY/runtime:stable.
将 Cloud Foundry 应用构建为 OCI 映像
迁移到 Cloud Run 的每个应用都需要有与 Cloud Foundry 运行应用的方式相匹配的 Dockerfile。Dockerfile 有以下作用:
- 加载构建器映像。
- 运行 v2 Buildpack 生命周期以创建 Droplet。
- 提取 Droplet 的内容。
- 在运行作业映像上加载 Droplet 的内容以创建可运行的应用映像。
最终应用映像与 Cloud Foundry 和 Cloud Run 都兼容,因此您可以对迁移进行 A/B 测试,以帮助调试任何意外行为。
应用团队必须为需要迁移的每个应用完成此流程。
从已部署的 Cloud Foundry 应用收集构建信息
查看应用堆栈。堆栈通过
cf push
中的-s
标志或应用清单的stack
字段提供。- 如果堆栈为 Windows,则应用可能与 Cloud Run 不兼容。您必须将应用移植到 Linux,然后才能继续。
- 如果堆栈为空、
cflinuxfs3
或cflinuxfs4
,则应用可以迁移到 Cloud Run。
收集应用 Buildpack 的列表。Buildpack 通过
cf push
中的-b
标志、应用清单中的buildpack
字段或应用清单的buildpacks
字段提供。- 如果未指定 Buildpack,则表示正在自动检测它们。查看 Cloud Foundry 中最新应用部署中的检测到的 Buildpack 列表,或者如果您知道路径,请明确指定它们。
- 如果 Buildpack 是网址,请记下网址并继续执行下一步。
对于任何使用简称的 Buildpack,请使用下表将其映射到网址:
简称 网址 staticfile_buildpack
https://github.com/cloudfoundry/staticfile-buildpack java_buildpack
https://github.com/cloudfoundry/java-buildpack ruby_buildpack
https://github.com/cloudfoundry/ruby-buildpack dotnet_core_buildpack
https://github.com/cloudfoundry/dotnet-core-buildpack nodejs_buildpack
https://github.com/cloudfoundry/nodejs-buildpack go_buildpack
https://github.com/cloudfoundry/go-buildpack python_buildpack
https://github.com/cloudfoundry/python-buildpack php_buildpack
https://github.com/cloudfoundry/php-buildpack binary_buildpack
https://github.com/cloudfoundry/binary-buildpack nginx_buildpack
https://github.com/cloudfoundry/nginx-buildpack 如需查找不常见 Buildpack 的源代码,请参阅 Cloud Foundry GitHub 组织。
收集映像的源代码位置。源代码通过应用清单的
path
属性或cf push
命令的-p
标志提供。如果未定义源代码,则引用当前目录。确定源代码目录中是否有
.cfignore
文件。如果存在,请将其移至名为.gcloudignore.
的文件中
构建 Cloud Foundry 应用
在此步骤中,您需要将构建元素整理到以下文件夹结构中:
.
├── cloudbuild.yaml
├── Dockerfile
├── .gcloudignore
└── src
├── go.mod
└── main.go
cloudbuild.yaml
为 Cloud Build 提供特定的构建说明Dockerfile
将使用前面步骤中的构建和运行映像来创建应用映像src/
包含应用的源代码
在目录中创建一个名为
Dockerfile
的文件,其中包含以下内容:ARG BUILD_IMAGE ARG RUN_IMAGE FROM $BUILD_IMAGE as build COPY src /staging/app COPY src /tmp/app ARG BUILDPACKS RUN /lifecycle/builder \ -buildArtifactsCacheDir=/tmp/cache \ -buildDir=/tmp/app \ -buildpacksDir=/tmp/buildpacks \ -outputBuildArtifactsCache=/tmp/output-cache \ -outputDroplet=/tmp/droplet \ -outputMetadata=/tmp/result.json \ "-buildpackOrder=${BUILDPACKS}" \ "-skipDetect=true" FROM $RUN_IMAGE COPY --from=build /tmp/droplet droplet RUN tar -xzf droplet && rm droplet
在目录中创建一个名为
cloudbuild.yaml
的文件,其中包含以下内容:steps: - name: gcr.io/cloud-builders/docker args: - 'build' - '--network' - 'cloudbuild' - '--tag' - '${_TAG}' - '--build-arg' - 'BUILD_IMAGE=${_BUILD_IMAGE}' - '--build-arg' - 'RUN_IMAGE=${_RUN_IMAGE}' - '--build-arg' - 'BUILDPACKS=${_BUILDPACKS}' - '.' images: - "${_TAG}" options: # Substitute build environment variables as an array of KEY=VALUE formatted strings here. env: [] substitutions: _BUILD_IMAGE: BUILD_IMAGE_URI _RUN_IMAGE: RUN_IMAGE_URI _BUILDPACKS: BUILDPACK_URL _TAG: APP_ARTIFACT_REGISTRY/APP_NAME:latest
如果您有
.cfignore
文件,请将其复制到名为.gcloudignore
的目录。在该目录中创建一个名为
src
的目录。将应用的内容复制到
src:
中- 如果源代码是 zip 文件(包括
.jar
文件),请将内容解压缩到src
。 - 如果源代码是目录,请将内容复制到
src
中。
- 如果源代码是 zip 文件(包括
运行
gcloud builds submit .
以构建应用。
已知的不兼容问题
- 依赖于 Cloud Foundry 注入的环境变量(如
VCAP_SERVICES
)的 Buildpack 不起作用。您应使用您的语言的管理系统明确声明依赖于它们注入的内容。 - 如需修补以这种方式生成的映像,您必须使用较新版本的构建重新构建并运行映像。如果您在 Cloud Foundry 上运行 BOSH stemcell,更新它们不会自动修补应用映像。
- 构建将在与 Cloud Foundry 集群不同的网络环境中进行,您可能需要设置自定义 Cloud Build 池并使其具有内部软件包镜像的访问权限。