1. Обзор
О Микронавт
Micronaut — это современная полнофункциональная платформа на базе JVM для создания модульных, легко тестируемых микросервисных и бессерверных приложений. Micronaut стремится обеспечить максимальное время запуска, высокую пропускную способность и минимальное использование памяти. Разработчики могут разрабатывать с помощью Micronaut на Java, Groovy или Kotlin.
Микронавт обеспечивает:
- Быстрое время запуска и низкое потребление памяти . Платформы IoC на основе отражения загружают и кэшируют данные отражения для каждого отдельного поля, метода и конструктора в вашем коде, тогда как с Micronaut время запуска вашего приложения и потребление памяти не привязаны к размеру вашего кода. кодовая база.
- Декларативный, реактивный HTTP-клиент времени компиляции . Декларативно создавайте реактивные HTTP-клиенты, которые реализуются во время компиляции, что снижает потребление памяти.
- Неблокирующий HTTP-сервер, построенный на Netty . Благодаря плавному обучению HTTP-сервер Micronaut максимально упрощает предоставление API-интерфейсов, которые могут использоваться HTTP-клиентами.
- Быстрое и простое тестирование . Легко запускайте серверы и клиенты в модульных тестах и запускайте их мгновенно.
- Эффективное внедрение зависимостей во время компиляции и АОП . Micronaut предоставляет простой API-интерфейс аспектно-ориентированного программирования во время компиляции, который не использует отражение.
- Создавайте полностью реактивные и неблокирующие приложения — Micronaut поддерживает любую платформу, реализующую Reactive Streams, включая RxJava и Reactor.
Для получения дополнительной информации посетите веб-сайт Micronaut .
О Кубернетесе
Kubernetes — это проект с открытым исходным кодом, который может работать в самых разных средах: от ноутбуков до многоузловых кластеров высокой доступности, от публичных облаков до локальных развертываний, от виртуальных машин до «голого железа».
В ходе этой лабораторной работы вы развернете простой микросервис Micronaut на базе Groovy в Kubernetes , работающий на Kubernetes Engine .
Цель этой лаборатории кода — запустить микросервис как реплицируемый сервис, работающий в Kubernetes. Вы берете код, разработанный на своем компьютере, превращаете его в образ контейнера Docker, а затем запускаете этот образ в Kubernetes Engine.
Ниже приведена диаграмма различных частей этой лаборатории кода, которая поможет вам понять, как части сочетаются друг с другом. Используйте это как справку по мере продвижения по кодовой лаборатории; к тому времени, как вы дойдете до конца, все это должно обрести смысл (но пока не стесняйтесь игнорировать это).
Для целей этой лаборатории использование управляемой среды, такой как Kubernetes Engine (размещенная в Google версия Kubernetes, работающая на Compute Engine), позволяет вам больше сосредоточиться на работе с Kubernetes, а не на настройке базовой инфраструктуры.
Если вы заинтересованы в запуске Kubernetes на своем локальном компьютере, например, на ноутбуке для разработки, вам, вероятно, следует присмотреться к Minikube . Это предлагает простую настройку кластера Kubernetes с одним узлом для целей разработки и тестирования. Если хотите, вы можете использовать Minikube для изучения этой лаборатории кода.
О Джибе
Jib — это инструмент с открытым исходным кодом, который позволяет создавать образы Docker и OCI для ваших приложений Java. Он доступен в виде плагинов для Maven и Gradle, а также в виде библиотеки Java.
Джиб стремится быть:
- Быстро — быстро развертывайте изменения. Jib разделяет ваше приложение на несколько уровней, отделяя зависимости от классов. Теперь вам не нужно ждать, пока Docker пересоберет все ваше Java-приложение — просто разверните измененные уровни.
- Воспроизводимость — при пересборке образа контейнера с тем же содержимым всегда создается один и тот же образ. Никогда больше не запускайте ненужное обновление.
- Daemonless — уменьшите зависимости CLI. Создайте свой образ Docker из Maven или Gradle и отправьте его в любой реестр по вашему выбору. Больше не нужно писать Dockerfiles и вызывать docker build/push.
Более подробную информацию о Jib вы можете найти на странице проекта Github.
Об этом уроке
В этом руководстве используется пример кода из инструмента Jib для создания контейнеров для приложений Java.
Пример представляет собой простой сервис hello world , использующий платформу Micronaut и язык программирования Apache Groovy .
Что вы узнаете
- Как упаковать простое Java-приложение в контейнер Docker с помощью Jib
- Как создать кластер Kubernetes на Kubernetes Engine.
- Как развернуть службу Micronaut в Kubernetes на Kubernetes Engine
- Как масштабировать свой сервис и выполнить обновление.
- Как получить доступ к графической панели управления Kubernetes.
Что вам понадобится
- Проект облачной платформы Google
- Браузер, например Chrome или Firefox.
- Знакомство со стандартными текстовыми редакторами Linux, такими как Vim, EMAC или Nano.
Как вы будете использовать этот урок?
Как бы вы оценили свой опыт создания веб-приложений HTML/CSS?
Как бы вы оценили свой опыт использования сервисов Google Cloud Platform?
2. Настройка и требования
Самостоятельная настройка среды
- Войдите в Cloud Console и создайте новый проект или повторно используйте существующий. (Если у вас еще нет учетной записи Gmail или G Suite, вам необходимо ее создать .)
Запомните идентификатор проекта — уникальное имя для всех проектов Google Cloud (имя, указанное выше, уже занято и не подойдет вам, извините!). Позже в этой лаборатории он будет называться PROJECT_ID
.
- Далее вам необходимо включить биллинг в Cloud Console, чтобы использовать ресурсы Google Cloud.
Прохождение этой лаборатории кода не должно стоить много, если вообще стоит. Обязательно следуйте всем инструкциям в разделе «Очистка», в которых рассказывается, как отключить ресурсы, чтобы вам не приходилось нести расходы, выходящие за рамки этого руководства. Новые пользователи Google Cloud имеют право на участие в программе бесплатной пробной версии стоимостью 300 долларов США .
3. Получите образец исходного кода Micronaut.
После запуска Cloud Shell вы можете использовать командную строку для клонирования исходного кода примера в домашнем каталоге и перейти в каталог, содержащий наш пример сервиса:
$ git clone https://github.com/GoogleContainerTools/jib.git
$ cd jib/examples/micronaut/
4. Беглый взгляд на код
Наш простой сервис Micronaut состоит из контроллера, который выводит печально известное сообщение Hello World:
@Controller("/hello") class HelloController { @Get("/") String index() { "Hello World" } }
Контроллер HelloController
отвечает на запросы по пути /hello
, а метод index()
принимает запросы HTTP GET.
Также доступен тестовый класс Спока , позволяющий проверить правильность вывода сообщения.
class HelloControllerSpec extends Specification { @Shared @AutoCleanup EmbeddedServer embeddedServer = ApplicationContext.run(EmbeddedServer) @Shared @AutoCleanup RxHttpClient client = embeddedServer.applicationContext.createBean(RxHttpClient, embeddedServer.getURL()) void "test hello world response"() { when: HttpRequest request = HttpRequest.GET('/hello') String rsp = client.toBlocking().retrieve(request) then: rsp == "Hello World" } }
Это не просто модульный тест, этот тест фактически запускает тот же стек серверов Micronaut (на основе платформы Netty ), который используется в рабочей среде. Таким образом, поведение вашего кода в продукте будет таким же, как и в ваших тестах.
Чтобы запустить тесты, вы можете запустить следующую команду и убедиться, что все в порядке:
./gradlew test
5. Запустите приложение локально.
Вы можете запустить службу Micronaut в обычном режиме с помощью следующей команды Gradle:
$ ./gradlew run
После запуска приложения вы можете открыть дополнительный экземпляр Cloud Shell благодаря маленькому значку +, а затем проверить с помощью Curl, что вы получили ожидаемый результат:
$ curl localhost:8080/hello
И вы должны увидеть простое сообщение «Hello World».
6. Упакуйте приложение как контейнер Docker с помощью Jib.
Затем подготовьте свое приложение для работы в Kubernetes. Для этой цели мы воспользуемся преимуществами Jib, который сделает всю тяжелую работу за нас, поскольку нам не придется самим трогать Dockerfile
!
Давайте запустим команду для сборки нашего контейнера:
$ ./gradlew jibDockerBuild
Вот результат, который вы должны увидеть:
Tagging image with generated image reference micronaut-jib:0.1. If you'd like to specify a different tag, you can set the jib.to.image parameter in your build.gradle, or use the --im age=<MY IMAGE> commandline flag. Containerizing application to Docker daemon as micronaut-jib:0.1... warning: Base image 'gcr.io/distroless/java' does not use a specific image digest - build may not be reproducible Getting base image gcr.io/distroless/java... Building dependencies layer... Building resources layer... Building classes layer... Finalizing... Container entrypoint set to [java, -cp, /app/resources:/app/classes:/app/libs/*, example.micronaut.Application] Loading to Docker daemon... Built image to Docker daemon as micronaut-jib:0.1
Теперь, когда наш образ создан, давайте проверим, можем ли мы увидеть наше дружелюбное приветственное сообщение, запустив наш образ Docker на первой вкладке Cloud Shell:
$ docker run -it -p 8080:8080 micronaut-jib:0.1 16:57:20.255 [main] INFO i.m.context.env.DefaultEnvironment - Established active environments: [cloud, gcp] 16:57:23.203 [main] INFO io.micronaut.runtime.Micronaut - Startup completed in 2926ms. Server Running: http://97b7d76ccf3f:8080
Наша служба запущена, поэтому теперь мы можем запустить команду Curl на второй вкладке Cloud Shell, чтобы проверить, работает ли она должным образом:
$ curl localhost:8080/hello Hello World
Вы можете остановить контейнер, нажав Ctrl+C
в Cloud Shell.
7. Добавление нашего контейнерного сервиса в реестр.
Теперь, когда образ работает так, как задумано, вы можете отправить его в реестр контейнеров Google — частный репозиторий для ваших образов Docker, доступный из каждого проекта Google Cloud (а также из-за пределов Google Cloud Platform).
Прежде чем отправлять данные в реестр, давайте убедимся, что реестр контейнеров включен для нашего проекта, перейдя в Инструменты > Реестр контейнеров . Если он не включен, вы должны увидеть следующее диалоговое окно, затем нажмите « Включить API реестра контейнеров », чтобы включить его:
Когда реестр будет готов, чтобы отправить образ в реестр, запустите следующие команды:
$ gcloud auth configure-docker $ docker tag micronaut-jib:0.1 \ gcr.io/$GOOGLE_CLOUD_PROJECT/micronaut-jib:0.1 $ docker push gcr.io/$GOOGLE_CLOUD_PROJECT/micronaut-jib:0.1
Приведенные выше команды позволяют gcloud SDK настроить и разрешить Docker отправлять изображения в ваш экземпляр реестра контейнеров, помечать образ так, чтобы он указывал на его местоположение в реестре, а затем отправлять его в реестр.
Если все пойдет хорошо, через некоторое время вы сможете увидеть образ контейнера, указанный в консоли: Инструменты > Реестр контейнера . На этом этапе у вас есть доступный образ Docker для всего проекта, к которому Kubernetes может получить доступ и который можно оркестровать, как вы увидите через несколько минут.
8. Создайте свой кластер
Хорошо, теперь вы готовы создать кластер Kubernetes Engine, но перед этим перейдите в раздел Google Kubernetes Engine веб-консоли и дождитесь инициализации системы (это займет всего несколько секунд).
Кластер состоит из главного API-сервера Kubernetes, управляемого Google, и набора рабочих узлов. Рабочие узлы — это виртуальные машины Compute Engine. Давайте воспользуемся CLI gcloud
из вашего сеанса CloudShell, чтобы создать кластер с двумя узлами n1-standard-1
(это займет несколько минут):
$ gcloud container clusters create hello-cluster \ --num-nodes 2 \ --machine-type n1-standard-1 \ --zone us-central1-c
В конце вы должны увидеть созданный кластер.
Creating cluster hello-cluster in us-central1-c...done. Created [https://container.googleapis.com/v1/projects/mn-gke-test/zones/us-central1-c/clusters/hello-cluster]. To inspect the contents of your cluster, go to: https://console.cloud.google.com/kubernetes/workload_/gcloud/us-central1-c/hello-cluster?project=mn-gke-test kubeconfig entry generated for hello-cluster. NAME LOCATION MASTER_VERSION MASTER_IP MACHINE_TYPE NODE_VERSION NUM_NODES STATUS hello-cluster us-central1-c 1.9.7-gke.7 35.239.224.115 n1-standard-1 1.9.7-gke.7 2 RUNNING
Теперь у вас должен быть полнофункциональный кластер Kubernetes на базе Google Kubernetes Engine:
Пришло время развернуть собственное контейнерное приложение в кластере Kubernetes! С этого момента вы будете использовать командную строку kubectl
(уже настроенную в вашей среде Cloud Shell). Для остальной части этой лаборатории кода требуется, чтобы версия клиента и сервера Kubernetes была 1.2 или выше. kubectl version
покажет вам текущую версию команды.
9. Разверните свое приложение в Kubernetes.
Развертывание Kubernetes позволяет создавать, управлять и масштабировать несколько экземпляров вашего приложения, используя только что созданный образ контейнера. Давайте создадим развертывание вашего приложения в Kubernetes с помощью команды kubectl create deployment
:
$ kubectl create deployment hello-micronaut \ --image=gcr.io/$GOOGLE_CLOUD_PROJECT/micronaut-jib:0.1
Чтобы просмотреть только что созданное развертывание, просто запустите:
$ kubectl get deployments NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE hello-micronaut 1 1 1 1 5m
Чтобы просмотреть экземпляры приложения, созданные при развертывании, выполните следующую команду:
$ kubectl get pods NAME READY STATUS RESTARTS AGE hello-micronaut-5647fb98c5-lh5h7 1/1 Running 0 5m
На этом этапе ваш контейнер должен работать под контролем Kubernetes, но вам все равно придется сделать его доступным для внешнего мира.
10. Разрешить внешний трафик
По умолчанию модуль доступен только по внутреннему IP-адресу внутри кластера. Чтобы сделать контейнер hello-micronaut
доступным за пределами виртуальной сети Kubernetes, вам необходимо представить модуль как службу Kubernetes.
Из Cloud Shell вы можете предоставить модуль общедоступному Интернету с помощью команды kubectl expose
в сочетании с флагом --type=LoadBalancer
. Этот флаг необходим для создания IP-адреса, доступного извне:
$ kubectl expose deployment hello-micronaut --type=LoadBalancer --port=8080
Флаг, используемый в этой команде, указывает, что вы будете использовать балансировщик нагрузки, предоставляемый базовой инфраструктурой (в данном случае балансировщик нагрузки Compute Engine ). Обратите внимание, что вы предоставляете доступ к развертыванию, а не к поду напрямую. Это приведет к тому, что результирующая служба будет балансировать трафик между всеми модулями, управляемыми развертыванием (в данном случае только 1 модуль, но вы добавите дополнительные реплики позже).
Мастер Kubernetes создает балансировщик нагрузки и связанные с ним правила переадресации Compute Engine, целевые пулы и правила брандмауэра, чтобы сделать сервис полностью доступным за пределами Google Cloud Platform.
Чтобы найти общедоступный IP-адрес службы, просто запросите kubectl
, чтобы получить список всех служб кластера:
$ kubectl get services NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE hello-micronaut LoadBalancer 10.39.243.251 aaa.bbb.ccc.ddd 8080:30354/TCP 1m kubernetes ClusterIP 10.39.240.1 <none> 443/TCP 31m
Обратите внимание, что для вашей службы указано 2 IP-адреса, оба обслуживают порт 8080
. Одним из них является внутренний IP-адрес, который виден только внутри вашей облачной виртуальной сети; другой — внешний IP-адрес с балансировкой нагрузки. В этом примере внешний IP-адрес — aaa.bbb.ccc.ddd
.
Теперь вы сможете получить доступ к службе, указав в браузере этот адрес: http://<EXTERNAL_IP>
:8080
/hello
11. Расширьте свой сервис
Одна из мощных функций, предлагаемых Kubernetes, — это простота масштабирования вашего приложения. Предположим, вам внезапно потребовалась дополнительная мощность для вашего приложения; вы можете просто указать контроллеру репликации управлять новым количеством реплик для экземпляров вашего приложения:
$ kubectl scale deployment hello-micronaut --replicas=3 deployment.extensions "hello-micronaut" scaled $ kubectl get deployment NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE hello-micronaut 3 3 3 3 16m
Обратите внимание на декларативный подход : вместо запуска или остановки новых экземпляров вы указываете, сколько экземпляров должно работать в любой момент времени. Циклы согласования Kubernetes просто проверяют, соответствует ли реальность тому, что вы запросили, и при необходимости предпринимают действия.
12. Обновите свой сервис
В какой-то момент приложение, которое вы развернули в рабочей среде, потребует исправления ошибок или дополнительных функций. Kubernetes здесь, чтобы помочь вам развернуть новую версию в рабочей среде, не затрагивая ваших пользователей.
Во-первых, давайте изменим приложение. Откройте редактор кода из Cloud Shell.
Перейдите к /jib/examples/micronaut/src/main/groovy/example/micronaut/HelloController.groovy
и обновите значение ответа:
@Controller("/hello") class HelloController { @Get("/") String index() { "Hello Kubernetes World" } }
В /jib/examples/micronaut/build.gradle
мы обновим версию нашего образа с 0,1 до 0,2, обновив эту строку:
version '0.2'
Затем пересоберите и упакуйте приложение с последними изменениями:
$ ./gradlew jibDockerBuild
Пометьте и поместите образ в реестр образов контейнера:
$ docker tag micronaut-jib:0.2 \ gcr.io/$GOOGLE_CLOUD_PROJECT/micronaut-jib:0.2 $ docker push gcr.io/$GOOGLE_CLOUD_PROJECT/micronaut-jib:0.2
Теперь вы готовы к тому, что Kubernetes сможет плавно обновить ваш контроллер репликации до новой версии приложения. Чтобы изменить метку образа для работающего контейнера, вам необходимо отредактировать существующее hello-micronaut deployment
и изменить образ с gcr.io/PROJECT_ID/micronaut-jib:0.1
на gcr.io/PROJECT_ID/micronaut-jib:0.2
.
Вы можете использовать команду kubectl set image
, чтобы попросить Kubernetes развернуть новую версию вашего приложения по всему кластеру по одному экземпляру с последовательным обновлением:
$ kubectl set image deployment/hello-micronaut \ micronaut-jib=gcr.io/$GOOGLE_CLOUD_PROJECT/micronaut-jib:0.2 deployment.apps "hello-micronaut" image updated
Проверьте http://EXTERNAL_IP:8080 еще раз, чтобы убедиться, что он возвращает новый ответ.
13. Откат назад
Упс — вы ошиблись с новой версией приложения? Возможно, новая версия содержала ошибку и вам необходимо быстро выполнить откат. С Kubernetes вы можете легко вернуться к предыдущему состоянию. Давайте откатим приложение, выполнив:
$ kubectl rollout undo deployment/hello-micronaut
Если вы посмотрите на выходные данные службы, мы вернемся к нашему первоначальному сообщению «Hello World».
14. Резюме
На этом этапе вы настроите простую службу приветствия World Micronaut на базе Apache Groovy, запустите ее непосредственно из Cloud Shell, упакуете как контейнер с помощью Jib и развернете в Google Kubernetes Engine.
15. Поздравляем!
Вы узнали, как создать и развернуть новый веб-микросервис Apache Groovy/Micronaut в Kubernetes в Google Kubernetes Engine.
Узнать больше
- Документация и образцы Jib: https://github.com/GoogleContainerTools/jib/.
- Веб-сайт Micronaut: http://micronaut.io/
- Java на облачной платформе Google: https://cloud.google.com/java/
- Примеры Java: https://cloud.google.com/java/samples .
- Более длинное и полное руководство по Kubernetes см. на сайте bit.ly/k8s-lab , где вы узнаете, как развернуть полнофункциональное приложение.
Лицензия
Эта работа распространяется под лицензией Creative Commons Attribution 2.0 Generic License.