מעבר מאפליקציית Google App Engine Java ל-Cloud Run באמצעות Buildpacks

1. סקירה כללית

סדרת שיעורי ה-codelab (מדריכים מעשיים בקצב אישי) הזו נועדה לעזור למפתחי Java ב-Google App Engine (Standard) לחדש את האפליקציות שלהם באמצעות סדרה של העברות. בעזרת השלבים האלה תוכלו לעדכן את האפליקציה כדי שתהיה ניידת יותר, ולהחליט להכניס אותה לקונטיינר בשביל Cloud Run, שירות אירוח הקונטיינרים של Google Cloud שהוא שירות אחות של App Engine, ושירותים אחרים לאירוח קונטיינרים.

במדריך הזה נלמד איך ליצור קונטיינר לאפליקציית App Engine כדי לפרוס אותה בשירות המנוהל באופן מלא Cloud Run באמצעות Buildpacks. ‫Buildpacks הם פרויקט של CNCF שמאפשר לכם לקחת את האפליקציה ישירות מקוד המקור ולהפוך אותה לקובצי אימג' ניידים מאוד שיכולים לפעול בכל ענן.

בנוסף להסבר על השלבים הנדרשים למעבר מ-App Engine ל-Cloud Run, נסביר גם איך לשדרג אפליקציית Java 8 App Engine ל-Java 17.

אם האפליקציה שרוצים להעביר משתמשת הרבה בשירותים מקובצים מדור קודם של App Engine או בתכונות ספציפיות אחרות של App Engine, יכול להיות שהמדריך גישה לשירותים מקובצים של App Engine ל-Java 11/17 מתאים יותר מה-codelab הזה.

כאן אפשר להבין איך

  • שימוש ב-Cloud Shell
  • הפעלת Cloud Run,‏ Artifact Registry ו-Cloud Build APIs
  • יצירת קונטיינר לאפליקציה באמצעות Buildpacks ב-Cloud Build
  • פריסת קובצי אימג' של קונטיינרים ב-Cloud Run

מה תצטרכו

סקר

איך תשתמשו במדריך הזה?

רק לקרוא לקרוא ולבצע את התרגילים

איך היית מדרג את החוויה שלך עם Java?

מתחילים ביניים מומחים

איזה דירוג מתאים לדעתך לחוויית השימוש שלך בשירותי Google Cloud?

מתחילים ביניים מומחים

2. רקע

מערכות PaaS כמו App Engine ו-Cloud Functions מספקות הרבה יתרונות לצוות ולאפליקציה, למשל מאפשרות לאדמינים של מערכות ולצוותי DevOps להתמקד בבניית פתרונות. פלטפורמות ללא שרתים מאפשרות לאפליקציה להגדיל את הקיבולת באופן אוטומטי לפי הצורך, לצמצם את הקיבולת לאפס באמצעות חיוב לפי שימוש כדי לעזור לכם לשלוט בעלויות, ולהשתמש במגוון שפות פיתוח נפוצות.

עם זאת, הגמישות של קונטיינרים היא גם יתרון משמעותי. האפשרות לבחור כל שפה, כל ספרייה וכל תוכנה בינארית מאפשרת לכם ליהנות מכל העולמות: הנוחות של שרתים וירטואליים יחד עם הגמישות של קונטיינרים. בדיוק בשביל זה נועד Google Cloud Run.

המדריך הזה לא כולל הסבר על השימוש ב-Cloud Run. אפשר לקרוא על כך במסמכי התיעוד של Cloud Run. המטרה כאן היא להכיר את האופן שבו יוצרים קונטיינר לאפליקציית App Engine עבור Cloud Run (או שירותים אחרים שמארחים קונטיינרים). לפני שממשיכים, חשוב לדעת כמה דברים, בעיקר שחוויית המשתמש תהיה שונה מעט.

ב-Codelab הזה תלמדו איך ליצור ולפרוס קונטיינרים. תלמדו איך להפוך את האפליקציה לקונטיינר באמצעות Buildpacks, איך להפסיק להשתמש בהגדרות של App Engine ואיך להגדיר שלבי בנייה ב-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:

  1. התקנה או היכרות מחדש עם gcloud CLI
  2. מאתחלים את ה-CLI של gcloud עבור הפרויקט באמצעות gcloud init
  3. יוצרים את פרויקט App Engine באמצעות gcloud app create
  4. פריסת אפליקציית הדוגמה ב-App Engine
./mvnw package appengine:deploy -Dapp.projectId=$PROJECT_ID
  1. אישור שהאפליקציה פועלת ב-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 כדי לצמצם את ההבדלים בהתנהגות ברירת המחדל אחרי ההעברה.

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. הגדרת build

לאחר מכן, מסירים את ההגדרה כדי לארוז את האפליקציה כ-WAR. הפעולה הזו לא דורשת הרבה הגדרות, במיוחד בפרויקטים שמשתמשים ב-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 – צריך ליצור מחדש באופן ידני, והן יוסברו בפירוט רב יותר במודולים הבאים.

אפליקציית הדוגמה לא משתמשת בשירותים מדור קודם שצורפו לחבילה, אבל משתמשים שהאפליקציות שלהם כן משתמשות בשירותים כאלה יכולים לעיין במדריכים הבאים:

מעכשיו תבצעו פריסה ל-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 מאחורי הקלעים כדי לספק חוויית פריסה ללא מגע יד. שימו לב: כדי להשתמש בתכונה הזו, אתם צריכים חשבון עם לפחות אחת מההרשאות הבאות, ולבצע את שלבי הגדרת הסביבה, או להשתמש ב-Cloud Shell:

אחרי שמוודאים שהדרישות המוקדמות האלה מתקיימות, פשוט מריצים את הפקודה הבאה מספריית קובצי המקור:

gcloud run deploy SERVICE --source .

במהלך הפעלת הפקודה deploy, תתבקשו לספק כמה פרטים, למשל:

  • ציון המיקום של קוד המקור
  • הזנת שם השירות
  • הפעלת Cloud Run API
  • בחירת האזור

אחרי שתענו על ההנחיות האלה, יתחיל תהליך הבנייה והפריסה, שבמהלכו Cloud Build יבצע את הפעולות הבאות:

  • מכווץ ושומר את המקור בקטגוריה של Cloud Storage
  • משתמש ב-buildpacks של Cloud Native Computing Foundation ברקע כדי ליצור את קובץ האימג'
  • יוצר רישום לאחסון קובץ אימג' של קונטיינר שמתקבל (אם הוא עדיין לא קיים)
  • יוצר שירות Cloud Run לאירוח האפליקציה (אם הוא לא קיים כבר)

אחרי שהבנייה והפריסה יסתיימו, תקבלו הודעה שמסבירה שגרסה חדשה פעילה ומשרתת 100% מהתנועה.

6. סיכום/ניקוי

מזל טוב, שדרגת, יצרת קונטיינר, העברת את האפליקציה שלך, ובכך סיימת את המדריך הזה!

מכאן, השלב הבא הוא לקרוא מידע נוסף על תכונות האבטחה של CI/CD ושל שרשרת אספקת התוכנה, שזמינות לכם עכשיו כשאתם יכולים לבצע פריסה באמצעות Cloud Build:

אופציונלי: פינוי נפח אחסון או השבתה של שירות

אם פרסתם את האפליקציה לדוגמה ב-App Engine במהלך המדריך הזה, אל תשכחו להשבית את האפליקציה כדי להימנע מחיובים. כשרוצים לעבור ל-codelab הבא, אפשר להפעיל אותו מחדש. בזמן שאפליקציות App Engine מושבתות, הן לא מקבלות תנועה ולכן לא צוברות חיובים. עם זאת, יכול להיות שיהיו חיובים על השימוש ב-Datastore אם הוא חורג מהמכסה החינמית, לכן צריך למחוק מספיק נתונים כדי שלא לחרוג מהמגבלה הזו.

מצד שני, אם אתם לא מתכוונים להמשיך בהעברות ורוצים למחוק הכול לגמרי, אתם יכולים למחוק את השירות או להשבית את הפרויקט לגמרי.

7. מקורות מידע נוספים

App Engine migration module codelabs issues/feedback

אם נתקלתם בבעיות ב-codelab הזה, כדאי לחפש את הבעיה לפני ששולחים דיווח. קישורים לחיפוש וליצירה של בעיות חדשות:

מקורות מידע על העברת נתונים

משאבים באינטרנט

בהמשך מופיעים מקורות מידע באינטרנט שעשויים להיות רלוונטיים למדריך הזה:

App Engine

מידע אחר על Cloud

סרטונים

רישיון

עבודה זו מורשית תחת רישיון Creative Commons שמותנה בייחוס 2.0 כללי.