การย้ายข้อมูลจากแอป Java ของ Google App Engine ไปยัง Cloud Run ด้วย Docker

1. ภาพรวม

ชุด Codelab นี้ (บทแนะนำแบบลงมือปฏิบัติด้วยตนเอง) มีจุดมุ่งหมายเพื่อช่วยให้นักพัฒนา Java ของ Google App Engine (Standard) ปรับแอปให้ทันสมัยโดยแนะนำขั้นตอนการย้ายข้อมูลต่างๆ การทำตามขั้นตอนเหล่านี้จะช่วยให้อัปเดตแอปให้พกพาได้มากขึ้นและตัดสินใจทำคอนเทนเนอร์สำหรับ Cloud Run ซึ่งเป็นบริการในเครือของ Google Cloud ที่ให้บริการโฮสติ้งคอนเทนเนอร์สำหรับ App Engine และบริการโฮสติ้งคอนเทนเนอร์อื่นๆ

บทแนะนำนี้จะสอนวิธีสร้างคอนเทนเนอร์ให้กับแอป App Engine เพื่อนำไปใช้งานกับบริการที่มีการจัดการเต็มรูปแบบของ Cloud Run ด้วย Dockerfile Dockerfile เป็นวิธีการติดตั้งใช้งานที่ลงมือปฏิบัติได้มากที่สุดสำหรับการย้ายข้อมูลนี้ แต่ก็มีตัวเลือกมากที่สุดในการปรับแต่งกระบวนการบิลด์ด้วย

นอกจากจะสอนขั้นตอนที่จำเป็นในการย้ายจาก App Engine ไปยัง Cloud Run แล้ว คุณยังจะได้เรียนรู้วิธีอัปเกรดแอป App Engine ที่ใช้ Java 8 เป็น Java 17 ด้วย

หากแอปพลิเคชันที่คุณสนใจจะย้ายข้อมูลใช้บริการแบบกลุ่มเดิมของ App Engine อย่างหนัก หรือใช้ฟีเจอร์อื่นๆ ที่เฉพาะเจาะจงของ App Engine การเข้าถึงบริการแบบกลุ่มของ App Engine สำหรับ Java 11/17 อาจเป็นจุดเริ่มต้นที่ดีกว่า Codelab นี้

คุณจะได้เรียนรู้วิธีต่อไปนี้

  • ใช้ Cloud Shell
  • เปิดใช้ Cloud Run, Artifact Registry และ Cloud Build API
  • ทำแอปให้เป็นคอนเทนเนอร์โดยใช้ Docker และ Cloud Build
  • ทําให้อิมเมจคอนเทนเนอร์ใช้งานได้กับ Cloud Run

สิ่งที่คุณต้องมี

แบบสำรวจ

คุณจะใช้บทแนะนำนี้อย่างไร

อ่านอย่างเดียว อ่านและทำแบบฝึกหัด

คุณจะให้คะแนนประสบการณ์การใช้งาน Java เท่าใด

ผู้ฝึกหัด ขั้นกลาง ผู้ชำนาญ

คุณจะให้คะแนนประสบการณ์การใช้บริการ Google Cloud เท่าใด

ผู้ฝึกหัด ขั้นกลาง ผู้ชำนาญ

2. ฉากหลัง

ระบบ PaaS เช่น App Engine และ Cloud Functions มอบความสะดวกมากมายให้กับทีมและแอปพลิเคชันของคุณ เช่น การช่วยให้ผู้ดูแลระบบและ DevOps มุ่งเน้นที่การสร้างโซลูชันได้ แพลตฟอร์มแบบไร้เซิร์ฟเวอร์ช่วยให้แอปของคุณปรับขนาดขึ้นได้โดยอัตโนมัติตามต้องการ ลดขนาดลงเหลือ 0 ด้วยการเรียกเก็บเงินแบบจ่ายตามการใช้งานเพื่อช่วยควบคุมต้นทุน และใช้ภาษาการพัฒนาทั่วไปได้หลากหลาย

อย่างไรก็ตาม ความยืดหยุ่นของคอนเทนเนอร์ก็เป็นสิ่งที่น่าสนใจเช่นกัน เนื่องจากเลือกภาษา ไลบรารี และไบนารีใดก็ได้ คอนเทนเนอร์จึงให้ประโยชน์ทั้ง 2 อย่างแก่คุณ นั่นคือความสะดวกของแบบไร้เซิร์ฟเวอร์และความยืดหยุ่นของคอนเทนเนอร์ Google Cloud Run มีไว้เพื่อสิ่งนี้

การเรียนรู้วิธีใช้ Cloud Run ไม่อยู่ในขอบเขตของ Codelab นี้ แต่จะอยู่ในเอกสารประกอบของ Cloud Run เป้าหมายในที่นี้คือเพื่อให้คุณคุ้นเคยกับวิธีสร้างคอนเทนเนอร์แอป App Engine สำหรับ Cloud Run (หรือบริการอื่นๆ ที่โฮสต์คอนเทนเนอร์) ก่อนดำเนินการต่อ คุณควรทราบว่าประสบการณ์ของผู้ใช้จะแตกต่างออกไปเล็กน้อย

ใน Codelab นี้ คุณจะได้เรียนรู้วิธีสร้างและติดตั้งใช้งานคอนเทนเนอร์ คุณจะได้เรียนรู้วิธีสร้างคอนเทนเนอร์ของแอปด้วย Dockerfile, ย้ายข้อมูลจากการกำหนดค่า 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. เริ่มต้น gcloud CLI สำหรับโปรเจ็กต์ด้วย 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 นี้แสดงเส้นทางการย้ายข้อมูลสำหรับแอปพลิเคชันที่ใช้บริการแบบสแตนด์อโลนอยู่แล้ว หรือสามารถปรับโครงสร้างใหม่ได้อย่างเหมาะสม

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 มีความแตกต่างกันหลายประการที่ควรพิจารณาเมื่อย้ายข้อมูลระหว่าง 2 บริการนี้ ความแตกต่างอย่างหนึ่งคือขณะที่รันไทม์ Java 8 ของ App Engine มีและจัดการเซิร์ฟเวอร์ Jetty สำหรับแอปที่โฮสต์ไว้ แต่ Cloud Run ไม่ได้ทำเช่นนั้น เราจะใช้ Spring Boot เพื่อจัดหาเว็บเซิร์ฟเวอร์และคอนเทนเนอร์ Servlet ให้

เพิ่มทรัพยากร Dependency ต่อไปนี้

<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 จะสามารถนำ Servlet กลับมาใช้ใหม่ได้โดยไม่ต้องแก้ไข แต่ก็ต้องมีการกำหนดค่าบางอย่างเพื่อให้แน่ใจว่า Servlet จะค้นพบได้

สร้าง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

แม้ว่าคุณจะสามารถทำคอนเทนเนอร์แอปได้โดยเริ่มจาก 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

ดังที่ได้กล่าวไว้ในช่วงต้นของโค้ดแล็บ Cloud Run และ App Engine ออกแบบมาเพื่อมอบประสบการณ์การใช้งานที่แตกต่างกัน ฟีเจอร์บางอย่างที่ App Engine มีให้พร้อมใช้งาน เช่น บริการ Cron และคิวของงาน จะต้องสร้างขึ้นใหม่ด้วยตนเอง และเราจะกล่าวถึงรายละเอียดเพิ่มเติมในโมดูลต่อๆ ไป

แอปตัวอย่างไม่ได้ใช้บริการแบบแพ็กเกจเดิม แต่ผู้ใช้ที่มีแอปที่ใช้บริการดังกล่าวสามารถดูคำแนะนำต่อไปนี้

เนื่องจากคุณจะทำให้ใช้งานได้กับ 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 Build เกี่ยวกับวิธีสร้างคอนเทนเนอร์ของแอปพลิเคชันแล้ว เมื่อใช้วิธีการทำคอนเทนเนอร์นี้ คุณไม่จำเป็นต้องมีไฟล์การกำหนดค่าบิลด์แยกต่างหาก (cloudbuild.yaml) เราสามารถกำหนด Dockerfile ขั้นต่ำเป็นจุดเริ่มต้นได้ง่ายๆ ดังนี้

FROM eclipse-temurin

ARG JAR_FILE=JAR_FILE_MUST_BE_SPECIFIED_AS_BUILD_ARG

COPY ${JAR_FILE} app.jar

ENTRYPOINT ["java", "-jar","/app.jar"]

Dockerfile นี้จะรวมเวอร์ชัน uber-jar ของบริการ Spring Boot ไว้ในเลเยอร์เดียว เป็นแนวทางที่ง่ายที่สุดในการทำคอนเทนเนอร์ Dockerfile แต่ก็มีข้อเสียหลายประการ โดยเฉพาะอย่างยิ่งเมื่อเปรียบเทียบเวลาที่ทำซ้ำซึ่งมีการอ้างอิงที่ค่อนข้างเสถียร ข้อกังวลเช่นนี้เป็นเหตุผลที่ทำให้วิธีการคอนเทนเนอร์นี้ถือว่ามีความซับซ้อนมากขึ้น อย่างไรก็ตาม การเขียน Dockerfile ของคุณเองจะช่วยให้คุณควบคุมอิมเมจฐานได้อย่างสมบูรณ์และเข้าถึงประโยชน์ด้านประสิทธิภาพของการเขียนอิมเมจที่แบ่งเลเยอร์อย่างระมัดระวัง

2**. เรียกใช้กระบวนการบิลด์**

เมื่อแจ้ง Cloud Build เกี่ยวกับขั้นตอนการสร้างที่ต้องการแล้ว คุณก็พร้อมที่จะทำให้ใช้งานได้ในคลิกเดียว

เรียกใช้คำสั่งต่อไปนี้

gcloud builds submit --tag LOCATION-docker.pkg.dev/PROJECT_ID/REPOSITORY/IMAGE_NAME

แทนที่ค่าตัวยึดตำแหน่งในคำสั่งด้านบนด้วยค่าต่อไปนี้

  • LOCATION: ตำแหน่งระดับภูมิภาคหรือหลายภูมิภาคสำหรับที่เก็บข้อมูล
  • PROJECT_ID: รหัสโปรเจ็กต์ Cloud
  • REPOSITORY: ชื่อที่เก็บ Artifact Registry
  • IMAGE_NAME: ชื่อของอิมเมจคอนเทนเนอร์

เมื่อกระบวนการเสร็จสิ้นแล้ว ระบบจะสร้างอิมเมจคอนเทนเนอร์ จัดเก็บไว้ใน Artifact Registry และทําให้ใช้งานได้ใน Cloud Run

เมื่อสิ้นสุด Codelab นี้ แอปของคุณควรมีลักษณะเหมือนกับแอปในโฟลเดอร์ mod4-migrate-to-cloud-run

เพียงเท่านี้ก็เรียบร้อยแล้ว คุณย้ายข้อมูลแอป App Engine ที่เขียนด้วย Java 8 ไปยัง Java 17 และ Cloud Run เรียบร้อยแล้ว และตอนนี้ก็เข้าใจงานที่เกี่ยวข้องเมื่อเปลี่ยนและเลือกตัวเลือกการโฮสต์ได้ชัดเจนขึ้น

6. สรุป/ล้างข้อมูล

ยินดีด้วย คุณได้อัปเกรด คอนเทนเนอร์ ย้ายข้อมูล และแอปของคุณแล้ว ซึ่งเป็นการสิ้นสุดบทแนะนำนี้

จากนี้ ขั้นตอนถัดไปคือการดูข้อมูลเพิ่มเติมเกี่ยวกับฟีเจอร์ความปลอดภัยของ CI/CD และซัพพลายเชนของซอฟต์แวร์ที่พร้อมให้ใช้งานแล้วในตอนนี้ที่คุณสามารถใช้ Cloud Build ในการติดตั้งใช้งานได้

ไม่บังคับ: ล้างข้อมูลและ/หรือปิดใช้บริการ

หากทำให้แอปตัวอย่างใช้งานได้ใน App Engine ระหว่างบทแนะนำนี้ อย่าลืมปิดใช้แอปเพื่อหลีกเลี่ยงการเรียกเก็บเงิน เมื่อพร้อมที่จะไปที่ Codelab ถัดไปแล้ว คุณก็เปิดใช้ฟีเจอร์นี้อีกครั้งได้ ในขณะที่ปิดใช้แอป App Engine แอปจะไม่ได้รับการเข้าชมใดๆ ที่จะทำให้เกิดค่าใช้จ่าย แต่ระบบอาจเรียกเก็บเงินสำหรับการใช้งาน Datastore หากเกินโควต้าฟรี ดังนั้นให้ลบข้อมูลให้เพียงพอเพื่อไม่ให้เกินขีดจำกัดดังกล่าว

ในทางกลับกัน หากคุณไม่ต้องการดำเนินการย้ายข้อมูลต่อและต้องการลบทุกอย่างออกทั้งหมด คุณสามารถลบบริการหรือปิดโปรเจ็กต์ทั้งหมด

7. แหล่งข้อมูลเพิ่มเติม

ปัญหา/ความคิดเห็นเกี่ยวกับ Codelab โมดูลการย้ายข้อมูล App Engine

หากพบปัญหาเกี่ยวกับ Codelab นี้ โปรดค้นหาปัญหาของคุณก่อนที่จะยื่นเรื่อง ลิงก์สำหรับค้นหาและสร้างปัญหาใหม่

แหล่งข้อมูลการย้ายข้อมูล

แหล่งข้อมูลออนไลน์

ด้านล่างนี้คือแหล่งข้อมูลออนไลน์ที่อาจเกี่ยวข้องกับบทแนะนำนี้

App Engine

ข้อมูลอื่นๆ เกี่ยวกับระบบคลาวด์

วิดีโอ

ใบอนุญาต

ผลงานนี้ได้รับอนุญาตภายใต้สัญญาอนุญาตครีเอทีฟคอมมอนส์สำหรับยอมรับสิทธิของผู้สร้าง (Creative Commons Attribution License) 2.0 แบบทั่วไป