Развертывание Java-приложения Spring Boot в Kubernetes в Google Kubernetes Engine

1. Прежде чем начать

Kubernetes — это проект с открытым исходным кодом, который может работать в самых разных средах: от ноутбуков до многоузловых кластеров высокой доступности, от общедоступных облаков до локальных развертываний, от экземпляров виртуальных машин (ВМ) до «голого железа».

В этой лаборатории кода вы развернете простое Java-приложение Spring Boot в Kubernetes на GKE с целью запустить свое веб-приложение в качестве реплицированного приложения в Kubernetes. Вы возьмете код, который разработали на своем компьютере, превратите его в образ контейнера Docker и запустите этот образ в GKE.

Вы будете использовать GKE, полностью управляемый сервис Kubernetes в Google Cloud, который позволит вам больше сосредоточиться на работе с Kubernetes, а не на настройке базовой инфраструктуры.

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

В лаборатории кода будет использоваться пример кода из руководства по созданию приложения с помощью Spring Boot .

Предварительные условия

  • Знание языка программирования и инструментов Java.
  • Знание стандартных текстовых редакторов Linux, таких как Vim, Emacs и nano.

Что ты будешь делать

  • Упакуйте простое Java-приложение в контейнер Docker.
  • Создайте свой кластер Kubernetes на GKE.
  • Разверните свое Java-приложение в Kubernetes на GKE.
  • Масштабируйте свой сервис и выполните обновление.
  • Access Dashboard — веб-интерфейс пользователя Kubernetes.

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

  • Проект Google Cloud
  • Браузер, например Google Chrome

2. Настройка и требования

Самостоятельная настройка среды

  1. Войдите в Google Cloud Console и создайте новый проект или повторно используйте существующий. Если у вас еще нет учетной записи Gmail или Google Workspace, вам необходимо ее создать .

b35bf95b8bf3d5d8.png

a99b7ace416376c4.png

bd84a6d3004737c5.png

  • Имя проекта — это отображаемое имя для участников этого проекта. Это строка символов, не используемая API Google. Вы всегда можете обновить его.
  • Идентификатор проекта уникален для всех проектов Google Cloud и является неизменяемым (невозможно изменить после его установки). Cloud Console автоматически генерирует уникальную строку; обычно тебя не волнует, что это такое. В большинстве лабораторий кода вам потребуется указать идентификатор проекта (обычно идентифицируемый как PROJECT_ID ). Если вам не нравится сгенерированный идентификатор, вы можете создать другой случайный идентификатор. Кроме того, вы можете попробовать свой собственный и посмотреть, доступен ли он. Его нельзя изменить после этого шага и он сохраняется на протяжении всего проекта.
  • К вашему сведению, есть третье значение — номер проекта , который используют некоторые API. Подробнее обо всех трех этих значениях читайте в документации .
  1. Затем вам необходимо включить выставление счетов в Cloud Console, чтобы использовать облачные ресурсы/API. Прохождение этой кодовой лаборатории не будет стоить много, если вообще что-то стоить. Чтобы отключить ресурсы и избежать выставления счетов за пределами этого руководства, вы можете удалить созданные вами ресурсы или удалить проект. Новые пользователи Google Cloud имеют право на участие в программе бесплатной пробной версии стоимостью 300 долларов США .

Активировать Cloud Shell

  1. В Cloud Console нажмите «Активировать Cloud Shell». 853e55310c205094.png .

55efc1aaa7a4d3ad.png

Если вы запускаете Cloud Shell впервые, вы увидите промежуточный экран с описанием того, что это такое. Если вам был представлен промежуточный экран, нажмите «Продолжить» .

9c92662c6a846a5c.png

Подготовка и подключение к Cloud Shell займет всего несколько минут.

9f0e51b578fecce5.png

Эта виртуальная машина загружена всеми необходимыми инструментами разработки. Он предлагает постоянный домашний каталог объемом 5 ГБ и работает в Google Cloud, что значительно повышает производительность сети и аутентификацию. Большую часть, если не всю, работу в этой лаборатории кода можно выполнить с помощью браузера.

После подключения к Cloud Shell вы увидите, что вы прошли аутентификацию и что для проекта установлен идентификатор вашего проекта.

  1. Выполните следующую команду в Cloud Shell, чтобы подтвердить, что вы прошли аутентификацию:
gcloud auth list

Вывод команды

 Credentialed Accounts
ACTIVE  ACCOUNT
*       <my_account>@<my_domain.com>

To set the active account, run:
    $ gcloud config set account `ACCOUNT`
  1. Выполните следующую команду в Cloud Shell, чтобы убедиться, что команда gcloud знает о вашем проекте:
gcloud config list project

Вывод команды

[core]
project = <PROJECT_ID>

Если это не так, вы можете установить это с помощью этой команды:

gcloud config set project <PROJECT_ID>

Вывод команды

Updated property [core/project].

3. Получите исходный код

После запуска Cloud Shell вы можете использовать командную строку для клонирования исходного кода примера в домашний каталог.

$ git clone https://github.com/spring-guides/gs-spring-boot.git
$ cd gs-spring-boot/complete

4. Запустите приложение локально.

  1. Убедитесь, что для JAVA_HOME установлена ​​правильная версия:
$ export JAVA_HOME=/usr/lib/jvm/java-1.17.0-openjdk-amd64
  1. Вы можете запустить приложение Spring Boot в обычном режиме с помощью плагина Spring Boot.
$ ./mvnw -DskipTests spring-boot:run
  1. После запуска приложения нажмите « Предварительный просмотр в Интернете». 1a94d5bd10bfc072.png на панели инструментов Cloud Shell и выберите «Предварительный просмотр на порту 8080» .

6252b94905f3f7bd.png

В вашем браузере откроется вкладка и произойдет подключение к только что запущенному серверу.

9b6c29059957bd0.jpeg

5. Упакуйте приложение Java как контейнер Docker.

Далее вам необходимо подготовить приложение для работы в Kubernetes. Первым шагом является определение контейнера и его содержимого.

  1. Создайте развертываемый JAR-файл для приложения.
$ ./mvnw -DskipTests package
  1. Включите API реестра артефактов для хранения образа контейнера, который вы создадите.
$ gcloud services enable artifactregistry.googleapis.com
  1. Создайте новый репозиторий Docker, если он не существует. Прежде чем отправлять в него любые изображения, необходимо создать репозиторий:
$ gcloud artifacts repositories create codelabrepo     --repository-format=docker --location=us-central1 
  1. Ваше изображение будет иметь формат:

{LOCATION}-docker.pkg.dev/{PROJECT-ID}/{REPOSITORY}/{IMAGE-NAME}

Например, если вы создали репозиторий в расположении us-central1 с именем codelabrepo и хотите назвать свой образ hello-java:v1 , образ будет таким:

us-central1-docker.pkg.dev/{PROJECT-ID}/codelabrepo/hello-java:v1

  1. Используйте Jib, чтобы создать образ контейнера и отправить его в реестр артефактов.
$ export GOOGLE_CLOUD_PROJECT=`gcloud config list --format="value(core.project)"`

$ ./mvnw -DskipTests com.google.cloud.tools:jib-maven-plugin:build -Dimage=us-central1-docker.pkg.dev/${GOOGLE_CLOUD_PROJECT}/codelabrepo/hello-java:v1
  1. Вы сможете увидеть образ контейнера, указанный в консоли, перейдя на страницу «Образы реестра артефактов» в Cloud Console. Теперь у вас есть образ Docker для всего проекта, к которому Kubernetes может получить доступ и управлять им, как вы увидите через несколько минут.
  2. (Необязательно) После завершения (загрузка и извлечение всего займет некоторое время) протестируйте образ с помощью следующей команды, которая запустит контейнер Docker в качестве демона на порту 8080 из вашего вновь созданного образа контейнера. Если у вас возникли проблемы с разрешениями, сначала запустите gcloud auth configure-docker us-central1-docker.pkg.dev :
$ docker run -ti --rm -p 8080:8080 \
  us-central1-docker.pkg.dev/$GOOGLE_CLOUD_PROJECT/codelabrepo/hello-java:v1
  1. Опять же, воспользуйтесь функцией веб-предварительного просмотра Cloud Shell.

6252b94905f3f7bd.png

  1. Вы должны увидеть страницу по умолчанию на новой вкладке. Убедившись, что приложение работает локально в контейнере Docker, вы можете остановить работающий контейнер, нажав Control+C .

6. Создайте свой кластер

Вы готовы создать кластер GKE. Кластер состоит из API-сервера Kubernetes, управляемого Google, и набора рабочих узлов. Рабочие узлы — это виртуальные машины Compute Engine.

  1. Сначала убедитесь, что соответствующие функции API включены.
$ gcloud services enable compute.googleapis.com container.googleapis.com
  1. Создайте кластер с двумя узлами n1-standard-1 (это займет несколько минут).
$ gcloud container clusters create hello-java-cluster \
  --num-nodes 2 \
  --machine-type n1-standard-1 \
  --zone us-central1-c

В конце вы должны увидеть созданный кластер.

Creating cluster hello-java-cluster...done.
Created [https://container.googleapis.com/v1/projects/...].
kubeconfig entry generated for hello-dotnet-cluster.
NAME                  ZONE            MASTER_VERSION  
hello-java-cluster  us-central1-c  ...

Теперь у вас должен быть полностью функционирующий кластер Kubernetes на базе GKE.

758c7fca14f70623.png

Пришло время развернуть ваше контейнерное приложение в кластере Kubernetes! С этого момента вы будете использовать командную строку kubectl (уже настроенную в вашей среде Cloud Shell). Для остальной части лаборатории кода требуется, чтобы версия клиента и сервера Kubernetes была 1.2 или выше. kubectl version покажет вам текущую версию команды.

7. Разверните свое приложение в Kubernetes.

  1. Развертывание Kubernetes позволяет создавать, управлять и масштабировать несколько экземпляров вашего приложения, используя созданный вами образ контейнера. Разверните один экземпляр вашего приложения в Kubernetes с помощью команды kubectl run .
$ kubectl create deployment hello-java --image=us-central1-docker.pkg.dev/$GOOGLE_CLOUD_PROJECT/codelabrepo/hello-java:v1
  1. Чтобы просмотреть созданное вами развертывание, просто выполните следующую команду:
$ kubectl get deployments

NAME         DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
hello-java   1         1         1            1           37s
  1. Чтобы просмотреть экземпляры приложения, созданные при развертывании, выполните следующую команду:
$ kubectl get pods

NAME                         READY     STATUS    RESTARTS   AGE
hello-java-714049816-ztzrb   1/1       Running   0          57s

На этом этапе ваш контейнер должен работать под контролем Kubernetes, но вам все равно придется сделать его доступным для внешнего мира.

8. Разрешить внешний трафик

По умолчанию модуль доступен только по внутреннему IP-адресу внутри кластера. Чтобы сделать контейнер hello-java доступным из-за пределов виртуальной сети Kubernetes, вам необходимо представить под как службу Kubernetes.

  1. В Cloud Shell вы можете предоставить Pod общедоступному Интернету, создав службу Kubernetes LoadBalancer.
$ kubectl create service loadbalancer hello-java --tcp=8080:8080

Обратите внимание, что вы предоставляете доступ непосредственно к развертыванию, а не к поду. Это приведет к тому, что результирующая служба будет распределять нагрузку по трафику между всеми модулями, управляемыми развертыванием (в данном случае только одним модулем, но вы добавите дополнительные реплики позже).

Kubernetes Master создает балансировщик нагрузки и связанные с ним правила переадресации Compute Engine, целевые пулы и правила брандмауэра, чтобы сделать сервис полностью доступным из-за пределов Google Cloud.

  1. Чтобы найти общедоступный IP-адрес службы, просто запросите kubectl , чтобы получить список всех служб кластера.
$ kubectl get services

NAME         CLUSTER-IP     EXTERNAL-IP      PORT(S)    AGE
hello-java   10.3.253.62    aaa.bbb.ccc.ddd  8080/TCP    1m
kubernetes   10.3.240.1     <none>           443/TCP    5m
  1. Теперь вы сможете получить доступ к службе, указав в браузере http://<EXTERNAL_IP>:8080 .

9. Масштабируйте свой сервис

Одна из мощных функций, предлагаемых Kubernetes, — это простота масштабирования вашего приложения. Предположим, вам внезапно потребовалось больше возможностей для вашего приложения. Вы можете просто указать контроллеру репликации управлять новым количеством реплик для экземпляров вашего приложения.

$ kubectl scale deployment hello-java --replicas=3

deployment "hello-java" scaled

$ kubectl get deployment
NAME         DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
hello-java   3         3         3            3           22m

Обратите внимание на декларативный подход. Вместо запуска или остановки новых экземпляров вы указываете, сколько экземпляров должно работать постоянно. Циклы согласования Kubernetes просто проверяют, что реальность соответствует тому, что вы запросили, и при необходимости принимают меры.

10. Обновите свой сервис

В какой-то момент для приложения, которое вы развернули в рабочей среде, потребуются исправления ошибок или дополнительные функции. Kubernetes может помочь вам развернуть новую версию в рабочей среде, не затрагивая при этом ваших пользователей.

  1. Откройте редактор кода, нажав Открыть редактор. 2109d75686c889a.png в меню Cloud Shell.
  2. Перейдите к src/main/java/com/example/springboot/HelloController.java и обновите значение ответа.
package com.example.springboot;

import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.RequestMapping;

@RestController
public class HelloController {

    @RequestMapping("/")
    public String index() {
        return "Greetings from Google Kubernetes Engine!";
    }
}
  1. Используйте Jib для создания и отправки новой версии образа контейнера. Создание и публикация обновленного образа будет происходить намного быстрее, поскольку вы в полной мере воспользуетесь преимуществами кэширования.
$ ./mvnw -DskipTests package com.google.cloud.tools:jib-maven-plugin:build -Dimage=us-central1-docker.pkg.dev/$GOOGLE_CLOUD_PROJECT/codelabrepo/hello-java:v2

Вы готовы к тому, что Kubernetes плавно обновит ваш контроллер репликации до новой версии приложения!

  1. Чтобы изменить метку образа для работающего контейнера, вам необходимо отредактировать существующее развертывание hello-java и изменить образ с us-central1-docker.pkg.dev/PROJECT_ID/codelabrepo/hello-java:v1

us-central1-docker.pkg.dev/PROJECT_ID/codelabrepo/hello-java:v2 /codelabrepo/hello-java:v2

  1. Вы можете использовать команду kubectl set image , чтобы попросить Kubernetes развернуть новую версию вашего приложения по всему кластеру по одному экземпляру с последовательными обновлениями.
$ kubectl set image deployment/hello-java hello-java=us-central1-docker.pkg.dev/$GOOGLE_CLOUD_PROJECT/codelabrepo/hello-java:v2

deployment "hello-java" image updated
  1. Проверьте http://EXTERNAL_IP:8080 еще раз, чтобы убедиться, что он возвращает новый ответ.

11. Откат назад

Упс! Вы допустили ошибку с новой версией приложения? Возможно, новая версия содержала ошибку и вам необходимо быстро откатить ее. С помощью Kubernetes вы можете легко вернуть его в предыдущее состояние. Откатите приложение, выполнив следующую команду:

$ kubectl rollout undo deployment/hello-java

Вы должны увидеть старый ответ, когда снова проверите http://EXTERNAL_IP:8080 .

12. Поздравления

Вы научились создавать и развертывать новое веб-приложение на основе Java в Kubernetes на GKE.

Очистить

$ gcloud container clusters delete hello-java-cluster --zone us-central1-c

$ gcloud container images delete us-central1-docker.pkg.dev/$GOOGLE_CLOUD_PROJECT/codelabrepo/hello-java:v1 us-central1-docker.pkg.dev/$GOOGLE_CLOUD_PROJECT/codelabrepo/hello-java:v2

Узнать больше