Zu OCI-Containern migrieren

Auf dieser Seite wird die Build-Infrastruktur beschrieben, die zum Reproduzieren des Cloud Foundry-Build-Prozesses beim Generieren von OCI-kompatiblen Anwendungs-Images erforderlich ist. Wenn Sie bereits die Migrationsanleitung für Spring Music durchgearbeitet haben, können Sie hier detaillierte Informationen zu den Migrationskonfigurationen für Ihre Anwendung erhalten.

Diagramm zur Erstellung von OCI-Images mit modernen Tools

Hinweise

  1. Prüfen Sie, ob Sie ein neues Projekt für Cloud Run eingerichtet haben, wie auf der Seite Cloud Run-Einrichtung beschrieben.
  2. Sie benötigen einen REGISTRY_URI zum Speichern von Containern. Cloud Run empfiehlt die Verwendung von Artifact Registry. Docker wird zum Erstellen von Zwischen-Images verwendet, um das Projekt zu erstellen.

Mit Cloud Foundry kompatiblen Build-Prozess einrichten

Zur Unterstützung dieses neuen Prozesses müssen Sie zwei OCI-Basis-Container erstellen:

  • Ein Builder-Image, das den Build-Prozess von Cloud Foundry spiegelt und in der Lage ist, Quellcode der Anwendung in Cloud Foundry-Droplets zu erstellen.
  • Ein Laufzeit-Image, das die Cloud Foundry-Anwendungslaufzeit spiegelt.

Dieser Vorgang muss mindestens einmal von Plattformadministratoren durchgeführt werden. Sobald der Prozess abgeschlossen ist, können die Build- und Ausführungs-Images von allen Cloud Foundry-Anwendungen geteilt werden, die zu Cloud Run migriert werden müssen.

Builder-Image erstellen

In diesem Abschnitt wird ein Build-Image mit cflinux3 als Basis-Image erstellt. Das Build-Image wird als Build-Umgebung zum Erstellen des Anwendungs-Images verwendet.

  1. Erstellen Sie in diesem Verzeichnis das Verzeichnis build/ und darin cd:

    mkdir build && cd build
    
  2. Erstellen Sie im Ordner build/ eine neue Datei mit dem Namen Dockerfile und fügen Sie den folgenden Code ein:

    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 zum Erstellen und Veröffentlichen des builder-Images verwenden

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

    Ersetzen Sie dabei REGISTRY_URI durch die Adresse der Artifact Registry, in der Sie das Build-Image veröffentlichen möchten. Beispiel: REGION-docker.pkg.dev/PROJECT_ID/REPOSITORY/builder:stable.

Laufzeit-Image erstellen

In diesem Abschnitt wird ein Ausführungs-Image mit cflinux3 als Basis-Image erstellt. Das Ausführungs-Image wird als Basis-Image verwendet, wenn Sie das endgültige Anwendungs-Image erstellen.

  1. Erstellen Sie ein Verzeichnis namens run/ und darin cd:

    mkdir run && cd run
    
  2. Erstellen Sie im Ordner run/ ein neues Shell-Skript namens entrypoint.bash mit folgendem Code:

    #!/usr/bin/env bash
    set -e
    
    if [[ "$@" == "" ]]; then
    exec /lifecycle/launcher "/home/vcap/app" "" ""
    else
    exec /lifecycle/launcher "/home/vcap/app" "$@" ""
    fi
    
  3. Erstellen Sie im Ordner run/ eine neue Datei mit dem Namen Dockerfile und fügen Sie den folgenden Code ein:

    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. Verwenden Sie Cloud Build, um das runtime-Image zu erstellen und zu veröffentlichen:

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

    Ersetzen Sie REGISTRY_URI durch die Adresse der Artifact Registry, in der Sie das Build-Image veröffentlichen möchten. Beispiel: REGION-docker.pkg.dev/PROJECT_ID/REPOSITORY/runtime:stable.

Cloud Foundry-Anwendungen als OCI-Images erstellen

Jede zu Cloud Run migrierte Anwendung benötigt ein eigenes Dockerfile für die Ausführung von Anwendungen durch Cloud Foundry. Das Dockerfile hat folgende Funktion:

  • Lädt das Builder-Image.
  • Führt den V2-Buildpack-Lebenszyklus aus, um ein Droplet zu erstellen.
  • Extrahiert den Inhalt des Droplets.
  • Lädt den Inhalt des Droplets in das Ausführungs-Image, um das ausführbare Anwendungs-Image zu erstellen.

Das endgültige Anwendungs-Image ist sowohl mit Cloud Foundry als auch mit Cloud Run kompatibel, sodass Sie einen A/B-Test der Migration durchführen können, um unerwartetes Verhalten zu beheben.

Dieser Prozess muss vom Anwendungsteam für jede zu migrierende Anwendung ausgeführt werden.

Build-Informationen aus einer bereitgestellten Cloud Foundry-Anwendung erfassen

  1. Sehen Sie sich das Anwendungspaket an. Der Stack wird über das Flag -s in cf push oder im Feld stack des Anwendungsmanifests bereitgestellt.

    1. Wenn der Stack Windows ist, ist die Anwendung wahrscheinlich nicht mit Cloud Run kompatibel. Sie müssen die Anwendung zu Linux portieren, bevor Sie fortfahren.
    2. Wenn der Stack leer ist, kann cflinuxfs3 oder cflinuxfs4 die Anwendung zu Cloud Run migriert werden.
  2. Erfassen Sie die Liste der Anwendungs-Buildpacks. Buildpacks werden über das Flag -b in cf push, das Feld buildpack im Anwendungsmanifest oder das Feld buildpacks des Anwendungsmanifests bereitgestellt.

    1. Wenn keine Buildpacks angegeben sind, werden sie automatisch erkannt. Sehen Sie sich die Liste der erkannten Buildpacks in Ihrer letzten Anwendungsbereitstellung in Cloud Foundry an oder geben Sie sie explizit an, wenn Sie die Pfade kennen.
    2. Wenn die Buildpacks URLs sind, notieren Sie sich die URLs und fahren Sie mit dem nächsten Schritt fort.
    3. Verwenden Sie für jedes Buildpack, das einen Kurznamen verwendet, die folgende Tabelle, um sie URLs zuzuordnen:

      Kurzform 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

      Die Quelle für weniger gängige Buildpacks finden Sie in der GitHub-Organisation für Cloud Foundry.

  3. Erfassen Sie den Speicherort des Quellcodes für das Image. Die Quelle wird über das Attribut path des Anwendungsmanifests oder das Flag -p des Befehls cf push bereitgestellt. Wenn die Quelle nicht definiert ist, bezieht sie sich auf das aktuelle Verzeichnis.

  4. Prüfen Sie, ob sich im Quellcodeverzeichnis die Datei .cfignore befindet. Wenn sie sich dort befindet, verschieben Sie sie in eine Datei mit dem Namen .gcloudignore..

Cloud Foundry-Anwendung erstellen

In diesem Schritt organisieren Sie die Build-Elemente in der folgenden Ordnerstruktur:

.
├── cloudbuild.yaml
├── Dockerfile
├── .gcloudignore
└── src
    ├── go.mod
    └── main.go
  • cloudbuild.yaml bietet Cloud Build mit spezifischen Build-Anweisungen.
  • Dockerfile verwendet die Build- und Ausführungs-Images aus den vorherigen Schritten, um das Anwendungs-Image zu erstellen.
  • src/ enthält Ihren Anwendungsquellcode.
  1. Erstellen Sie eine Dockerfile-Datei im Verzeichnis mit folgendem Inhalt:

    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. Erstellen Sie eine cloudbuild.yaml-Datei im Verzeichnis mit folgendem Inhalt:

    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
    
    • Ersetzen Sie BUILD_IMAGE_URI durch den URI des Build-Images, das in den vorherigen Schritten erstellt wurde.
    • Ersetzen Sie RUN_IMAGE_URI durch den URI des Ausführungs-Images, das in den vorherigen Schritten erstellt wurde.
    • Ersetzen Sie BUILDPACK_URL durch die URLs der Buildpacks, die von Ihrer Anwendung verwendet werden. Dies kann eine durch Kommas getrennte Liste mit mehreren Buildpacks sein.
  3. Wenn Sie eine .cfignore-Datei haben, kopieren Sie sie in das Verzeichnis mit dem Namen .gcloudignore.

  4. Erstellen Sie im Verzeichnis das Verzeichnis src.

  5. Kopieren Sie den Inhalt Ihrer Anwendung in src:.

    1. Wenn die Quelle eine ZIP-Datei ist (einschließlich .jar-Dateien), entpacken Sie den Inhalt in src.
    2. Wenn der Quellcode ein Verzeichnis ist, kopieren Sie den Inhalt in src.
  6. Führen Sie gcloud builds submit . aus, um die Anwendung zu erstellen.

Bekannte Inkompatibilitäten

  • Buildpacks, die auf von Cloud Foundry eingefügten Umgebungsvariablen wie VCAP_SERVICES basieren, funktionieren nicht. Sie sollten stattdessen explizit eine Abhängigkeit von den Inhalten einfügen, die über das Verwaltungssystem Ihrer Sprache eingefügt werden.
  • Um die auf diese Weise erzeugten Images zu patchen, müssen Sie das Image mit einer neueren Version des Build- und Ausführungs-Images neu erstellen. Anwendungs-Images werden durch die Aktualisierung von BOSH-Stemcells nicht automatisch gepatcht, wenn Sie sie in Cloud Foundry ausführen.
  • Builds werden in einer anderen Netzwerkumgebung als Ihr Cloud Foundry-Cluster ausgeführt. Möglicherweise müssen Sie benutzerdefinierte Cloud Build-Pools einrichten, um Zugriff auf Ihre internen Paketspiegel zu haben.

Weitere Informationen