Миграция Java-приложения Google App Engine в Cloud Run с Jib

1. Обзор

Эта серия практических руководств (в удобном для вас темпе) призвана помочь разработчикам Google App Engine (Standard) на Java модернизировать свои приложения, проведя их через ряд миграций. Следуя этим шагам, вы сможете сделать свое приложение более портативным и принять решение о его контейнеризации для Cloud Run , сервиса Google Cloud для размещения контейнеров, аналогичного App Engine, и других сервисов для размещения контейнеров.

В этом руководстве вы узнаете, как контейнеризировать приложение App Engine для развертывания в полностью управляемом сервисе Cloud Run с помощью Jib . С помощью Jib вы можете создавать образы Docker — хорошо известной в отрасли платформы для разработки, распространения и запуска приложений в контейнерах.

Помимо обучения необходимым шагам для перехода с App Engine на Cloud Run, вы также узнаете, как обновить приложение App Engine на Java 8 до Java 17.

Если ваше приложение активно использует устаревшие встроенные сервисы App Engine или другие функции App Engine, мы рекомендуем отказаться от этих встроенных сервисов или заменить эти функции перед переходом на Cloud Run. Если вам нужно больше времени для изучения вариантов миграции или вы хотите пока продолжать использовать устаревшие встроенные сервисы, вы можете продолжать использовать встроенные сервисы App Engine для Java 11/17 при обновлении до более новой среды выполнения. Когда ваше приложение станет более портативным, вернитесь к этому руководству, чтобы узнать, как применить инструкции к вашему приложению.

Вы узнаете, как

  • Используйте Cloud Shell
  • Включите API Cloud Run, Artifact Registry и Cloud Build.
  • Создайте контейнер для своего приложения с помощью Jib и Cloud Build.
  • Развертывайте образы контейнеров в Cloud Run.

Что вам понадобится

Опрос

Как вы будете использовать этот учебный материал?

Прочитайте только от начала до конца. Прочитайте текст и выполните упражнения.

Как бы вы оценили свой опыт работы с Java?

Новичок Средний Профессионал

Как бы вы оценили свой опыт использования сервисов Google Cloud?

Новичок Средний Профессионал

2. Предыстория

Платформы как услуга (PaaS), такие как App Engine и Cloud Functions, предоставляют множество удобств для вашей команды и приложения, например, позволяют системным администраторам и специалистам DevOps сосредоточиться на разработке решений. Благодаря бессерверным платформам ваше приложение может автоматически масштабироваться по мере необходимости, масштабироваться до нуля с оплатой по факту использования для контроля затрат, а также использовать различные распространенные языки программирования.

Однако гибкость контейнеров также является привлекательным преимуществом. Благодаря возможности выбора любого языка, любой библиотеки и любого исполняемого файла, контейнеры предоставляют вам лучшее из двух миров: удобство бессерверных вычислений в сочетании с гибкостью контейнеров. Именно в этом и заключается суть Cloud Run .

Изучение использования Cloud Run не входит в рамки этого практического занятия; это рассматривается в документации Cloud Run . Цель здесь — познакомить вас с тем, как контейнеризировать ваше приложение App Engine для Cloud Run (или других сервисов, использующих контейнеры). Прежде чем двигаться дальше, следует учесть несколько моментов, прежде всего, что пользовательский опыт будет немного отличаться.

В этом практическом занятии вы научитесь создавать и развертывать контейнеры. Вы узнаете, как:

  • Создайте контейнер для своего приложения с помощью Jib.
  • Откажитесь от конфигурации 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 .

В качестве примера представлено Java 8-приложение на основе сервлетов для работы с хранилищем данных, предназначенное для развертывания в App Engine. Следуйте инструкциям в файле README, чтобы подготовить это приложение к развертыванию в App Engine.

3. (Необязательно) Разверните базовое приложение

Следующая информация необходима только в том случае, если вы хотите убедиться в работоспособности приложения в App Engine перед переходом на Cloud Run.

Следуйте инструкциям в файле README.md:

  1. Установите/ознакомьтесь с интерфейсом командной строки gcloud
  2. Инициализируйте интерфейс командной строки gcloud для вашего проекта с помощью gcloud init
  3. Создайте проект App Engine с помощью gcloud app create
  4. Разверните демонстрационное приложение в App Engine.
./mvnw package appengine:deploy -Dapp.projectId=$PROJECT_ID
  1. Убедитесь, что приложение работает в App Engine без проблем.

4. Создайте репозиторий реестра артефактов.

После контейнеризации вашего приложения вам понадобится место для загрузки и хранения изображений. Рекомендуемый способ сделать это в 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, мы рекомендуем продолжать использовать эти сервисы при обновлении до новой среды выполнения. В этом практическом примере демонстрируется путь миграции для приложений, которые уже используют автономные сервисы или могут быть переработаны для их использования.

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 позволит повторно использовать ваши сервлеты без изменений, для обеспечения их доступности потребуется некоторая настройка.

Создайте следующий класс 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.

Как упоминалось в начале практического занятия, 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 в фоновом режиме для обеспечения автоматизированного развертывания. Более подробно о развертывании из исходного кода мы поговорим в последующих модулях.

В качестве альтернативы, если вам нужен больший контроль над способом развертывания вашего приложения, вы можете добиться этого, определив файл cloudbuild.yaml , в котором явно указаны предполагаемые этапы сборки:

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 указание выполнить эти шаги, он сделает следующее:

  1. Запускайте тесты с помощью ./mvnw test
  2. Создавайте, загружайте и помечайте свой образ в реестре артефактов с помощью Jib.
  3. Разверните образ в Cloud Run с помощью gcloud run deploy

Обратите внимание, что в качестве желаемого имени сервиса для Cloud Run используется 'visitors' . Флаг –allow-unauthenticated позволяет пользователям посещать веб-приложение без аутентификации. Убедитесь, что вы заменили PROJECT_ID на идентификатор вашего проекта в файле cloudbuild.yaml .

Далее добавьте следующие привязки политики IAM, чтобы разрешить учетной записи службы Cloud Build доступ к реестру артефактов:

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. Запустите процесс сборки.

Теперь, когда вы указали Cloud Build необходимые этапы сборки, вы готовы к развертыванию в один клик.

Выполните следующую команду:

gcloud builds submit

После завершения процесса образ вашего контейнера будет создан, сохранен в реестре артефактов и развернут в Cloud Run.

По завершении этого практического занятия ваше приложение должно выглядеть так же, как и приложение в задании java17-and-cloud-run/finish .

Вот и все! Вы успешно перенесли приложение Java 8 App Engine на Java 17 и Cloud Run, и теперь у вас есть более четкое представление о работе, связанной с переходом и выбором между вариантами хостинга .

6. Подведение итогов/Завершение

Поздравляем, вы успешно обновили, контейнеризировали, перенесли и мигрировали ваше приложение, на этом данный урок завершается!

Следующий шаг — узнать больше о функциях CI/CD и безопасности цепочки поставок программного обеспечения, которые теперь доступны благодаря развертыванию с помощью Cloud Build:

Дополнительно: Очистка и/или отключение сервиса.

Если вы развернули демонстрационное приложение в App Engine во время этого урока, не забудьте отключить его , чтобы избежать дополнительных расходов. Когда вы будете готовы перейти к следующему практическому занятию, вы можете снова включить его. Пока приложения App Engine отключены, они не будут получать трафик, за который взимается плата, однако использование Datastore может быть платным, если оно превысит бесплатную квоту , поэтому удалите достаточное количество данных, чтобы оно не превышало этот лимит.

С другой стороны, если вы не собираетесь продолжать миграции и хотите полностью удалить все, вы можете либо удалить свой сервис , либо полностью закрыть свой проект .

7. Дополнительные ресурсы

Проблемы/обратная связь по модулю миграции App Engine на Codelabs

Если вы обнаружите какие-либо проблемы в этом практическом задании, пожалуйста, сначала найдите свою проблему, прежде чем сообщать о ней. Ссылки для поиска и создания новых проблем:

Миграционные ресурсы

Онлайн-ресурсы

Ниже приведены онлайн-ресурсы, которые могут быть полезны для данного урока:

App Engine

Прочая информация об облачных сервисах

Видео

Лицензия

Данная работа распространяется под лицензией Creative Commons Attribution 2.0 Generic.