Contoh migrasi Cloud Foundry ke Cloud Run: Spring Music

Sampel migrasi ini menggunakan project Spring Music untuk menunjukkan cara aplikasi Cloud Foundry dapat dibangun sebagai image aplikasi yang mematuhi OCI. Sampel ini menggunakan strategi lift and shift, yang memakai komponen open source dari ekosistem Cloud Foundry. Setelah membuat image aplikasi, Anda perlu mengonfigurasi aplikasi tersebut untuk di-deploy ke Cloud Run.

Sebelum memulai

  • Pastikan Anda telah menyiapkan project baru untuk Cloud Run seperti yang dijelaskan di halaman setup.
  • Pastikan Anda memiliki REGISTRY_URI untuk menyimpan penampung. Cloud Run merekomendasikan penggunaan Artifact Registry.
  • Jika Anda dikenai kebijakan organisasi pembatasan domain yang membatasi pemanggilan yang tidak diautentikasi untuk project, Anda perlu mengakses layanan yang di-deploy seperti yang dijelaskan di bagian Menguji layanan pribadi.

  • Instal Docker di workstation Anda. Docker digunakan untuk membuat image menengah untuk membangun project.

Izin yang diperlukan untuk men-deploy

Untuk panduan ini, Anda memerlukan izin untuk membangun, menyimpan image container yang telah dibuat, dan men-deploy-nya.

Anda harus memiliki peran berikut:

Struktur Project

Untuk panduan ini, sebaiknya buat direktori project, misalnya cr-spring-music/, dan buat subdirektori saat Anda mempelajari panduan ini.

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

Membuat Image build

Bagian ini membuat image build menggunakan cflinux3 sebagai image dasar. Image build digunakan sebagai lingkungan build untuk membuat image aplikasi.

  1. Buat direktori bernama build/ dan cd ke dalamnya:

    mkdir build && cd build
    
  2. Di folder build/, buat file baru bernama Dockerfile dan tempelkan kode berikut:

    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. Gunakan Cloud Build untuk membangun dan memublikasikan image builder

    gcloud builds \
        submit --tag "REGISTRY_URI/builder:stable"
    

    Ganti REGISTRY_URI dengan alamat Artifact Registry tempat Anda ingin memublikasikan image build. Contoh: REGION-docker.pkg.dev/PROJECT_ID/REPOSITORY/builder:stable.

Buat Image runtime

Bagian ini membuat image run menggunakan cflinux3 sebagai image dasar. Image run digunakan sebagai image dasar saat Anda membuat image aplikasi akhir.

  1. Buat direktori bernama run/ dan cd ke dalamnya:

    mkdir run && cd run
    
  2. Di folder run/, buat skrip shell baru bernama entrypoint.bash dengan kode berikut:

    #!/usr/bin/env bash
    set -e
    
    if [[ "$@" == "" ]]; then
    exec /lifecycle/launcher "/home/vcap/app" "" ""
    else
    exec /lifecycle/launcher "/home/vcap/app" "$@" ""
    fi
    
  3. Di folder run/, buat file baru bernama Dockerfile dan tempelkan kode berikut:

    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. Gunakan Cloud Build untuk membangun dan memublikasikan image runtime:

    gcloud builds submit \
        --tag "REGISTRY_URI/runtime:stable"
    

    Ganti REGISTRY_URI dengan alamat ke Artifact Registry tempat Anda ingin memublikasikan image build. Contoh: REGION-docker.pkg.dev/PROJECT_ID/REPOSITORY/runtime:stable.

Bangun Musik Musim Semi untuk Cloud Foundry

Untuk meng-clone project Spring Music dan menjalankan perintah build seolah-olah kita men-deploy project ke Cloud Foundry:

  1. Clone repositori Spring Music:

    git clone https://github.com/cloudfoundry-samples/spring-music.git
    
  2. Untuk tujuan panduan ini, kita akan menggunakan aplikasi Spring Music versi lama yang menggunakan Java 8 dan Spring Boot 2. Untuk melakukannya, kita akan beralih ke revisi lama project Spring Music:

    git checkout 610ba471a643a20dee7a62d88a7879f13a21d6a3
    
  3. Pindahkan ke repositori:

    cd spring-music
    
  4. Buat biner Spring Music:

    ./gradlew clean assemble
    

Anda sekarang memiliki folder build/ dengan aplikasi Spring Music yang dikompilasi dan siap untuk dikirim ke instance Cloud Foundry.

Konversi Spring Music menjadi aplikasi yang kompatibel dengan Cloud Run

Anda harus mengambil output perintah build guna menyiapkan artefak Spring Music untuk di-deploy ke Cloud Run.

  1. Buat direktori staging cr-app dan subdirektori src di dalamnya:

    mkdir -p cr-app/src
    
  2. Tirukan cf push dengan mengekstrak konten JAR yang dikompilasi ke dalam direktori src:

    unzip build/libs/spring-music-1.0.jar -d cr-app/src
    
  3. Ubah direktori menjadi cr-app/:

    cd cr-app/
    
  4. Buat file baru dengan nama Dockerfile. Dockerfile ini akan menggunakan image build dan image runtime yang dibuat pada langkah sebelumnya untuk membuat image aplikasi yang dapat dijalankan untuk Spring Music, menggunakan buildpack Java.

  5. Tempelkan kode berikut ke dalam 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
    

Membangun Spring Music sebagai image yang sesuai dengan OCI

Pada langkah ini, Anda akan menginstruksikan Cloud Build cara membuat image yang sesuai dengan OCI menggunakan image build, image runtime, dan Dockerfile aplikasi yang dibuat pada langkah sebelumnya.

Untuk membuat image yang sesuai dengan OCI:

  1. Buat file dengan nama cloudbuild.yaml. Ini adalah konfigurasi build yang akan menginstruksikan Cloud Build cara mem-build aplikasi.

  2. Tempel konfigurasi berikut ke dalam 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
    
    • Ganti REGISTRY_URI dengan URI container registry tempat Anda memublikasikan builder dan runner.
  3. Build image aplikasi menggunakan Cloud Build:

    gcloud builds submit .
    

    Saat build selesai, catat URI image yang dihasilkan. Anda akan membutuhkannya saat men-deploy aplikasi di langkah berikutnya. Image yang dihasilkan akan berupa image container yang sesuai dengan OCI untuk menjalankan aplikasi Spring Music, yang di-build menggunakan komponen Cloud Foundry open source.

Men-deploy ke Cloud Run

Anda harus membuat file definisi layanan untuk digunakan di Cloud Run:

  1. Buat akun layanan untuk aplikasi Anda:

    gcloud iam service-accounts create spring-music
    
  2. Buat file service.yaml dengan kode berikut:

    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. Men-deploy layanan ke Cloud Run:

    gcloud run services replace service.yaml
    

    Setelah deployment selesai, Anda dapat membuka aplikasi Spring Music yang sedang berjalan di URL yang di-deploy.

Langkah Berikutnya