빌드팩을 사용하여 Google App Engine 자바 앱에서 Cloud Run으로 마이그레이션

1. 개요

이 Codelab 시리즈 (사용자 주도형, 실무 가이드)는 Google App Engine (표준) Java 개발자가 일련의 마이그레이션을 통해 자신의 앱을 현대화할 수 있도록 돕기 위한 것입니다. 이 단계에 따라 앱을 더 쉽게 이동할 수 있도록 업데이트하고 Cloud Run, App Engine의 Google Cloud 컨테이너 호스팅 자매 서비스, 기타 컨테이너 호스팅 서비스에 앱을 컨테이너화할 수 있습니다.

이 튜토리얼에서는 빌드팩을 사용하여 Cloud Run 완전 관리형 서비스에 배포하기 위해 App Engine 앱을 컨테이너화하는 방법을 설명합니다. 빌드팩은 소스 코드에서 모든 클라우드에서 실행할 수 있는 이식성이 뛰어난 이미지로 앱을 직접 가져올 수 있는 CNCF 프로젝트입니다.

App Engine에서 Cloud Run으로 이전하는 데 필요한 단계를 안내하는 것 외에도 Java 8 App Engine 앱을 Java 17로 업그레이드하는 방법도 알아봅니다.

마이그레이션하려는 애플리케이션에서 App Engine 기존 번들 서비스나 기타 App Engine 관련 기능을 많이 사용하는 경우 자바 11/17용 App Engine 번들 서비스에 액세스 가이드가 이 Codelab보다 적합할 수 있습니다.

다음 실습에서는

  • Cloud Shell 사용
  • Cloud Run, Artifact Registry, Cloud Build API 사용 설정
  • Cloud Build에서 빌드팩을 사용하여 앱 컨테이너화
  • Cloud Run에 컨테이너 이미지 배포

필요한 항목

설문조사

이 튜토리얼을 어떻게 사용하실 계획인가요?

읽기만 할 계획입니다 읽은 다음 연습 활동을 완료할 계획입니다

Java 사용 경험을 평가해 주세요.

초급 중급 고급

귀하의 Google Cloud 서비스 사용 경험을 평가해 주세요.

초급 중급 고급

2. 배경

App Engine 및 Cloud Functions와 같은 PaaS 시스템은 SysAdmin과 Devops가 솔루션 빌드에 집중할 수 있도록 지원하는 등 팀과 애플리케이션에 많은 편의를 제공합니다. 서버리스 플랫폼을 사용하면 앱이 필요에 따라 자동 확장하고, 사용량 기반 결제를 통해 0으로 축소하여 비용을 관리하고, 다양한 일반적인 개발 언어를 사용할 수 있습니다.

하지만 컨테이너의 유연성도 매력적입니다. 컨테이너는 모든 언어, 라이브러리, 바이너리를 선택할 수 있으므로 서버리스의 편리함과 컨테이너의 유연성을 모두 누릴 수 있습니다. 이것이 바로 Google Cloud Run의 핵심입니다.

Cloud Run 사용 방법을 배우는 것은 Cloud Run 문서에서 다루는 이 Codelab의 범위에 포함되지 않습니다. 이 가이드의 목표는 Cloud Run (또는 기타 컨테이너 호스팅 서비스)용 App Engine 앱을 컨테이너화하는 방법을 익히는 것입니다. 진행하기 전에 알아두어야 할 몇 가지 사항이 있으며, 주로 사용자 환경이 약간 달라진다는 점을 염두에 두어야 합니다.

이 Codelab에서는 컨테이너를 빌드하고 배포하는 방법을 알아봅니다. 빌드팩으로 앱을 컨테이너화하고, App Engine 구성에서 이전하고, Cloud Build의 빌드 단계를 정의하는 방법을 알아봅니다. 이 과정에서 특정 App Engine 관련 기능이 지원 중단됩니다. 이 경로를 따르지 않으려는 경우에도 App Engine에서 앱을 유지하면서 자바 11/17 런타임으로 업그레이드할 수 있습니다.

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에서 샘플 앱을 클론한 후 기준점 폴더로 이동합니다.

이 샘플은 App Engine에 배포하기 위한 Java 8, 서블릿 기반 Datastore 앱입니다. App Engine 배포를 위해 이 앱을 준비하는 방법에 관한 README의 안내를 따릅니다.

3. (선택사항) 기준 앱 배포

다음은 Cloud Run으로 이전하기 전에 앱이 App Engine에서 작동하는지 확인하려는 경우에만 필요합니다.

README.md의 단계를 참고하세요.

  1. gcloud CLI 설치/재숙지
  2. gcloud init로 프로젝트의 gcloud CLI 초기화
  3. gcloud app create로 App Engine 프로젝트 만들기
  4. App Engine에 샘플 앱 배포
./mvnw package appengine:deploy -Dapp.projectId=$PROJECT_ID
  1. 앱이 문제 없이 App Engine에서 실행되는지 확인합니다.

4. Artifact Registry 저장소 만들기

앱을 컨테이너화한 후에는 이미지를 푸시하고 저장할 위치가 필요합니다. Google Cloud에서 이 작업을 수행하는 데 권장되는 방법은 Artifact Registry를 사용하는 것입니다.

다음과 같이 gcloud로 migration라는 저장소를 만듭니다.

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을 사용하는 경우 보안 업데이트를 계속 받고 새로운 언어 기능을 이용할 수 있도록 11 또는 17과 같은 이후 LTS 후보로 업그레이드하는 것이 좋습니다.

먼저 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 언어 기능에 액세스하고 컴파일된 클래스가 Java 17 JVM과 호환되기를 원한다고 알립니다.

2. 웹 서버 포함

App Engine과 Cloud Run 간에 이동할 때 고려해야 할 몇 가지 차이점이 있습니다. 한 가지 차이점은 App Engine의 Java 8 런타임은 호스팅하는 앱의 Jetty 서버를 제공하고 관리했지만 Cloud Run은 그렇지 않다는 점입니다. Spring Boot를 사용하여 웹 서버와 Servlet 컨테이너를 제공합니다.

다음 종속 항목을 추가합니다.

<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을 재사용할 수 있지만 검색 가능하도록 하려면 몇 가지 구성이 필요합니다.

com.example.appengine 패키지에 다음 MigratedServletApplication.java 클래스를 만듭니다.

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);
    }
}

여기에는 @WebServlets를 찾고 예상대로 사용할 수 있도록 하는 @ServletComponentScan 주석이 포함됩니다 (기본적으로 현재 패키지에서).

4. 빌드 구성

그런 다음 애플리케이션을 WAR로 패키징하는 구성을 삭제합니다. 특히 Maven을 빌드 도구로 사용하는 프로젝트의 경우 jar 패키징이 기본 동작이므로 별도의 구성이 필요하지 않습니다.

pom.xml 파일에서 packaging 태그를 삭제합니다.

<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태스크 큐 서비스)은 수동으로 다시 만들어야 하며, 이는 이후 모듈에서 자세히 다룹니다.

샘플 앱은 기존 번들 서비스를 사용하지 않지만 앱에서 기존 번들 서비스를 사용하는 사용자는 다음 가이드를 참고할 수 있습니다.

이제 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 .

배포 명령어를 실행하는 동안 다음과 같은 몇 가지 메시지가 표시됩니다.

  • 소스 코드 위치 제공
  • 서비스 이름 제공
  • Cloud Run API 사용 설정
  • 지역 선택

이러한 메시지에 응답하면 빌드 및 배포 프로세스가 시작되며, 이 과정에서 Cloud Build는 다음을 실행합니다.

  • Cloud Storage 버킷에 소스를 압축하여 저장
  • 백그라운드에서 Cloud Native Computing Foundation 빌드팩을 사용하여 이미지를 빌드합니다.
  • 결과 컨테이너 이미지를 저장할 레지스트리를 만듭니다 (아직 없는 경우).
  • 앱을 호스팅할 Cloud Run 서비스를 만듭니다 (아직 없는 경우).

빌드 및 배포가 완료되면 새 버전이 게시되고 트래픽을 100% 제공하고 있다는 메시지가 표시됩니다.

6. 요약/삭제

축하합니다. 앱을 업그레이드, 컨테이너화, 이전했습니다. 이로써 튜토리얼이 종료되었습니다.

이제 다음 단계로 Cloud Build로 배포할 수 있는 CI/CD 및 소프트웨어 공급망 보안 기능에 대해 자세히 알아보세요.

선택사항: 서비스 정리 또는 사용 중지

이 튜토리얼 중에 App Engine에 샘플 앱을 배포했다면 비용이 청구되지 않도록 을 사용 중지해야 합니다. 다음 Codelab으로 이동할 준비가 되었으면 이를 다시 사용 설정하면 됩니다. App Engine 앱이 사용 중지되면 비용이 발생하는 트래픽이 수행되지 않지만, 무료 할당량을 초과하는 경우 Datastore 사용량에 대한 요금이 청구될 수 있습니다. 따라서 제한에 걸리지 않도록 충분히 삭제해야 합니다.

반면에 마이그레이션을 계속하지 않고 모든 것을 완전히 삭제하려면 서비스를 삭제하거나 프로젝트를 완전히 종료합니다.

7. 추가 리소스

App Engine 마이그레이션 모듈 Codelab 문제/의견

이 Codelab에 문제가 발견된 경우 문제를 기록하기 전에 먼저 비슷한 기록이 있는지 검색해보세요. 검색 및 새 문제 만들기 링크:

이전 리소스

온라인 리소스

다음은 이 튜토리얼과 관련이 있는 온라인 리소스입니다.

App Engine

기타 클라우드 정보

동영상

라이선스

이 작업물은 Creative Commons Attribution 2.0 일반 라이선스에 따라 사용이 허가되었습니다.