1. סקירה כללית
סדרת שיעורי ה-codelab (מדריכים מעשיים בקצב אישי) הזו נועדה לעזור למפתחי Java ב-Google App Engine (Standard) לחדש את האפליקציות שלהם באמצעות סדרה של העברות. בעזרת השלבים האלה תוכלו לעדכן את האפליקציה כדי שתהיה ניידת יותר, ולהחליט להכניס אותה לקונטיינר בשביל Cloud Run, שירות אירוח הקונטיינרים של Google Cloud שהוא שירות אחות של App Engine, ושירותים אחרים לאירוח קונטיינרים.
במדריך הזה נסביר איך להכניס לאריזת Container אפליקציית App Engine כדי לפרוס אותה לשירות המנוהל במלואו Cloud Run באמצעות Jib. בעזרת Jib, אפשר ליצור תמונות Docker, פלטפורמה מוכרת בתעשייה לפיתוח, למשלוח ולהרצה של אפליקציות בקונטיינרים.
בנוסף להסבר על השלבים הנדרשים למעבר מ-App Engine ל-Cloud Run, נסביר גם איך לשדרג אפליקציית Java 8 App Engine ל-Java 17.
אם האפליקציה שלכם עושה שימוש נרחב בשירותים מקובצים מדור קודם של App Engine או בתכונות אחרות של App Engine, מומלץ להעביר את האפליקציה מהשירותים המקובצים האלה או להחליף את התכונות האלה לפני המעבר ל-Cloud Run. אם אתם צריכים עוד זמן כדי לבדוק את אפשרויות המיגרציה או שאתם רוצים להמשיך להשתמש בשירותים הקודמים שצורפו לחבילה בינתיים, אתם יכולים להמשיך לגשת לשירותים שצורפו לחבילה של App Engine ל-Java 11/17 כשמשדרגים לסביבת זמן ריצה חדשה יותר. כשהאפליקציה שלכם תהיה ניידת יותר, תוכלו לחזור ל-Codelab הזה כדי ללמוד איך ליישם את ההוראות באפליקציה.
כאן אפשר להבין איך
- שימוש ב-Cloud Shell
- הפעלת Cloud Run, Artifact Registry ו-Cloud Build APIs
- העברת האפליקציה לקונטיינר באמצעות Jib ו-Cloud Build
- פריסת קובצי אימג' של קונטיינרים ב-Cloud Run
מה תצטרכו
- פרויקט ב-Google Cloud Platform עם חשבון חיוב פעיל ב-GCP ועם App Engine מופעל
- ידע מעשי בפקודות נפוצות של Linux
- ידע בסיסי בפיתוח ופריסה של אפליקציות App Engine
- אפליקציית סרוולט Java 8 שרוצים להעביר ל-Java 17 ולפרוס ב-Cloud Run (יכולה להיות אפליקציה ב-App Engine או רק המקור)
סקר
איך תשתמשו במדריך הזה?
איך היית מדרג את החוויה שלך עם Java?
איזה דירוג מתאים לדעתך לחוויית השימוש שלך בשירותי Google Cloud?
2. רקע
מערכות פלטפורמה כשירות (PaaS) כמו App Engine ו-Cloud Functions מספקות הרבה יתרונות לצוות ולאפליקציה, למשל הן מאפשרות לאדמינים של מערכות ולצוותי DevOps להתמקד בבניית פתרונות. פלטפורמות ללא שרתים מאפשרות לאפליקציה להגדיל את הקיבולת באופן אוטומטי לפי הצורך, לצמצם את הקיבולת לאפס באמצעות חיוב לפי שימוש כדי לעזור לכם לשלוט בעלויות, ולהשתמש במגוון שפות פיתוח נפוצות.
עם זאת, הגמישות של קונטיינרים היא גם יתרון משמעותי. האפשרות לבחור כל שפה, כל ספרייה וכל תוכנה בינארית מאפשרת לכם ליהנות מכל העולמות: הנוחות של שרתים וירטואליים יחד עם הגמישות של קונטיינרים. בדיוק בשביל זה יש את Cloud Run.
המדריך הזה לא כולל הסבר על השימוש ב-Cloud Run. אפשר לקרוא על כך במסמכי התיעוד של Cloud Run. המטרה כאן היא להכיר את האופן שבו יוצרים קונטיינר לאפליקציית App Engine עבור Cloud Run (או שירותים אחרים שמארחים קונטיינרים). לפני שממשיכים, חשוב לדעת כמה דברים, בעיקר שחוויית המשתמש תהיה שונה מעט.
ב-Codelab הזה תלמדו איך ליצור ולפרוס קונטיינרים. במאמר הזה נסביר איך:
- יצירת קונטיינר לאפליקציה באמצעות Jib
- מעבר מהגדרת App Engine
- ואם רוצים, מגדירים שלבי build ל-Cloud Build.
הפעולה הזו תכלול מעבר מתכונות מסוימות שספציפיות ל-App Engine. אם אתם לא רוצים לפעול לפי השלבים האלה, אתם יכולים לשדרג לסביבת ריצה של Java 11/17 תוך כדי השארת האפליקציות ב-App Engine.
3. הגדרה/עבודה מקדימה
1. הגדרת פרויקט
במדריך הזה נשתמש באפליקציה לדוגמה ממאגר appengine-java-migration-samples בפרויקט חדש לגמרי. מוודאים שיש בפרויקט חשבון פעיל לחיוב.
אם אתם מתכוונים להעביר אפליקציית App Engine קיימת אל Cloud Run, אתם יכולים להשתמש באפליקציה הזו כדי לפעול לפי ההוראות.
מריצים את הפקודה הבאה כדי להפעיל את ממשקי ה-API הנדרשים לפרויקט:
gcloud services enable artifactregistry.googleapis.com cloudbuild.googleapis.com run.googleapis.com
2. קבלת אפליקציה לדוגמה של בסיס
משכפלים את האפליקציה לדוגמה במחשב שלכם או ב-Cloud Shell, ואז עוברים לתיקייה baseline.
הדוגמה היא אפליקציית Datastore מבוססת-Servlet ב-Java 8, שמיועדת לפריסה ב-App Engine. פועלים לפי ההוראות בקובץ ה-README כדי להכין את האפליקציה לפריסה ב-App Engine.
3. (אופציונלי) פריסת אפליקציית בסיס
השלב הבא נדרש רק אם רוצים לוודא שהאפליקציה פועלת ב-App Engine לפני המעבר ל-Cloud Run.
פועלים לפי השלבים בקובץ README.md:
- התקנה או היכרות מחדש עם
gcloudCLI - מאתחלים את ה-CLI של gcloud עבור הפרויקט באמצעות
gcloud init - יוצרים את פרויקט App Engine באמצעות
gcloud app create - פריסת אפליקציית הדוגמה ב-App Engine
./mvnw package appengine:deploy -Dapp.projectId=$PROJECT_ID
- אישור שהאפליקציה פועלת ב-App Engine ללא בעיות
4. יצירת מאגר ב-Artifact Registry
אחרי שמכניסים את האפליקציה לקונטיינר, צריך מקום לשליחה ולאחסון של קובצי האימג' של הקונטיינרים. הדרך המומלצת לעשות זאת ב-Google Cloud היא באמצעות Artifact Registry.
יוצרים את המאגר בשם migration באמצעות gcloud באופן הבא:
gcloud artifacts repositories create migration --repository-format=docker \
--description="Docker repository for the migrated app" \
--location="northamerica-northeast1"
שימו לב שהמאגר הזה משתמש בפורמט docker, אבל יש כמה סוגים של מאגרים.
בשלב הזה, יש לכם אפליקציית App Engine בסיסית, והפרויקט שלכם ב-Google Cloud מוכן להעברה אל Cloud Run.
4. שינוי קבצים של אפליקציות
במקרים שבהם האפליקציה שלכם עושה שימוש נרחב בשירותים, בהגדרות או בתכונות אחרות של App Engine מדור קודם, אנחנו ממליצים להמשיך לגשת לשירותים האלה בזמן השדרוג לסביבת זמן הריצה החדשה. Codelab זה מדגים נתיב העברה לאפליקציות שכבר משתמשות בשירותים עצמאיים, או שאפשר לבצע בהן ארגון הקוד מחדש (Refactoring) כדי שיוכלו להשתמש בשירותים כאלה.
1. שדרוג ל-Java 17
אם האפליקציה שלכם מבוססת על Java 8, כדאי לשדרג לגרסה מאוחרת יותר של LTS כמו 11 או 17 כדי להתעדכן בעדכוני אבטחה ולקבל גישה לתכונות חדשות של השפה.
כדי להתחיל, צריך לעדכן את המאפיינים ב-pom.xml כך שיכללו את המאפיינים הבאים:
<properties>
<java.version>17</java.version>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
</properties>
הפעולה הזו תגדיר את גרסת הפרויקט ל-17, תודיע לתוסף של הקומפיילר שאתם רוצים גישה לתכונות השפה של Java 17, ותגרום לכך שהמחלקות המקומפלות יהיו תואמות ל-JVM של Java 17.
2. כולל שרת אינטרנט
יש כמה הבדלים בין App Engine לבין Cloud Run שכדאי לקחת בחשבון כשעוברים ביניהם. הבדל אחד הוא שבזמן הריצה של Java 8 ב-App Engine, שרת Jetty סופק ונוהל על ידי האפליקציות שהוא אירח, אבל ב-Cloud Run זה לא קורה. נשתמש ב-Spring Boot כדי לספק לנו שרת אינטרנט ומאגר סרוולטים.
מוסיפים את יחסי התלות הבאים:
<dependencies>
<!-- ... -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>2.6.6</version>
<exclusions>
<!-- Exclude the Tomcat dependency -->
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- Use Jetty instead -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jetty</artifactId>
<version>2.6.6</version>
</dependency>
<!-- ... -->
</dependencies>
Spring Boot מטמיע שרת Tomcat כברירת מחדל, אבל בדוגמה הזו לא נכלל הארטיפקט הזה, והמערכת תשתמש ב-Jetty כדי לצמצם את ההבדלים בהתנהגות ברירת המחדל אחרי ההעברה. אפשר גם להגדיר את גרסת Jetty כך שתהיה זהה לגרסה ש-App Engine מספקת כברירת מחדל.
<properties>
<java.version>17</java.version>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<jetty.version>9.4.46.v20220331</jetty.version>
</properties>
3. הגדרה של Spring Boot
מערכת Spring Boot תוכל לעשות שימוש חוזר ב-servlets שלכם בלי לבצע שינויים, אבל היא תדרוש הגדרה מסוימת כדי לאפשר גילוי.
יוצרים את המחלקה MigratedServletApplication.java הבאה בחבילה com.example.appengine:
package com.example.appengine;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletComponentScan;
@ServletComponentScan
@SpringBootApplication
@EnableAutoConfiguration
public class MigratedServletApplication {
public static void main(String[] args) {
SpringApplication.run(MigratedServletApplication.class, args);
}
}
שימו לב: זה כולל את ההערה @ServletComponentScan, שתחפש (בחבילה הנוכחית כברירת מחדל) כל @WebServlets ותהפוך אותם לזמינים כצפוי.
4. אריזת האפליקציה כקובץ JAR
אפשר להכניס את האפליקציה לקונטיינר באמצעות Jib החל מקובץ WAR, אבל יהיה קל יותר אם תארזו את האפליקציה כקובץ JAR שניתן להפעלה. הפעולה הזו לא דורשת הרבה הגדרות, במיוחד בפרויקטים שמשתמשים ב-Maven ככלי בנייה, כי אריזת jar היא התנהגות ברירת המחדל.
מסירים את התג packaging בקובץpom.xml:
<packaging>war</packaging>
לאחר מכן, מוסיפים את spring-boot-maven-plugin:
<plugins>
<!-- ... -->
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>2.6.6</version>
</plugin>
<!-- ... -->
</plugins>
5. מעבר מהגדרות, משירותים ומהתלויות של App Engine
כמו שציינו בתחילת ה-codelab, Cloud Run ו-App Engine נועדו לספק חוויות משתמש שונות. תכונות מסוימות ש-App Engine מציע מחוץ לקופסה – כמו השירותים Cron ו-Task Queue – צריך ליצור מחדש באופן ידני, והן יוסברו בפירוט רב יותר במודולים הבאים.
אפליקציית הדוגמה לא משתמשת בשירותים מדור קודם שצורפו לחבילה, אבל משתמשים שהאפליקציות שלהם כן משתמשות בשירותים כאלה יכולים לעיין במדריכים הבאים:
- מעבר מחבילות שירותים כדי למצוא שירותים עצמאיים מתאימים.
- העברת קובצי הגדרות XML ל-YAML, למשתמשים שעוברים לזמני הריצה של Java 11/17 ונשארים ב-App Engine.
מעכשיו תבצעו פריסה ל-Cloud Run, ולכן אפשר להסיר את appengine-maven-plugin:
<plugin>
<groupId>com.google.cloud.tools</groupId>
<artifactId>appengine-maven-plugin</artifactId>
<version>2.4.1</version>
<configuration>
<!-- can be set w/ -DprojectId=myProjectId on command line -->
<projectId>${app.projectId}</projectId>
<!-- set the GAE version or use "GCLOUD_CONFIG" for an autogenerated GAE version -->
<version>GCLOUD_CONFIG</version>
</configuration>
</plugin>
5. העברה של אפליקציה לקונטיינר
בשלב הזה אפשר לפרוס את האפליקציה באופן ידני ב-Cloud Run ישירות מקוד המקור. זו אפשרות מצוינת שמשתמשת ב-Cloud Build מאחורי הקלעים כדי לספק חוויית פריסה ללא מגע יד. במודולים הבאים נסביר על פריסות של מקורות בצורה מפורטת יותר.
לחלופין, אם אתם צריכים יותר שליטה באופן הפריסה של האפליקציה, אתם יכולים להשיג זאת על ידי הגדרת קובץ cloudbuild.yaml שמפרט באופן מפורש את שלבי ה-build הרצויים:
1. הגדרת קובץ cloudbuild.yaml
יוצרים את הקובץ cloudbuild.yaml הבא באותה רמה כמו pom.xml:
steps:
# Test your build
- name: maven:eclipse-temurin
entrypoint: mvn
args: ["test"]
# Build with Jib
- name: maven:eclipse-temurin
entrypoint: mvn
args: [ "compile", "com.google.cloud.tools:jib-maven-plugin:3.2.1:build", "-Dimage=northamerica-northeast1-docker.pkg.dev/PROJECT_ID/migration/visitors:jib"]
# Deploy to Cloud Run
- name: 'gcr.io/google.com/cloudsdktool/cloud-sdk'
entrypoint: gcloud
args: [ 'run', 'deploy', 'visitors', '--image', 'northamerica-northeast1-docker.pkg.dev/PROJECT_ID/migration/visitors:jib', '--region', 'northamerica-northeast1', '--allow-unauthenticated']
אחרי שאומרים ל-Cloud Build לפעול לפי השלבים האלה, הוא:
- הרצת הבדיקות באמצעות
./mvnw test - יצירה, העברה ותיוג של תמונה ב-Artifact Registry באמצעות Jib
- פריסת האימג' ב-Cloud Run באמצעות
gcloud run deploy
שימו לב ש-‘visitors' מסופק ל-Cloud Run כשם השירות הרצוי. הדגל –allow-unauthenticated מאפשר למשתמשים לבקר באפליקציית האינטרנט בלי לדרוש אימות. חשוב להחליף את PROJECT_ID במזהה הפרויקט שלכם בקובץ cloudbuild.yaml.
לאחר מכן, מוסיפים את הקישורים הבאים של מדיניות IAM כדי לאפשר לחשבון השירות של Cloud Build לגשת ל-Artifact Registry:
export PROJECT_ID=$(gcloud config list --format 'value(core.project)')
export PROJECT_NUMBER=$(gcloud projects describe $PROJECT_ID --format="value(projectNumber)" )
gcloud projects add-iam-policy-binding $PROJECT_ID \
--member=serviceAccount:$PROJECT_NUMBER@cloudbuild.gserviceaccount.com \
--role=roles/run.admin \
--project=$PROJECT_ID
gcloud iam service-accounts add-iam-policy-binding $PROJECT_NUMBER-compute@developer.gserviceaccount.com \
--member=serviceAccount:$PROJECT_NUMBER@cloudbuild.gserviceaccount.com \
--role roles/iam.serviceAccountUser --project=$PROJECT_ID
2. הפעלת תהליך build
אחרי שעדכנתם את Cloud Build לגבי שלבי ה-build הרצויים, אתם מוכנים לפריסה בלחיצה אחת.
מריצים את הפקודה הבאה:
gcloud builds submit
בסיום התהליך, קובץ אימג' של קונטיינר נבנה, אוחסן ב-Artifact Registry ונפרס ב-Cloud Run.
בסיום ה-codelab, האפליקציה שלכם אמורה להיראות כמו האפליקציה ב- java17-and-cloud-run/finish.
זהו, אתה מוכן! הצלחתם להעביר אפליקציית Java 8 App Engine ל-Java 17 ול-Cloud Run, ועכשיו יש לכם הבנה ברורה יותר של העבודה הנדרשת כשעוברים בין אפשרויות אירוח ובוחרים ביניהן.
6. סיכום/ניקוי
מזל טוב, שדרגת, יצרת קונטיינר, העברת את האפליקציה שלך, ובכך סיימת את המדריך הזה!
מכאן, השלב הבא הוא לקרוא מידע נוסף על תכונות האבטחה של CI/CD ושל שרשרת אספקת התוכנה, שזמינות לכם עכשיו כשאתם יכולים לבצע פריסה באמצעות Cloud Build:
- יצירת שלבים מותאמים אישית של build באמצעות Cloud Build
- יצירה וניהול של טריגרים לפיתוח גרסת Build
- שימוש בסריקה לפי דרישה בצינור העיבוד של Cloud Build
אופציונלי: פינוי נפח אחסון או השבתה של שירות
אם פרסתם את האפליקציה לדוגמה ב-App Engine במהלך המדריך הזה, אל תשכחו להשבית את האפליקציה כדי להימנע מחיובים. כשרוצים לעבור ל-codelab הבא, אפשר להפעיל אותו מחדש. בזמן שאפליקציות App Engine מושבתות, הן לא מקבלות תנועה ולכן לא צוברות חיובים. עם זאת, יכול להיות שיהיו חיובים על השימוש ב-Datastore אם הוא חורג מהמכסה החינמית, לכן צריך למחוק מספיק נתונים כדי שלא לחרוג מהמגבלה הזו.
מצד שני, אם אתם לא מתכוונים להמשיך בהעברות ורוצים למחוק הכול לגמרי, אתם יכולים למחוק את השירות או להשבית את הפרויקט לגמרי.
7. מקורות מידע נוספים
App Engine migration module codelabs issues/feedback
אם נתקלתם בבעיות ב-codelab הזה, כדאי לחפש את הבעיה לפני ששולחים דיווח. קישורים לחיפוש וליצירה של בעיות חדשות:
מקורות מידע על העברת נתונים
- אפשרויות להעברה של שירותי App Engine
- הגדרת טריגרים של Build ל-Cloud Build
- מידע נוסף על מעבר ל-Java 11/17
משאבים באינטרנט
בהמשך מופיעים מקורות מידע באינטרנט שעשויים להיות רלוונטיים למדריך הזה:
App Engine
- מסמכי App Engine
- מידע על התמחור ועל המכסות ב-App Engine
- השוואה בין פלטפורמות מהדור הראשון לבין פלטפורמות מהדור השני
- תמיכה לטווח ארוך בסביבות זמן ריצה מדור קודם
מידע אחר על Cloud
- רמת השימוש 'תמיד בחינם' ב-Google Cloud
- Google Cloud CLI (
gcloudCLI) - כל מסמכי התיעוד של Google Cloud
סרטונים
- Serverless Migration Station
- מסעות ללא שרת
- הרשמה למינוי לערוץ Google Cloud Tech
- הרשמה לניוזלטר של Google Developers
רישיון
עבודה זו מורשית תחת רישיון Creative Commons שמותנה בייחוס 2.0 כללי.