העברה לקונטיינרים של OCI

בדף הזה מתוארת תשתית הבנייה שנדרשת כדי לשחזר את תהליך build של Cloud Foundry במהלך יצירת תמונות של אפליקציות שתואמות ל-OCI. אם כבר השלמתם את מדריך ההעברה של Spring Music, תוכלו להשתמש במאמר הזה כדי לקבל מידע מעמיק על הגדרות העברה ספציפיות לאפליקציה שלכם.

דיאגרמה שמתארת איך ליצור תמונות OCI באמצעות כלים מודרניים

לפני שמתחילים

  1. מוודאים שהגדרתם פרויקט חדש ל-Cloud Run כמו שמתואר בדף הגדרת Cloud Run.
  2. מוודאים שיש לכם REGISTRY_URI לאחסון קונטיינרים. ב-Cloud Run מומלץ להשתמש ב-Artifact Registry. ‫Docker משמש ליצירת קובצי אימג' ביניים כדי ליצור את הפרויקט.

הגדרת תהליך build שתואם ל-Cloud Foundry

כדי לתמוך בתהליך החדש הזה, צריך ליצור שני קונטיינרים בסיסיים של OCI:

  • קובץ אימג' של builder שמשקף את תהליך ה-build של Cloud Foundry ויכול ליצור קוד מקור של אפליקציה ב-droplets של Cloud Foundry.
  • אימג' של זמן ריצה שמשקף את זמן הריצה של האפליקציה ב-Cloud Foundry.

מנהלי הפלטפורמה צריכים לבצע את התהליך הזה לפחות פעם אחת. אחרי שהתהליך מוגדר, כל האפליקציות של Cloud Foundry שצריך להעביר ל-Cloud Run יכולות לשתף את קובצי האימג' של ה-build וההרצה.

יצירת קובץ האימג' של ה-builder

בקטע הזה נוצר קובץ אימג' של build באמצעות cflinux3 כקובץ האימג' הבסיסי. האימג' של ה-build משמש כסביבת ה-build ליצירת האימג' של האפליקציה.

  1. יוצרים ספרייה בשם build/ ומעבירים אליה את cd:

    mkdir build && cd build
    
  2. בתיקייה 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
    
  3. שימוש ב-Cloud Build כדי ליצור ולפרסם את קובץ האימג' של builder

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

    מחליפים את REGISTRY_URI בכתובת של Artifact Registry שבה רוצים לפרסם את אימג' הבנייה. לדוגמה: REGION-docker.pkg.dev/PROJECT_ID/REPOSITORY/builder:stable.

יצירת תמונת זמן הריצה

בקטע הזה נוצרת תמונה של ריצה באמצעות cflinux3 כתמונת הבסיס. תמונת ההפעלה משמשת כתמונת הבסיס כשיוצרים את תמונת האפליקציה הסופית.

  1. יוצרים ספרייה בשם run/ ומעבירים אליה את cd:

    mkdir run && cd run
    
  2. בתיקייה 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
    
  3. בתיקייה 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={}
    
  4. משתמשים ב-Cloud Build כדי ליצור ולפרסם את קובץ האימג' runtime:

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

    מחליפים את REGISTRY_URI בכתובת של Artifact Registry שבה רוצים לפרסם את אימג' הבנייה. לדוגמה: REGION-docker.pkg.dev/PROJECT_ID/REPOSITORY/runtime:stable.

יצירת אפליקציות Cloud Foundry כקובצי אימג' של OCI

לכל אפליקציה שמועברת ל-Cloud Run צריך להיות Dockerfile משלה, שתואם לאופן שבו Cloud Foundry מריץ אפליקציות. קובץ ה-Dockerfile מבצע את הפעולות הבאות:

  • טעינת קובץ האימג' של ה-builder.
  • מריצים את מחזור החיים של חבילת ה-buildpack בגרסה 2 כדי ליצור droplet.
  • הפעולה מחלצת את התוכן של ה-droplet.
  • טוען את התוכן של ה-droplet בקובץ האימג' של ההרצה כדי ליצור את קובץ האימג' של האפליקציה שאפשר להפעיל.

קובץ האימג' הסופי של האפליקציה תואם ל-Cloud Foundry ול-Cloud Run, כך שאפשר לבצע בדיקת A/B של ההעברה כדי לנפות באגים בהתנהגות לא צפויה.

התהליך הזה צריך להתבצע על ידי צוות האפליקציה לכל אפליקציה שצריך להעביר.

איסוף מידע על בנייה מאפליקציית Cloud Foundry שנפרסה

  1. בודקים את ערימת האפליקציות. המידע על ה-stack מסופק באמצעות הדגל -s ב-cf push או בשדה stack של מניפסט האפליקציה.

    1. אם ה-stack הוא Windows, סביר להניח שהאפליקציה לא תואמת ל-Cloud Run. כדי להמשיך, צריך להעביר את האפליקציה ל-Linux.
    2. אם מחסנית הטכנולוגיות ריקה, cflinuxfs3 או cflinuxfs4, אפשר להעביר את האפליקציה ל-Cloud Run.
  2. אוספים את רשימת ה-buildpacks של האפליקציה. ה-buildpacks מסופקים באמצעות הדגל -b ב-cf push, השדה buildpack במניפסט האפליקציה או השדה buildpacks במניפסט האפליקציה.

    1. אם לא מציינים buildpacks, המשמעות היא שהם מזוהים אוטומטית. אפשר לעיין ברשימת חבילות ה-buildpack שזוהו בפריסת האפליקציה האחרונה ב-Cloud Foundry, או לציין אותן באופן מפורש אם אתם יודעים את הנתיבים.
    2. אם חבילות ה-buildpack הן כתובות URL, רושמים את כתובות ה-URL וממשיכים לשלב הבא.
    3. אם משתמשים ב-buildpack עם שם מקוצר, אפשר להשתמש בטבלה הבאה כדי למפות אותו לכתובת URL:

      שם מקוצר כתובת 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

      אפשר למצוא את המקור של חבילות buildpack פחות נפוצות בארגון Cloud Foundry GitHub.

  3. מאתרים את קוד המקור של התמונה. המקור מסופק באמצעות המאפיין path של מניפסט האפליקציה או הדגל -p של הפקודה cf push. אם המקור לא מוגדר, הוא מתייחס לספרייה הנוכחית.

  4. בודקים אם יש קובץ .cfignore בספריית קוד המקור. אם הוא נמצא שם, מעבירים אותו לקובץ בשם .gcloudignore.

פיתוח אפליקציית Cloud Foundry

בשלב הזה, מארגנים את רכיבי ה-build במבנה התיקיות הבא:

.
├── cloudbuild.yaml
├── Dockerfile
├── .gcloudignore
└── src
    ├── go.mod
    └── main.go
  • cloudbuild.yaml מספק ל-Cloud Build הוראות בנייה ספציפיות
  • Dockerfile ישתמש בתמונות של build ו-run מהשלבים הקודמים כדי ליצור את תמונת האפליקציה
  • src/ מכיל את קוד המקור של האפליקציה
  1. יוצרים קובץ בשם 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
    
  2. יוצרים בספרייה קובץ בשם 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: BUILD_IMAGE_URI
      _RUN_IMAGE:  RUN_IMAGE_URI
      _BUILDPACKS: BUILDPACK_URL
      _TAG: APP_ARTIFACT_REGISTRY/APP_NAME:latest
    
    • מחליפים את BUILD_IMAGE_URI ב-URI של קובץ האימג' של ה-build שנוצר בשלבים הקודמים.
    • מחליפים את RUN_IMAGE_URI במזהה המשאבים האחיד (URI) של קובץ האימג' של ההרצה שנוצר בשלבים הקודמים.
    • מחליפים את BUILDPACK_URL בכתובות ה-URL של חבילות ה-buildpack שבהן נעשה שימוש באפליקציה. אפשר להזין רשימה מופרדת בפסיקים עם כמה חבילות buildpack.
  3. אם יש לכם קובץ .cfignore, מעתיקים אותו לספרייה עם השם .gcloudignore.

  4. יוצרים ספרייה בשם src בספרייה.

  5. מעתיקים את התוכן של הבקשה אל src:

    1. אם המקור הוא קובץ ZIP (כולל קובצי .jar), צריך לבטל את הדחיסה של התוכן לתוך src.
    2. אם קוד המקור הוא ספרייה, מעתיקים את התוכן אל src.
  6. מריצים את הפקודה gcloud builds submit . כדי ליצור את האפליקציה.

בעיות תאימות ידועות

  • ‫Buildpacks שמסתמכים על משתני סביבה שמוזרקים על ידי Cloud Foundry, כמו VCAP_SERVICES, לא יפעלו. במקום זאת, צריך להצהיר במפורש על תלות במה שהם מזריקים באמצעות מערכת הניהול של השפה.
  • כדי לתקן את התמונות שנוצרו בדרך הזו, צריך לבנות מחדש את התמונה באמצעות גרסה חדשה יותר של תמונת הבנייה וההפעלה. אם מריצים תמונות של אפליקציות ב-Cloud Foundry, הן לא יתוקנו אוטומטית על ידי עדכון של תאי גזע BOSH.
  • ה-Builds יתבצעו בסביבת רשת שונה מזו של אשכול Cloud Foundry, ולכן יכול להיות שתצטרכו להגדיר מאגרי Cloud Build בהתאמה אישית עם גישה למאגרי המידע הפנימיים של החבילות.

המאמרים הבאים