Exemple de migration de Cloud Foundry vers Cloud Run : Spring Music

Cet exemple de migration utilise le projet Spring Music pour montrer comment créer une application Cloud Foundry en tant qu'image d'application compatible OCI. Cet exemple utilise la stratégie de migration Lift and Shift, qui utilise des composants Open Source de l'écosystème Cloud Foundry. Après avoir créé l'image de l'application, vous devez configurer l'application pour le déploiement sur Cloud Run.

Avant de commencer

  • Assurez-vous d'avoir configuré un nouveau projet pour Cloud Run, comme décrit sur la page de configuration.
  • Assurez-vous de disposer d'un REGISTRY_URI pour le stockage de conteneurs. Cloud Run recommande d'utiliser Artifact Registry.
  • Si vous êtes soumis à une règle d'administration de restriction de domaine limitant les appels non authentifiés pour votre projet, vous devez accéder au service déployé comme décrit dans la section Tester les services privés.

  • Installez Docker sur votre poste de travail. Docker est utilisé pour créer des images intermédiaires pour créer le projet.

Autorisations requises pour déployer

Pour ce guide, vous devez disposer des autorisations nécessaires pour créer, stocker l'image de conteneur créée et pour le déploiement.

Vous devez disposer des rôles suivants :

Structure du projet

Pour ce guide, nous vous recommandons de créer un répertoire de projet (par exemple, cr-spring-music/) et de créer des sous-répertoires au fur et à mesure que vous progressez dans le guide.

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

Créer l'image compilée

Dans cette section, vous allez créer une image de build en utilisant cflinux3 comme image de base. L'image de build est utilisée comme environnement de compilation pour créer l'image d'application.

  1. Créez un répertoire appelé build/ et utilisez cd pour y accéder :

    mkdir build && cd build
    
  2. Dans le dossier build/, créez un fichier appelé Dockerfile et collez-y le code suivant:

    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. Utiliser Cloud Build pour compiler et publier l'image builder

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

    Remplacez REGISTRY_URI par l'adresse du registre Artifact Registry dans lequel vous souhaitez publier l'image de compilation. Exemple : REGION-docker.pkg.dev/PROJECT_ID/REPOSITORY/builder:stable.

Créer l'image de l'environnement d'exécution

Dans cette section, vous allez créer une image d'exécution en utilisant cflinux3 comme image de base. L'image d'exécution est utilisée comme image de base lorsque vous créez l'image d'application finale.

  1. Créez un répertoire appelé run/ et utilisez cd pour y accéder :

    mkdir run && cd run
    
  2. Dans le dossier run/, créez un script shell nommé entrypoint.bash avec le code suivant:

    #!/usr/bin/env bash
    set -e
    
    if [[ "$@" == "" ]]; then
    exec /lifecycle/launcher "/home/vcap/app" "" ""
    else
    exec /lifecycle/launcher "/home/vcap/app" "$@" ""
    fi
    
  3. Dans le dossier run/, créez un fichier appelé Dockerfile et collez-y le code suivant:

    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. Utilisez Cloud Build pour créer et publier l'image runtime:

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

    Remplacez REGISTRY_URI par l'adresse du registre Artifact Registry dans lequel vous souhaitez publier l'image de compilation. Exemple : REGION-docker.pkg.dev/PROJECT_ID/REPOSITORY/runtime:stable..

Compiler Spring Music pour Cloud Foundry

Pour cloner le projet Spring Music et exécuter les commandes de compilation comme si nous le déployions sur Cloud Foundry :

  1. Clonez le dépôt Spring Music :

    git clone https://github.com/cloudfoundry-samples/spring-music.git
    
  2. Pour les besoins de ce guide, nous utiliserons une ancienne version de l'application Spring Music qui utilise Java 8 et Spring Boot 2. Pour ce faire, nous allons passer à une révision plus ancienne du projet Spring Music :

    git checkout 610ba471a643a20dee7a62d88a7879f13a21d6a3
    
  3. Accédez au dépôt:

    cd spring-music
    
  4. Créez le binaire Spring Music:

    ./gradlew clean assemble
    

Vous disposez maintenant d'un dossier build/ avec l'application Spring Music compilée prête à être transférée vers une instance Cloud Foundry.

Convertir Spring Music en une application compatible avec Cloud Run

Vous devez préparer le résultat de la commande de compilation pour préparer l'artefact Spring Music pour le déploiement dans Cloud Run.

  1. Créez un répertoire de préproduction cr-app et créez-y un sous-répertoire src :

    mkdir -p cr-app/src
    
  2. Imiter cf push en extrayant le contenu du fichier JAR compilé dans le répertoire src:

    unzip build/libs/spring-music-1.0.jar -d cr-app/src
    
  3. Remplacez le répertoire par cr-app/:

    cd cr-app/
    
  4. Créez un fichier appelé Dockerfile. Dockerfile utilisera l'image de build et l'image d'exécution créées lors des étapes précédentes pour créer l'image d'application exécutable pour Spring Music à l'aide du buildpack Java.

  5. Collez le code suivant dans le fichier 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
    

Compiler Spring Music en tant qu'image conforme à l'OCI

Au cours de cette étape, vous allez indiquer à Cloud Build comment créer une image conforme à l'OCI à l'aide de l'image de build, de l'image d'exécution et du fichier Dockerfile de l'application créés aux étapes précédentes.

Pour créer l'image conforme à l'OCI, procédez comme suit:

  1. Créez un fichier appelé cloudbuild.yaml : Il s'agit d'une configuration de compilation qui indique à Cloud Build comment compiler l'application.

  2. Collez la configuration suivante dans 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
    
    • Remplacez REGISTRY_URI par l'URI du registre de conteneurs dans lequel vous avez publié le compilateur et l'exécuteur.
  3. Générez l'image d'application à l'aide de Cloud Build :

    gcloud builds submit .
    

    Une fois la compilation terminée, notez l'URI de l'image obtenue. Vous en aurez besoin pour déployer l'application lors des étapes suivantes. L'image obtenue est une image de conteneur compatible avec l'OCI pour l'exécution de l'application Spring Music, créée à l'aide des composants Open Source Cloud Foundry.

Déployer dans Cloud Run

Vous devez créer un fichier de définition de service à utiliser dans Cloud Run:

  1. Créez un compte de service pour votre application :

    gcloud iam service-accounts create spring-music
    
  2. Créez un fichier service.yaml avec le code suivant :

    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. Déployez le service dans Cloud Run:

    gcloud run services replace service.yaml
    

    Une fois le déploiement terminé, vous pourrez accéder à l'application Spring Music en cours d'exécution à l'URL déployée.

Étape suivante