Migración de muestra: Spring Music

En esta migración de muestra, se usa el proyecto Spring Music para mostrar cómo se puede compilar una aplicación de Cloud Foundry como una imagen de la aplicación compatible con OCI. En esta muestra, se usa la estrategia lift-and-shift, que utiliza componentes de código abierto del ecosistema de Cloud Foundry. Después de crear la imagen de la aplicación, debes configurarla para su implementación en Cloud Run.

Antes de comenzar

  • Asegúrate de haber configurado un proyecto nuevo para Cloud Run, como se describe en la página de configuración.
  • Asegúrate de tener un REGISTRY_URI para almacenar contenedores. Cloud Run recomienda usar Artifact Registry.
  • Si estás bajo una política de la organización de restricción de dominios que restringe las invocaciones no autenticadas para tu proyecto, deberás acceder al servicio implementado como se describe en Prueba servicios privados.

  • Instala Docker en tu estación de trabajo. Docker se usa para crear imágenes intermedias para compilar el proyecto.

Permisos necesarios para realizar una implementación

En esta guía, necesitas permisos para compilar, almacenar la imagen de contenedor compilada y realizar su implementación.

Debes tener los siguientes roles:

Estructura del proyecto

Para esta guía, te sugerimos que crees un directorio del proyecto, p. ej., cr-spring-music/, y subdirectorios a medida que avanzas a través de la guía.

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

Crea la imagen de compilación

En esta sección, se crea una imagen de compilación con cflinux3 como la imagen base. La imagen de compilación se usa como entorno de compilación para crear la imagen de la aplicación.

  1. Crea un directorio llamado build/ y cd en él:

    mkdir build && cd build
    
  2. En la carpeta build/, crea un archivo nuevo llamado Dockerfile y pega el siguiente código:

    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. Usa Cloud Build para compilar y publicar la imagen builder

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

    Reemplaza REGISTRY_URI por la dirección de Artifact Registry en el que deseas publicar la imagen de compilación. Por ejemplo: REGION-docker.pkg.dev/PROJECT_ID/REPOSITORY/builder:stable

Crea la imagen del entorno de ejecución

En esta sección, se crea una imagen de ejecución con cflinux3 como la imagen base. La imagen de ejecución se usa como la imagen base cuando creas la imagen final de la aplicación.

  1. Crea un directorio llamado run/ y cd en él:

    mkdir run && cd run
    
  2. En la carpeta run/, crea una secuencia de comandos de shell nueva llamada entrypoint.bash con el siguiente código:

    #!/usr/bin/env bash
    set -e
    
    if [[ "$@" == "" ]]; then
    exec /lifecycle/launcher "/home/vcap/app" "" ""
    else
    exec /lifecycle/launcher "/home/vcap/app" "$@" ""
    fi
    
  3. En la carpeta run/, crea un archivo nuevo llamado Dockerfile y pega el siguiente código:

    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. Usa Cloud Build para compilar y publicar la imagen runtime:

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

    Reemplaza REGISTRY_URI por la dirección en Artifact Registry en el que deseas publicar la imagen de compilación. Por ejemplo: REGION-docker.pkg.dev/PROJECT_ID/REPOSITORY/runtime:stable.

Compila Spring Music para Cloud Foundry

Para clonar el proyecto Spring Music y ejecutar los comandos de compilación como si implementaras el proyecto en Cloud Foundry, sigue estos pasos:

  1. Clona el repositorio de Spring Music:

    git clone https://github.com/cloudfoundry-samples/spring-music.git
    
  2. Para los fines de esta guía, usaremos una versión anterior de la aplicación de Spring Music que usa Java 8 y Spring Boot 2. Para hacerlo, pasaremos a una revisión anterior del proyecto Spring Music:

    git checkout 610ba471a643a20dee7a62d88a7879f13a21d6a3
    
  3. Migra al repositorio:

    cd spring-music
    
  4. Compila el objeto binario de Spring Music:

    ./gradlew clean assemble
    

Ahora tienes una carpeta build/ con la app de Spring Music compilada lista para enviarse a una instancia de Cloud Foundry.

Convierte Spring Music en una aplicación compatible con Cloud Run

Debes tomar la salida del comando de compilación para preparar el artefacto de Spring Music para su implementación en Cloud Run.

  1. Crea un directorio de etapa de pruebas cr-app y un subdirectorio src dentro de él:

    mkdir -p cr-app/src
    
  2. Imita cf push a través de la extracción del contenido del JAR compilado en el directorio src:

    unzip build/libs/spring-music-1.0.jar -d cr-app/src
    
  3. Cambia el directorio a cr-app/:

    cd cr-app/
    
  4. Crea un archivo nuevo llamado Dockerfile de la siguiente manera: Este Dockerfile usará la imagen de compilación y la imagen del entorno de ejecución creadas en los pasos anteriores para crear la imagen de la aplicación ejecutable para Spring Music con el paquete de compilación de Java.

  5. Pega el siguiente código en 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
    

Compila Spring Music como una imagen compatible con OCI

En este paso, le indicas a Cloud Build cómo construir una imagen compatible con OCI a través de la imagen de compilación, la imagen del entorno de ejecución y el Dockerfile de la aplicación creados en los pasos anteriores.

Para crear la imagen compatible con OCI, haz lo siguiente:

  1. Crea un archivo llamado cloudbuild.yaml. Esta es una configuración de compilación que le indicará a Cloud Build cómo compilar la aplicación.

  2. Pega la siguiente configuración en 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
    
    • Reemplaza REGISTRY_URI por el URI de Container Registry en el que publicaste el compilador y el ejecutor.
  3. Compila la imagen de la aplicación con Cloud Build:

    gcloud builds submit .
    

    Cuando se complete la compilación, toma nota del URI de la imagen resultante. La necesitarás cuando implementes la aplicación en los pasos siguientes. La imagen resultante será una imagen de contenedor compatible con OCI para ejecutar la app Spring Music, compilada con componentes de código abierto de Cloud Foundry.

Implementa en Cloud Run

Debes crear un archivo de definición de servicio para usarlo en Cloud Run:

  1. Crea una cuenta de servicio para tu aplicación:

    gcloud iam service-accounts create spring-music
    
  2. Crea un archivo service.yaml con el siguiente código:

    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. Implementa el servicio en Cloud Run:

    gcloud run services replace service.yaml
    

    Una vez que se complete la implementación, podrás visitar la aplicación Spring Music en ejecución en la URL implementada.

Pasos siguientes