การย้ายข้อมูลจากแอป Java ของ Google App Engine ไปยัง Cloud Run ด้วย Docker
เกี่ยวกับ Codelab นี้
1 ภาพรวม
ชุดโค้ดแล็บ (บทแนะนำแบบฝึกหัดด้วยตนเอง) นี้มีจุดประสงค์เพื่อช่วยให้นักพัฒนาซอฟต์แวร์ Java ของ Google App Engine (มาตรฐาน) ปรับแอปให้ทันสมัยโดยแนะนำขั้นตอนการย้ายข้อมูล เมื่อทำตามขั้นตอนเหล่านี้ คุณจะอัปเดตแอปให้พกพาได้มากขึ้นและตัดสินใจที่จะใช้คอนเทนเนอร์สำหรับ Cloud Run ซึ่งเป็นบริการโฮสติ้งคอนเทนเนอร์ของ Google Cloud ที่ทำงานร่วมกับ App Engine และบริการโฮสติ้งคอนเทนเนอร์อื่นๆ ได้
บทแนะนำนี้จะสอนวิธีทำให้แอป App Engine เป็นคอนเทนเนอร์เพื่อทำให้ใช้งานได้กับบริการ Cloud Run ที่มีการจัดการโดยสมบูรณ์ด้วย Dockerfile Dockerfile เป็นวิธีการทำให้ใช้งานได้จริงมากที่สุดสำหรับการย้ายข้อมูลนี้ แต่ก็ยังมีตัวเลือกมากที่สุดในการปรับแต่งกระบวนการสร้างด้วย
นอกจากสอนขั้นตอนที่จำเป็นในการย้ายจาก App Engine ไปยัง Cloud Run แล้ว คุณยังจะได้เรียนรู้วิธีอัปเกรดแอป Java 8 ใน App Engine เป็น Java 17 ด้วย
หากแอปพลิเคชันที่คุณสนใจย้ายข้อมูลใช้บริการแบบกลุ่มเดิมของ App Engine หรือฟีเจอร์อื่นๆ ที่เจาะจงของ App Engine เป็นหลัก คู่มือการเข้าถึงบริการแบบกลุ่มของ App Engine สำหรับ Java 11/17 อาจเป็นจุดเริ่มต้นที่ดีกว่าโค้ดแล็บนี้
คุณจะได้เรียนรู้วิธีต่อไปนี้
- ใช้ Cloud Shell
- เปิดใช้ Cloud Run, Artifact Registry และ Cloud Build API
- สร้างคอนเทนเนอร์ให้กับแอปโดยใช้ Docker, Docker และ Cloud Build
- ทำให้อิมเมจคอนเทนเนอร์ใช้งานได้กับ Cloud Run
สิ่งที่ต้องมี
- โปรเจ็กต์ Google Cloud Platform ที่มีบัญชีสำหรับการเรียกเก็บเงิน GCP ที่ใช้งานอยู่และเปิดใช้ App Engine
- ความรู้เกี่ยวกับคำสั่งทั่วไปของ Linux
- ความรู้พื้นฐานเกี่ยวกับการพัฒนาและการทำให้แอป App Engine ใช้งานได้
- แอป Servlet ของ Java 8 ที่ต้องการย้ายข้อมูลไปยัง Java 17 และทำให้ใช้งานได้ใน Cloud Run (อาจเป็นแอปใน App Engine หรือแค่ซอร์สโค้ด)
แบบสำรวจ
คุณจะใช้บทแนะนำนี้อย่างไร
คุณจะให้คะแนนประสบการณ์การใช้งาน Java เท่าไร
คุณจะให้คะแนนประสบการณ์การใช้งานบริการ Google Cloud เท่าใด
2 ข้อมูลเบื้องต้น
ระบบ PaaS เช่น App Engine และ Cloud Functions มอบความสะดวกมากมายให้กับทีมและแอปพลิเคชันของคุณ เช่น ช่วยให้ผู้ดูแลระบบและนักพัฒนาซอฟต์แวร์สามารถมุ่งเน้นที่การสร้างโซลูชันได้ เมื่อใช้แพลตฟอร์มแบบเซิร์ฟเวอร์เสมือน แอปจะปรับขนาดอัตโนมัติได้ตามต้องการ ปรับขนาดลงเป็น 0 ด้วยการเรียกเก็บเงินแบบจ่ายต่อการใช้งานเพื่อช่วยควบคุมค่าใช้จ่าย และใช้ภาษาการพัฒนาทั่วไปที่หลากหลาย
อย่างไรก็ตาม ความยืดหยุ่นของคอนเทนเนอร์ก็น่าสนใจเช่นกัน คอนเทนเนอร์มีความสามารถในการเลือกภาษา ไลบรารี และไบนารีใดก็ได้ คุณจึงได้รับประโยชน์สูงสุดจากทั้ง 2 ด้าน ซึ่งก็คือความสะดวกสบายในการใช้งานแบบ Serverless และความยืดหยุ่นของคอนเทนเนอร์ Google Cloud Run สร้างขึ้นเพื่อจุดประสงค์นี้
การเรียนรู้วิธีใช้ Cloud Run ไม่ได้อยู่ในขอบเขตของโค้ดแล็บนี้ โปรดดูข้อมูลในเอกสารประกอบของ Cloud Run เป้าหมายนี้มีไว้เพื่อให้คุณทำความคุ้นเคยกับวิธีสร้างคอนเทนเนอร์แอป App Engine สำหรับ Cloud Run (หรือบริการอื่นๆ ที่โฮสต์บนคอนเทนเนอร์) โปรดทราบว่าคุณควรทราบข้อมูลบางอย่างก่อนดำเนินการต่อ โดยเฉพาะอย่างยิ่งประสบการณ์ของผู้ใช้จะแตกต่างกันเล็กน้อย
ในโค้ดแล็บนี้ คุณจะได้เรียนรู้วิธีสร้างและทำให้คอนเทนเนอร์ใช้งานได้ คุณจะได้เรียนรู้วิธีบรรจุคอนเทนเนอร์แอปด้วย 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
- ติดตั้ง/ทบทวนการใช้
gcloud
CLI - เริ่มต้น gcloud CLI สําหรับโปรเจ็กต์ด้วย
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, การกําหนดค่า หรือฟีเจอร์อื่นๆ ของ 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 มีความแตกต่างหลายประการที่ควรพิจารณาเมื่อย้ายข้อมูลระหว่างแพลตฟอร์ม ความแตกต่างอย่างหนึ่งคือ ในขณะที่รันไทม์ 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 จะใช้เซิร์ฟเลตซ้ำได้โดยไม่ต้องแก้ไข แต่จะต้องกำหนดค่าบางอย่างเพื่อให้ระบบค้นพบเซิร์ฟเลตได้
สร้างคลาส 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
ดังที่กล่าวในตอนต้นของ 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 Build เกี่ยวกับวิธีสร้างคอนเทนเนอร์ของแอปพลิเคชันแล้ว เมื่อใช้เมธอดการขนส่งด้วยคอนเทนเนอร์นี้ จึงไม่จำเป็นต้องใช้ไฟล์การกำหนดค่าบิลด์แยกต่างหาก (cloudbuild.yaml) เราเพียงกำหนด Dockerfile ขั้นต่ำเป็นจุดเริ่มต้น
FROM eclipse-temurin
ARG JAR_FILE=JAR_FILE_MUST_BE_SPECIFIED_AS_BUILD_ARG
คัดลอก ${JAR_FILE} app.jar
ENTRYPOINT ["java", "-jar","/app.jar"]
Dockerfile นี้จะรวมบริการ Spring Boot เวอร์ชัน Uber Jar ไว้ในเลเยอร์เดียว วิธีนี้เป็นวิธีที่ง่ายที่สุดในการสร้างคอนเทนเนอร์ Dockerfile แต่ก็มาพร้อมกับข้อเสียหลายประการ โดยเฉพาะเมื่อเปรียบเทียบเวลาที่เกิดขึ้นซ้ำๆ ซึ่งทรัพยากร Dependency ค่อนข้างเสถียร ข้อกังวลเช่นนี้เป็นเหตุผลที่วิธีการบรรจุคอนเทนเนอร์นี้ถือว่าล้ำสมัยกว่า อย่างไรก็ตาม ข้อดีของการเขียนไฟล์ Docker ของคุณเองคือคุณจะควบคุมอิมเมจฐานได้อย่างสมบูรณ์และเข้าถึงประโยชน์ด้านประสิทธิภาพของการเขียนอิมเมจแบบเลเยอร์อย่างละเอียด
2**. เรียกใช้กระบวนการบิลด์**
เมื่อแจ้งขั้นตอนการสร้างที่ต้องการให้ Cloud Build แล้ว คุณก็พร้อมสำหรับการทำให้ใช้งานได้ในคลิกเดียว
เรียกใช้คำสั่งต่อไปนี้
gcloud builds submit --tag LOCATION-docker.pkg.dev/PROJECT_ID/REPOSITORY/IMAGE_NAME
แทนที่ค่าตัวยึดตําแหน่งในคําสั่งด้านบนด้วยค่าต่อไปนี้
- ตำแหน่ง: ตำแหน่งระดับภูมิภาคหรือหลายภูมิภาคสำหรับที่เก็บข้อมูล
- PROJECT_ID: รหัสโปรเจ็กต์ที่อยู่ในระบบคลาวด์
- REPOSITORY: ชื่อที่เก็บ Artifact Registry
- IMAGE_NAME: ชื่ออิมเมจคอนเทนเนอร์
เมื่อกระบวนการเสร็จสิ้นแล้ว ระบบจะสร้างอิมเมจคอนเทนเนอร์ จัดเก็บไว้ใน Artifact Registry และทำให้ใช้งานได้ใน Cloud Run
เมื่อสิ้นสุดโค้ดแล็บนี้ แอปของคุณควรมีลักษณะเหมือนกับแอปในโฟลเดอร์ mod4-migrate-to-cloud-run
เพียงเท่านี้ก็เรียบร้อยแล้ว คุณย้ายข้อมูลแอป Java 8 App Engine ไปยัง Java 17 และ Cloud Run สำเร็จแล้ว และตอนนี้มีความเข้าใจที่ชัดเจนยิ่งขึ้นเกี่ยวกับงานที่เกี่ยวข้องเมื่อสลับและเลือกตัวเลือกโฮสติ้ง
6 สรุป/ล้างข้อมูล
ขอแสดงความยินดี คุณได้อัปเกรด สร้างคอนเทนเนอร์ ย้ายข้อมูล และย้ายข้อมูลแอปแล้ว ซึ่งได้จบบทแนะนำนี้
จากขั้นตอนนี้ ขั้นตอนถัดไปคือดูข้อมูลเพิ่มเติมเกี่ยวกับฟีเจอร์ความปลอดภัยของ CI/CD และซัพพลายเชนซอฟต์แวร์ที่คุณใช้งานได้แล้วตอนนี้เมื่อใช้ Cloud Build
- การสร้างขั้นตอนการบิลด์ที่กำหนดเองด้วย Cloud Build
- การสร้างและจัดการทริกเกอร์บิลด์
- การใช้การสแกนแบบออนดีมานด์ในไปป์ไลน์ Cloud Build
ไม่บังคับ: ล้างข้อมูลและ/หรือปิดใช้บริการ
หากคุณทำให้แอปตัวอย่างใช้งานได้ใน App Engine ระหว่างบทแนะนำนี้ อย่าลืมปิดใช้แอปเพื่อหลีกเลี่ยงการเรียกเก็บเงิน เมื่อพร้อมที่จะไปยังโค้ดแล็บถัดไป คุณจะเปิดใช้โค้ดแล็บอีกครั้งได้ เมื่อปิดใช้แอป App Engine ระบบจะไม่เรียกเก็บเงินสำหรับการเข้าชมแอปดังกล่าว แต่อาจเรียกเก็บเงินสำหรับการใช้งาน Datastore หากเกินโควต้าแบบไม่มีค่าใช้จ่าย ดังนั้นให้ลบข้อมูลให้เหลือไม่เกินขีดจำกัดดังกล่าว
ในทางกลับกัน หากไม่ต้องการย้ายข้อมูลต่อและต้องการลบทุกอย่างออกอย่างสมบูรณ์ คุณสามารถลบบริการหรือปิดโปรเจ็กต์โดยสมบูรณ์
7 แหล่งข้อมูลเพิ่มเติม
ปัญหา/ความคิดเห็นของโมดูลการย้ายข้อมูล App Engine
หากพบปัญหาเกี่ยวกับโค้ดแล็บนี้ โปรดค้นหาปัญหาก่อนยื่นเรื่อง ลิงก์สำหรับค้นหาและสร้างปัญหาใหม่
แหล่งข้อมูลการย้ายข้อมูล
- ตัวเลือกการย้ายข้อมูลสำหรับการแยกบริการ App Engine
- การตั้งค่าทริกเกอร์บิลด์สําหรับ Cloud Build
- ข้อมูลเพิ่มเติมเกี่ยวกับการย้ายข้อมูลไปยัง Java 11/17
แหล่งข้อมูลออนไลน์
ด้านล่างนี้คือแหล่งข้อมูลออนไลน์ที่อาจเกี่ยวข้องกับบทแนะนำนี้
App Engine
- เอกสารประกอบของ App Engine
- ข้อมูลราคาและโควต้าของ App Engine
- การเปรียบเทียบแพลตฟอร์มรุ่นที่ 1 กับรุ่นที่ 2
- การรองรับรันไทม์เดิมในระยะยาว
ข้อมูลอื่นๆ ในระบบคลาวด์
วิดีโอ
- สถานีย้ายข้อมูลแบบ Serverless
- Expeditions แบบ Serverless
- สมัครใช้บริการ Google Cloud Tech
- สมัครรับข้อมูลใน Google Developers
ใบอนุญาต
ผลงานนี้ได้รับอนุญาตภายใต้สัญญาอนุญาตครีเอทีฟคอมมอนส์สำหรับยอมรับสิทธิของผู้สร้าง (Creative Commons Attribution License) 2.0 ทั่วไป