Cloud Foundry から Cloud Run への移行のサンプル: Spring Music

この移行のサンプルでは、Spring Music プロジェクトを使用して、OCI 準拠のアプリケーション イメージとして Cloud Foundry アプリケーションを構築する方法を示します。このサンプルは、Cloud Foundry エコシステムのオープンソース コンポーネントを使用するリフト&シフト戦略を使用しています。アプリケーション イメージを作成したら、Cloud Run にデプロイするようにアプリケーションを構成する必要があります。

始める前に

  • 設定ページの説明に従って、Cloud Run に新しいプロジェクトを設定したことを確認してください。
  • データを保存するコンテナ用の REGISTRY_URI があることを確認します。Cloud Run では、Artifact Registry の使用を推奨します。
  • ドメイン制限の組織のポリシーでプロジェクトの未認証呼び出しが制限されている場合は、プライベート サービスのテストの説明に従って、デプロイされたサービスにアクセスする必要があります。

  • ワークステーションに Docker をインストールします。Docker を使用して、プロジェクトをビルドするための中間イメージを作成します。

デプロイに必要な権限

このガイドでは、ビルドしたコンテナ イメージを保存してデプロイするための権限が必要です。

次のロールが必要です。

プロジェクト構造

このガイドでは、プロジェクト ディレクトリ(cr-spring-music/ など)を作成し、ガイドを進める過程でサブディレクトリを作成することをおすすめします。

cr-spring-music/
├── build
├── run
└── spring-music

ビルドイメージを作成する

このセクションでは、cflinux3 をベースイメージとして使用して、ビルドイメージを作成します。ビルドイメージは、アプリケーション イメージを作成するためのビルド環境として使用されます。

  1. build/ という名前のディレクトリを作成し、その中に cd を作成します。

    mkdir build && cd build
    
  2. 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
    
  3. 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 をベースイメージとして使用して、実行イメージを作成します。実行イメージは、最終的なアプリイメージを作成するときにベースイメージとして使用されます。

  1. run/ という名前のディレクトリを作成し、その中に cd を作成します。

    mkdir run && cd run
    
  2. run/ フォルダ内に、次のコードを含む entrypoint.bash という名前の新しいシェル スクリプトを作成します。

    #!/usr/bin/env bash
    set -e
    
    if [[ "$@" == "" ]]; then
    exec /lifecycle/launcher "/home/vcap/app" "" ""
    else
    exec /lifecycle/launcher "/home/vcap/app" "$@" ""
    fi
    
  3. 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={}
    
  4. 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 用に Spring Music をビルドする

Spring Music プロジェクトのクローンを作成し、そのプロジェクトを Cloud Foundry にデプロイしているかのようにビルドコマンドを実行するには:

  1. Spring Music リポジトリのクローンを作成します。

    git clone https://github.com/cloudfoundry-samples/spring-music.git
    
  2. このガイドでは、Java 8 と Spring Boot 2 を使用する古いバージョンの Spring Music アプリケーションを使用します。このため、Spring Music プロジェクトの古いリビジョンに移動します。

    git checkout 610ba471a643a20dee7a62d88a7879f13a21d6a3
    
  3. リポジトリに移動します。

    cd spring-music
    
  4. Spring Music バイナリをビルドします。

    ./gradlew clean assemble
    

これで、コンパイル済みの Spring Music アプリを含む build/ フォルダが作成され、Cloud Foundry インスタンスに push する準備が整いました。

Spring Music を Cloud Run 互換アプリケーションに変換する

build コマンドの出力を使用して、Spring Music アーティファクトを Cloud Run にデプロイする準備を行う必要があります。

  1. ステージング ディレクトリ cr-app を作成し、その内部に src サブディレクトリを作成します。

    mkdir -p cr-app/src
    
  2. コンパイル済みの JAR の内容を src ディレクトリに抽出することで、cf push を模倣します。

    unzip build/libs/spring-music-1.0.jar -d cr-app/src
    
  3. ディレクトリを cr-app/ に変更します。

    cd cr-app/
    
  4. Dockerfile という名前の新しいファイルを作成します。この Dockerfile は、前の手順で作成したビルドイメージとランタイム イメージを使用して、Java ビルドパックによって Spring Music の実行可能なアプリケーション イメージを作成します。

  5. 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
    

Spring Music を OCI 準拠のイメージとしてビルドする

このステップでは、前のステップで作成したビルドイメージ、ランタイム イメージ、アプリケーション Dockerfile を使用して、OCI 準拠のイメージを作成する方法を Cloud Build に指示します。

OCI 準拠のイメージを作成するには:

  1. cloudbuild.yaml というファイルを作成します。これは、Cloud Build にアプリケーションのビルド方法を指示するビルド構成です。

  2. 次の構成を 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: REGISTRY_URI/builder:stable
      _RUN_IMAGE:  REGISTRY_URI/runtime:stable
      _BUILDPACKS: https://github.com/cloudfoundry/java-buildpack
      _TAG: REGISTRY_URI/spring-music:latest
    
    • REGISTRY_URI は、ビルダーとランナーを公開したコンテナ レジストリの URI に置き換えます。
  3. Cloud Build を使用してアプリケーション イメージをビルドします。

    gcloud builds submit .
    

    ビルドが完了したら、結果イメージの URI をメモします。これは、次の手順でアプリケーションをデプロイするときに必要になります。ビルド後に得られるイメージは、オープンソースの Cloud Foundry コンポーネントを使用して構築された、Spring Music アプリを実行するための OCI 準拠のコンテナ イメージになります。

Cloud Run にデプロイする

Cloud Run で使用するサービス定義ファイルを作成する必要があります。

  1. アプリケーションのサービス アカウントを作成します。

    gcloud iam service-accounts create spring-music
    
  2. 次の内容の service.yaml ファイルを作成します。

    apiVersion: serving.knative.dev/v1
    kind: Service
    metadata:
      name: "spring-music"
      # Set this to be the project number of the project you're deploying to.
      namespace: "PROJECT_NUMBER"
      labels:
        cloud.googleapis.com/location: us-central1
        migrated-from: cloud-foundry
      annotations:
        run.googleapis.com/ingress: all
    spec:
      template:
        metadata:
          annotations:
            autoscaling.knative.dev/minScale: '1'
            autoscaling.knative.dev/maxScale: '1'
            run.googleapis.com/cpu-throttling: 'true'
            run.googleapis.com/startup-cpu-boost: 'true'
            run.googleapis.com/sessionAffinity: 'false'
        spec:
          containerConcurrency: 1000
          timeoutSeconds: 900
          serviceAccountName: spring-music@PROJECT_NUMBER.iam.gserviceaccount.com
          containers:
          - name: user-container
            # Set the following value to either:
            # - The image you built for your application in the last section of the guide.
            image: SPRING_IMAGE_URI
            ports:
            - name: http1
              containerPort: 8080
            env:
            - name: VCAP_APPLICATION
              value: |-
                    {
                        "application_id": "00000000-0000-0000-0000-000000000000",
                        "application_name": "spring-music",
                        "application_uris": [],
                        "limits": {
                        "disk": 0,
                        "mem": 1024
                        },
                        "name": "spring-music",
                        "process_id": "00000000-0000-0000-0000-000000000000",
                        "process_type": "web",
                        "space_name": "none",
                        "uris": []
                    }
            - name: MEMORY_LIMIT
              value: '1024M'
            resources:
              limits:
                memory: 1024Mi
                cpu: "1"
            startupProbe:
              httpGet:
                path: /
                port: 8080
              timeoutSeconds: 1
              failureThreshold: 30
              successThreshold: 1
              periodSeconds: 2
            livenessProbe:
              httpGet:
                path: /
                port: 8080
              timeoutSeconds: 1
              failureThreshold: 1
              successThreshold: 1
              periodSeconds: 30
      traffic:
      - percent: 100
        latestRevision: true
    
  3. サービスを Cloud Run にデプロイする

    gcloud run services replace service.yaml
    

    デプロイが完了すると、デプロイされた URL で実行中の Spring Music アプリケーションにアクセスできるようになります。

次のステップ