בדוגמה הזו להעברה נעשה שימוש בפרויקט Spring Music כדי להראות איך אפשר ליצור אפליקציה תואמת OCI מתוך אפליקציית Cloud Foundry. בדוגמה הזו נעשה שימוש באסטרטגיית Lift and Shift, שמתבססת על רכיבי קוד פתוח מהסביבה העסקית של Cloud Foundry. אחרי שיוצרים את קובץ האימג' של האפליקציה, צריך להגדיר את האפליקציה לפריסה ב-Cloud Run.
לפני שמתחילים
- מוודאים שהגדרתם פרויקט חדש ל-Cloud Run כמו שמתואר בדף ההגדרה.
- מוודאים שיש לכם
REGISTRY_URIלאחסון קונטיינרים. מומלץ להשתמש ב-Artifact Registry ב-Cloud Run. אם אתם כפופים למדיניות ארגונית של הגבלת דומיין שמגבילה הפעלות לא מאומתות של הפרויקט, תצטרכו לגשת לשירות הפרוס שלכם כמו שמתואר בקטע בדיקת שירותים פרטיים.
- מתקינים את Docker בתחנת העבודה. Docker משמש ליצירת קובצי אימג' ביניים כדי ליצור את הפרויקט.
ההרשאות שנדרשות לפריסה
כדי לבצע את הפעולות במדריך הזה, צריך הרשאות לבנייה, לאחסון של קובץ האימג' של הקונטיינר ולפריסה.
אתם צריכים להיות בעלי התפקידים הבאים:
- תפקיד עריכה ב-Cloud Build
- תפקיד אדמין ב-Artifact Registry
- התפקיד 'אדמין לניהול נפח האחסון'
- תפקיד האדמין ב-Cloud Run
- התפקיד 'משתמש בחשבון שירות'
מבנה הפרויקט
במדריך הזה אנחנו מציעים ליצור ספריית פרויקט, למשל cr-spring-music/
ולצור ספריות משנה תוך כדי קריאת המדריך.
cr-spring-music/
├── build
├── run
└── spring-music
יצירת תמונת ה-build
בקטע הזה נוצר קובץ אימג' של build באמצעות cflinux3 כקובץ האימג' הבסיסי. קובץ האימג' ל-build משמש כסביבת ה-build ליצירת קובץ האימג' של האפליקציה.
יוצרים ספרייה בשם
build/ומעבירים אליה אתcd:mkdir build && cd buildבתיקייה
build/, יוצרים קובץ חדש בשםDockerfileומדביקים בו את הקוד הבא: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שימוש ב-Cloud Build כדי ליצור ולפרסם את קובץ האימג'
buildergcloud builds \ submit --tag "REGISTRY_URI/builder:stable"מחליפים את
REGISTRY_URIבכתובת של Artifact Registry שבה רוצים לפרסם את אימג' הבנייה. לדוגמה:REGION-docker.pkg.dev/PROJECT_ID/REPOSITORY/builder:stable.
יצירת תמונה נטענת לאפקט
בקטע הזה נוצרת תמונה של ריצה באמצעות cflinux3 כתמונת הבסיס. תמונת ההרצה משמשת כתמונת הבסיס כשיוצרים את תמונת האפליקציה הסופית.
יוצרים ספרייה בשם
run/ומעבירים אליה אתcd:mkdir run && cd runבתיקייה
run/, יוצרים סקריפט מעטפת חדש בשםentrypoint.bashעם הקוד הבא:#!/usr/bin/env bash set -e if [[ "$@" == "" ]]; then exec /lifecycle/launcher "/home/vcap/app" "" "" else exec /lifecycle/launcher "/home/vcap/app" "$@" "" fiבתיקייה
run/, יוצרים קובץ חדש בשםDockerfileומדביקים בו את הקוד הבא: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={}משתמשים ב-Cloud Build כדי ליצור ולפרסם את קובץ האימג'
runtime:gcloud builds submit \ --tag "REGISTRY_URI/runtime:stable"מחליפים את
REGISTRY_URIבכתובת של Artifact Registry שבה רוצים לפרסם את אימג' ה-build. לדוגמה:REGION-docker.pkg.dev/PROJECT_ID/REPOSITORY/runtime:stable.
פיתוח Spring Music ל-Cloud Foundry
כדי לשכפל את הפרויקט Spring Music ולהריץ את פקודות ה-build כאילו אנחנו פורסים את הפרויקט ב-Cloud Foundry:
משכפלים את מאגר Spring Music:
git clone https://github.com/cloudfoundry-samples/spring-music.gitלצורך המדריך הזה, נשתמש בגרסה ישנה יותר של אפליקציית Spring Music שמשתמשת ב-Java 8 וב-Spring Boot 2. כדי לעשות את זה, נעבור לגרסה קודמת של פרויקט Spring Music:
git checkout 610ba471a643a20dee7a62d88a7879f13a21d6a3עוברים למאגר:
cd spring-musicיוצרים את הקובץ הבינארי של Spring Music:
./gradlew clean assemble
עכשיו יש לכם תיקייה של build/ עם אפליקציית Spring Music שעברה קומפילציה ומוכנה להעברה למופע של Cloud Foundry.
המרת Spring Music לאפליקציה שתואמת ל-Cloud Run
צריך להשתמש בפלט של פקודת ה-build כדי להכין את ארטיפקט Spring Music לפריסה ב-Cloud Run.
יוצרים ספריית ביניים
cr-appותיקיית משנהsrcבתוכה:mkdir -p cr-app/srcמחקים את
cf pushעל ידי חילוץ התוכן של קובץ ה-JAR המהודר אל הספרייהsrc:unzip build/libs/spring-music-1.0.jar -d cr-app/srcשינוי הספרייה ל-
cr-app/:cd cr-app/יוצרים קובץ חדש בשם
Dockerfile. הפקודהDockerfileתשתמש בקובץ האימג' של ה-build ובקובץ האימג' של זמן הריצה שנוצרו בשלבים הקודמים כדי ליצור את קובץ האימג' של האפליקציה שאפשר להריץ עבור Spring Music, באמצעות Java buildpack.מדביקים את הקוד הבא ב-
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
יצירת Spring Music כתמונה שתואמת ל-OCI
בשלב הזה, נותנים ל-Cloud Build הוראות איך ליצור תמונה שתואמת ל-OCI באמצעות תמונת ה-build, תמונת זמן הריצה וקובץ ה-Dockerfile של האפליקציה שנוצרו בשלבים הקודמים.
כדי ליצור את האימג' שתואם ל-OCI:
יוצרים קובץ בשם
cloudbuild.yaml. זהו קובץ הגדרות של build שמכיל הוראות ל-Cloud Build לגבי אופן יצירת האפליקציה.מדביקים את ההגדרה הבאה ב-
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- מחליפים את
REGISTRY_URIבמזהה המשאבים האחיד (URI) של מאגר הקונטיינרים שבו פרסמתם את ה-builder ואת ה-runner.
- מחליפים את
יוצרים את קובץ האימג' של האפליקציה באמצעות Cloud Build:
gcloud builds submit .בסיום ה-build, רושמים את ה-URI של קובץ האימג' שנוצר. תצטרכו אותו כשפורסים את האפליקציה בשלבים הבאים. קובץ האימג' שיתקבל יהיה קובץ אימג' של קונטיינר שתואם ל-OCI להרצת אפליקציית Spring Music, שנוצר באמצעות רכיבי Cloud Foundry בקוד פתוח.
פריסה ב-Cloud Run
כדי להשתמש ב-Cloud Run, צריך ליצור קובץ הגדרת שירות:
יוצרים חשבון שירות לאפליקציה:
gcloud iam service-accounts create spring-musicיוצרים קובץ
service.yamlעם הקוד הבא: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- מחליפים את
PROJECT_NUMBERבמספר הפרויקט. - מחליפים את
SPRING_IMAGE_URIב-URI של תמונת האפליקציה שנוצרה בקטע build Spring Music as an OCI compliant image.
- מחליפים את
פורסים את השירות ב-Cloud Run:
gcloud run services replace service.yamlאחרי שהפריסה תסתיים, תוכלו להיכנס לאפליקציית Spring Music הפועלת בכתובת ה-URL שנפרסה.
המאמרים הבאים
- למידע נוסף על תהליך יצירת הקונטיינרים, אפשר לעיין במאמר בנושא העברה לקונטיינרים של OCI.