Migra a contenedores de OCI

En esta página, se describe la infraestructura de compilación necesaria para reproducir el proceso de compilación de Cloud Foundry mientras se generan imágenes de aplicaciones compatibles con OCI. Si ya completaste la guía de migración de Spring Music, puedes usar este análisis detallado en la configuración de migración específica para tu aplicación.

Diagrama que describe cómo crear imágenes de OCI con herramientas modernas

Antes de comenzar

  1. Asegúrate de haber configurado un proyecto nuevo para Cloud Run, como se describe en la página Configuración de Cloud Run.
  2. Asegúrate de tener un REGISTRY_URI para almacenar contenedores. Cloud Run recomienda usar Artifact Registry. Docker se usa para crear imágenes intermedias para compilar el proyecto.

Configura un proceso de compilación compatible con Cloud Foundry

Debes crear dos contenedores de OCI base para admitir este proceso nuevo:

  • Una imagen de compilador que replica el proceso de compilación de Cloud Foundry y es capaz de compilar el código fuente de la aplicación en los Droplets de Cloud Foundry.
  • Una imagen de entorno de ejecución que replica el entorno de ejecución de la aplicación de Cloud Foundry.

Los administradores de la plataforma deben realizar este proceso al menos una vez. Una vez que se establece el proceso, todas las aplicaciones de Cloud Foundry que necesitan migrar a Cloud Run pueden compartir las imágenes de compilación y ejecución.

Crea la imagen del compilador

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 aplicaciones de Cloud Foundry como imágenes de OCI

Cada aplicación migrada a Cloud Run necesita su propio Dockerfile que coincida con la forma en que Cloud Foundry ejecuta aplicaciones. El Dockerfile hace lo siguiente:

  • Carga la imagen del compilador.
  • Ejecuta el ciclo de vida del paquete de compilación v2 para crear un Droplet.
  • Extrae el contenido del Droplet.
  • Carga el contenido del Droplet en la imagen de ejecución para crear la imagen de la aplicación ejecutable.

La imagen final de la aplicación es compatible con Cloud Foundry y Cloud Run, por lo que puedes realizar una prueba A/B de tu migración para depurar cualquier comportamiento inesperado.

El equipo de aplicación de cada aplicación que deba migrarse debe realizar este proceso.

Recopila información de compilación desde una aplicación implementada de Cloud Foundry

  1. Observa la pila de aplicaciones. La pila se proporciona a través de la marca -s en cf push o el campo stack del manifiesto de la aplicación.

    1. Si la pila es Windows, es probable que la aplicación no sea compatible con Cloud Run. Debes transferir la aplicación a Linux antes de continuar.
    2. Si la pila está en blanco, cflinuxfs3 o cflinuxfs4 se puede migrar la aplicación a Cloud Run.
  2. Recopila la lista de los paquetes de compilación de la aplicación. Los paquetes de compilación se proporcionan a través de la marca -b en cf push, el campo buildpack en el manifiesto de la aplicación o el campo buildpacks del manifiesto de la aplicación.

    1. Si no se especifican paquetes de compilación, significa que se detectan de forma automática. Mira la lista de paquetes de compilación detectados en la implementación de tu aplicación más reciente en Cloud Foundry o especifícalos de forma explícita si conoces las rutas de acceso.
    2. Si los paquetes de compilación son URL, toma nota de las URLs y continúa con el siguiente paso.
    3. Para cualquier paquete de compilación que use un nombre corto, usa la siguiente tabla para asignarlo a las URLs:

      Nombre corto URL
      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

      La fuente para paquetes de compilación menos comunes se puede encontrar en la organización de GitHub de Cloud Foundry.

  3. Recopila la ubicación del código fuente de la imagen. La fuente se proporciona a través del atributo path del manifiesto de la aplicación o la marca -p del comando cf push. Si la fuente no está definida, se refiere al directorio actual.

  4. Determina si hay un archivo .cfignore en el directorio del código fuente. Si está allí, muévela a un archivo llamado .gcloudignore.

Compila la aplicación de Cloud Foundry

En este paso, organizas los elementos de compilación en la siguiente estructura de carpetas:

.
├── cloudbuild.yaml
├── Dockerfile
├── .gcloudignore
└── src
    ├── go.mod
    └── main.go
  • cloudbuild.yaml proporciona Cloud Build con instrucciones de compilación específicas
  • Dockerfile usará las imágenes de compilación y ejecución de los pasos anteriores para crear la imagen de la aplicación
  • src/ contiene el código fuente de la aplicación
  1. Crea un archivo llamado Dockerfile en el directorio con el siguiente contenido:

    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
    
  2. Crea un archivo llamado cloudbuild.yaml en el directorio con el siguiente contenido:

    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
    
    • Reemplaza BUILD_IMAGE_URI por el URI de la imagen de compilación creada en los pasos anteriores.
    • Reemplaza RUN_IMAGE_URI por el URI de la imagen de ejecución creada en los pasos anteriores.
    • Reemplaza BUILDPACK_URL por las URLs de los paquetes de compilación que usa tu aplicación. Puede ser una lista separada por comas con varios paquetes de compilación.
  3. Si tienes un archivo .cfignore, cópialo en el directorio con el nombre .gcloudignore.

  4. Crea un directorio llamado src en el directorio.

  5. Copia el contenido de tu aplicación en src:.

    1. Si el origen es un archivo ZIP (incluidos los archivos .jar), descomprime el contenido en src.
    2. Si el código fuente es un directorio, copia el contenido en src.
  6. Ejecuta gcloud builds submit . para compilar tu aplicación.

Incompatibilidades conocidas

  • Los paquetes de compilación que se basan en las variables de entorno insertadas de Cloud Foundry como VCAP_SERVICES no funcionarán. En cambio, debes declarar explícitamente una dependencia sobre lo que insertan con el sistema de administración de lenguajes.
  • Para aplicar un parche a las imágenes producidas de esta manera, debes volver a compilar la imagen con una versión más reciente de la imagen de compilación y ejecución. A las imágenes de la aplicación no se les aplicarán parches de forma automática si actualizas las stemcells BOSH si las ejecutas en Cloud Foundry.
  • Las compilaciones se realizarán en un entorno de red diferente del de Cloud Foundry, por lo que es posible que debas configurar grupos personalizados de Cloud Build con acceso a las duplicaciones internas de paquetes.

Pasos siguientes