В этом руководстве вы собираетесь использовать Kubernetes для развертывания архитектуры микросервиса Spring Boot в Google Cloud, в частности Google Kubernetes Engine (GKE). Вы также собираетесь использовать Visio для создания слоя сервисной сетки и создания общедоступного шлюза. Все это будет защищено с помощью аутентификации Okta OAuth JWT.
Это была путаница жаргона. Мы не собираемся подробно описывать здесь микросервисы. Короче говоря, микросервисы – это шаблон проектирования, который разделяет более крупные монолитные сервисы на более мелкие независимые “микро” сервисы. Эти службы слабо связаны по сети. Преимущества этой архитектуры заключаются в том, что каждая служба становится тестируемой, поддерживаемой и независимо развертываемой. В масштабах Интернета и в таких огромных компаниях, как Amazon и Netflix, эта архитектура великолепна, потому что она позволяет компаниям назначать небольшие команды, отвечающие за управляемые, отдельные функциональные единицы; в отличие от огромных монолитных блоков кода, контролируемых тысячами людей. Недостатком является высокая начальная стоимость сложности и инфраструктуры, что может не иметь смысла для небольших проектов, которые не собираются масштабироваться.
Kubernetes – это платформа для развертывания контейнерных сервисов. Вы можете думать об этом как о контейнерном оркестраторе для контейнеров Docker (это упрощение, но оно сработает). Это позволит нам писать сценарии YAML, которые автоматизируют развертывание нашей микросервисной архитектуры на выбранной нами платформе GKE. Это огромный проект, в котором есть над чем покопаться. Взгляните на их документы для получения дополнительной информации.
Edition добавляет еще один уровень функций поверх Kubernetes, добавляя некоторые отличные функции мониторинга, безопасности, контроля доступа и балансировки нагрузки. Проверьте их веб-сайт для получения дополнительной информации.
Последняя часть микросервисной архитектуры – это Google Cloud и GKE . Это платформа, которую вы будете использовать для развертывания микросервиса. Другой вариант, не описанный в этом руководстве, – это Миникуб. Mini cube работает локально на вашем компьютере и может отлично работать для некоторых людей; Я обнаружил, что движок Google Kubernetes проще в использовании и более производителен.
Мы предполагаем, что вы знакомы с Spring Boot и Java. Если нет, взгляните на конец руководства, чтобы найти некоторые ссылки, которые помогут вам начать.
Требования к Spring Boot и Kubernetes
HTTP ie : Установите HTTPie с их веб-сайта , чтобы мы могли легко запускать HTTP-запросы с терминала.
Docker : Пожалуйста, скачайте и установите Docker Desktop с их веб-сайта , если он у вас еще не установлен.
кубектл : Это интерфейс командной строки Kubernetes. Инструкции по его установке находятся на их веб-сайте .
Google Cloud : Вам понадобится учетная запись Google Cloud с включенной выставлением счетов. Доступна бесплатная пробная версия, которая должна включать более чем достаточный кредит и время, чтобы вы прошли этот урок. Перейдите на веб-сайт Google Cloud и зарегистрируйтесь.
Перейдите на веб-сайт Google Cloud и зарегистрируйтесь. : Мы предлагаем бесплатные учетные записи разработчиков на нашем сайте разработчика . Пожалуйста,
облако : Это облачный интерфейс Google Cloud CLI. Установите его, используя инструкции с их веб-сайта. | Как только это будет сделано, вам нужно будет установить компоненты
gcloud components install kubectl
Я упоминал, что микросервисы имеют высокую начальную стоимость сложности?
Создайте проект Google Kubernetes Engine с помощью Istio
Теперь у вас должна быть учетная запись Google Cloud с включенной выставлением счетов. Опять же, вам не нужно на самом деле тратить какие-либо деньги, но без выставления счетов вы не сможете получить доступ к бесплатной пробной версии.
Создайте новый проект. Назовите это spring-boot-gke
(или все, что вы хотите, но вам понадобится идентификатор проекта для различных команд). Дождитесь создания проекта.
Название проекта, скорее всего, в конечном итоге будет иметь идентификационный номер, прикрепленный к концу, например spring-boot-gke-232934
. Вам понадобится это имя проекта несколько раз, так что продолжайте и сохраните его в переменной оболочки и примите это к сведению.
PROJECT_NAME=
Как только проект будет готов, откройте панель управления проектом, откройте меню навигации и нажмите на Kubernetes Engine . Нажмите кнопку Включить выставление счетов (если вы еще не включили выставление счетов) и выберите учетную запись для выставления счетов.
Нажмите Создать кластер .
На левой боковой панели выберите Ваш первый кластер .
Назовите кластер “spring-boot-cluster”.
Выберите зону “США-запад1-a”.
Нажмите на ссылку Дополнительные параметры в нижней части панели конфигурации кластера, чтобы отобразить дополнительные параметры. Прокрутите страницу вниз до самого низа и установите флажок Включить выпуск (бета-версия) . Это автоматически установит Istio в кластере.
Внизу нажмите Создать , чтобы создать кластер. Выпейте кофе или сделайте перерыв; на создание кластера уйдет несколько минут.
Тем временем, если вы еще этого не сделали, продолжайте и инициализируйте cloud
CLI, выполнив:
gcloud init
В процессе инициализации вы можете установить свой новый проект в качестве проекта по умолчанию, а регион проекта – в качестве региона по умолчанию.
Как только кластер будет развернут, вам необходимо подключить свой локальный cloud
и kubectl
CLI к нему с помощью следующей команды:
gcloud container clusters get-credentials {yourClusterName} --zone us-west1-a --project {yourProjectId}
Если вы использовали другое название проекта, вам нужно будет изменить команду, чтобы отразить это.
записка: Если вы нажмете на кнопку Подключиться справа от панели управления облачной платформы Google, вы увидите правильную команду для ввода:
В результате вы должны увидеть что-то вроде следующего:
Fetching cluster endpoint and auth data. kubeconfig entry generated for spring-boot-cluster.
Вам также нужно будет предоставить себе права администратора в кластере:
kubectl create clusterrolebinding cluster-admin-binding --clusterrole=cluster-admin --user=$(gcloud config get-value core/account)
Теперь вам нужно проверить и убедиться, что службы редактора были установлены и запущены. Есть несколько способов проверить это. Сначала на панели инструментов Google Cloud Platform Kubernetes Engine нажмите кнопку Services . Вы должны увидеть список служб Istio в вашем spring-boot-cluster
. У всех них должно быть зеленое “Ок” под столбцом статуса.
Пока вы там, обратите внимание на службу с именем istio-входной шлюз
типа LoadBalancer
. Это общедоступный балансировщик нагрузки для вашего кластера, и в записи указаны общедоступный IP-адрес и открытые порты.
Другой способ проверить – использовать kubectl
CLI.
Для проверки служб используйте следующую команду: kubectl get services --all-namespaces
. Параметр --all-namespaces
требуется для отображения служб истории, которые находятся в пространстве имен istio-system
.
$ kubectl get services --all-namespaces NAMESPACE NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE default kubernetes ClusterIP 10.31.240.1443/TCP 5m istio-system istio-citadel ClusterIP 10.31.252.214 8060/TCP,9093/TCP 3m istio-system istio-egressgateway ClusterIP 10.31.247.186 80/TCP,443/TCP 3m istio-system istio-galley ClusterIP 10.31.249.131 443/TCP,9093/TCP 3m istio-system istio-ingressgateway LoadBalancer 10.31.244.186 35.185.213.229 80:31380/TCP,443:31390/TCP,31400:31400/TCP,15011:30675/TCP,8060:31581/TCP,853:32460/TCP,15030:30998/TCP,15031:31606/TCP 3m istio-system istio-pilot ClusterIP 10.31.251.44 15010/TCP,15011/TCP,8080/TCP,9093/TCP 3m istio-system istio-policy ClusterIP 10.31.246.176 9091/TCP,15004/TCP,9093/TCP 3m istio-system istio-sidecar-injector ClusterIP 10.31.240.214 443/TCP 3m istio-system istio-telemetry ClusterIP 10.31.247.23 9091/TCP,15004/TCP,9093/TCP,42422/TCP 3m istio-system promsd ClusterIP 10.31.246.88 9090/TCP 3m kube-system default-http-backend NodePort 10.31.250.134 80:31955/TCP 4m kube-system heapster ClusterIP 10.31.250.242 80/TCP 4m kube-system kube-dns ClusterIP 10.31.240.10 53/UDP,53/TCP 4m kube-system metrics-server ClusterIP 10.31.245.127 443/TCP
Чтобы проверить модули Kubernetes, используйте: kubectl get pods --all -пространства имен
$ kubectl get pods --all-namespaces NAMESPACE NAME READY STATUS RESTARTS AGE istio-system istio-citadel-7c4864c9d5-7xq9x 1/1 Running 0 10m istio-system istio-cleanup-secrets-ghqbl 0/1 Completed 0 10m istio-system istio-egressgateway-c7f44ff8-tz7br 1/1 Running 0 10m istio-system istio-galley-698f5c74d6-hmntq 1/1 Running 0 10m istio-system istio-ingressgateway-774d77cb7c-qvhkb 1/1 Running 0 10m istio-system istio-pilot-6bd6f7cdb-gb2gd 2/2 Running 0 10m istio-system istio-policy-678bd4cf9-r8p6z 2/2 Running 0 10m istio-system istio-sidecar-injector-6555557c7b-99c6k 1/1 Running 0 10m istio-system istio-telemetry-5f4cfc5b6-vj8cf 2/2 Running 0 10m istio-system promsd-ff878d44b-hlkpg 2/2 Running 1 10m kube-system heapster-v1.6.0-beta.1-8c76f98c7-2b4dm 2/2 Running 0 9m kube-system kube-dns-7549f99fcc-z5trl 4/4 Running 0 10m kube-system kube-dns-autoscaler-67c97c87fb-m52vb 1/1 Running 0 10m kube-system kube-proxy-gke-spring-boot-cluster-pool-1-b6988227-p09h 1/1 Running 0 10m kube-system l7-default-backend-7ff48cffd7-ppvnn 1/1 Running 0 10m kube-system metrics-server-v0.2.1-fd596d746-njws2 2/2 Running 0 10m
Все модули должны иметь статус Завершено
или Работает
. Пару раз я сталкивался с проблемой, когда автоматическая настройка не работала, а некоторые модули так и не достигли статуса Running
и застряли в Создание контейнера
. Мне пришлось удалить кластер и переустановить его, чтобы заставить его работать.
Если это произойдет, вы можете использовать команду describe god's
, чтобы посмотреть, что происходит: kubectl describe pods -n istio-system
. Это даст вам массу информации обо всех площадках в пространстве имен istio-system
, которое задается с помощью параметров -n
.
Если вы зашли так далеко без проблем, то теперь у вас есть кластер Kubernetes, развернутый на GLEE с установленным Istio! Довольно мило.
И у Google, и у Isis есть несколько довольно полезных документов, если у вас возникнут проблемы. Ознакомьтесь с документами Google GKE docs и Редактор GKE docs для дальнейшей поддержки.
Создайте проект Spring Boot для ваших микросервисов
Теперь перейдите в Spring Initializer и создайте свой начальный проект.
- Измените инструмент сборки с Maven на Gradle
- Использовать Ява и версия Spring Boot/| 2.1.3 Обновите
- Группу до: Обновите
Группу
- до: Использовать
Артефакт
- : springbootkbe Добавьте три
Зависимости
::
Творческая сеть
Нажмите Создать проект и загрузите проект. Распакуйте проект где-нибудь на вашем локальном компьютере и откройте его в вашей любимой среде разработки или редакторе.
Инициализатор Spring создал проект barebones reactive Web flux с поддержкой MongoDB, который вы можете расширить.
Как и в некоторых других моих уроках, и поскольку мне нравится кататься на байдарках, вы собираетесь создать простой реактивный сервис REST, который поддерживает базу данных записей о байдарках. На самом деле это просто демонстрация базовой функциональности CRUD (Создание, чтение, обновление и удаление) и может быть обобщено на любой тип ресурса.
В пакете com.okta.spring.springbootkbe
в разделе src/main/java
создайте класс документа с именем Kayak.java
и вставьте в него следующее. Это ваш документ с реактивной моделью данных.
package com.okta.spring.springbootkbe; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; import org.springframework.data.mongodb.core.mapping.Document; @Document @Data @AllArgsConstructor @NoArgsConstructor public class Kayak { private String name; private String owner; private Number value; private String makeModel; }
Теперь создайте другой файл в том же пакете с именем KayakRepository.java
.
package com.okta.spring.springbootkbe; import org.springframework.data.mongodb.repository.ReactiveMongoRepository; public interface KayakRepository extends ReactiveMongoRepository{ }
Я не собираюсь вдаваться в подробности в этом руководстве о том, что здесь происходит. Spring Boot выполняет множество автоматических связей между этими двумя файлами для создания полнофункционального документа reactive Mongo.
Далее вам нужно добавить контроллер, чтобы разрешить доступ к модели данных документа Kayak. Создайте файл с именем Kayak Controller
в пакете com.okta.spring.springbootkbe
.
package com.okta.spring.springbootkbe; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.*; import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; @Controller @RequestMapping(path = "/kayaks") public class KayakController { private final KayakRepository kayakRepository; public KayakController(KayakRepository kayakRepository) { this.kayakRepository = kayakRepository; } @PostMapping() public @ResponseBody MonoaddKayak(@RequestBody Kayak kayak) { return kayakRepository.save(kayak); } @GetMapping() public @ResponseBody Flux getAllKayaks() { Flux result = kayakRepository.findAll(); return result; }}
Этот контроллер добавляет два метода к конечной точке /kayaks
, конечную точку POST и GET, которые добавляют новую байдарку и перечисляют все байдарки соответственно.
Наконец, добавьте простой корневой контроллер с именем Root Controller
.
package com.okta.spring.springbootkbe; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.*; import reactor.core.publisher.Flux; @Controller public class RootController { @GetMapping("/") @ResponseBody public FluxgetRoot() { return Flux.just("Alive"); } }
Этот контроллер необходим, потому что Kubernetes выполняет проверку работоспособности корневой конечной точки наших служб и должен возвращать ответ, в противном случае кластер подумает, что ваша служба не работает. Фактическая конечная точка настраивается, но вы можете просто оставить ее в корне на данный момент.
Чтобы загрузить некоторые образцы данных в нашу базу данных, обновите определение класса Springbootapplication
, чтобы оно соответствовало следующему.
package com.okta.spring.springbootkbe; import org.springframework.boot.ApplicationRunner; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.annotation.Bean; import reactor.core.publisher.Flux; @SpringBootApplication public class SpringbootkbeApplication { public static void main(String[] args) { SpringApplication.run(SpringbootkbeApplication.class, args); } @Bean ApplicationRunner init(KayakRepository repository) { Object[][] data = { {"sea", "Andrew", 300.12, "NDK"}, {"creek", "Andrew", 100.75, "Piranha"}, {"loaner", "Andrew", 75, "Necky"} }; return args -> { repository .deleteAll() .thenMany( Flux .just(data) .map(array -> { return new Kayak((String) array[0], (String) array[1], (Number) array[2], (String) array[3]); }) .flatMap(repository::save) ) .thenMany(repository.findAll()) .subscribe(kayak -> System.out.println("saving " + kayak.toString())); }; } }
На данный момент у вас есть полностью функционирующее приложение Spring Boot (за вычетом сервера MongoDB). Чтобы протестировать свое приложение, добавьте следующую зависимость в свой файл build.gradle
.
compile 'de.flapdoodle.embed:de.flapdoodle.embed.mongo'
Это добавит встроенную базу данных MongoDB в ваш проект. Вам нужно будет удалить эту зависимость перед развертыванием в кластере, но это позволит вам запустить приложение Spring Boot локально.
Запустите приложение Spring Boot с помощью: gradle bootRun
.
Вы должны увидеть кучу выходных данных, заканчивающихся:
2019-02-14 19:29:34.941 INFO 35982 --- [ntLoopGroup-2-4] org.mongodb.driver.connection : Opened connection [connectionId{localValue:5, serverValue:5}] to localhost:61858 2019-02-14 19:29:34.946 INFO 35982 --- [ntLoopGroup-2-3] org.mongodb.driver.connection : Opened connection [connectionId{localValue:4, serverValue:4}] to localhost:61858 saving Kayak(name=sea, owner=Andrew, value=300.12, makeModel=NDK) saving Kayak(name=loaner, owner=Andrew, value=75, makeModel=Necky) saving Kayak(name=creek, owner=Andrew, value=100.75, makeModel=Piranha)
Используйте HTTPie для тестирования приложения: http:8080
(при этом выполняется запрос get на порт загрузки Spring по умолчанию).
HTTP/1.1 200 OK Content-Type: text/plain;charset=UTF-8 transfer-encoding: chunked Alive
И ПОЛУЧИТЕ свою конечную точку /kayaks
, используя: http:8080/kayaks
.
HTTP/1.1 200 OK Content-Type: application/json;charset=UTF-8 transfer-encoding: chunked [ { "makeModel": "NDK", "name": "sea", "owner": "Andrew", "value": 300.12 }, { "makeModel": "Necky", "name": "loaner", "owner": "Andrew", "value": 75 }, { "makeModel": "Piranha", "name": "creek", "owner": "Andrew", "value": 100.75 } ]
Предполагая, что все сработало, удалите встроенную зависимость Mongo . Вы собираетесь использовать модуль Mongo Kubernetes, и эта зависимость вызовет проблемы с развертыванием кластера.
compile 'de.flapdoodle.embed:de.flapdoodle.embed.mongo'
Разверните модуль MongoDB Kubernetes Pod для вашего приложения Spring Boot
Kubernetes работает (для грубого обобщения и упрощения) путем развертывания контейнеров Docker с использованием сценариев развертывания YAML.
Создайте файл с именем deployment-mongo.yml
в корневом каталоге вашего проекта.
apiVersion: apps/v1 kind: Deployment metadata: name: mongodb labels: appdb: mongodb spec: replicas: 1 selector: matchLabels: appdb: mongodb template: metadata: labels: appdb: mongodb spec: containers: - name: mongodb image: mongo:3.6.6 ports: - containerPort: 27017 --- apiVersion: v1 kind: Service metadata: name: mongodb labels: app: mongodb spec: ports: - port: 27017 protocol: TCP selector: appdb: mongodb
Это определяет MongoDB Kubernetes Deployment
и Service
, необходимые для создания базы данных Mongo в кластере. Я не собираюсь пытаться полностью объяснить, что это за объекты, но вы можете прочитать Kubernetes deployment docs и служебные документы . Грубо говоря, развертывания определяют микроприложения, которые выполняются в развернутых модулях, в то время как службы обеспечивают всеобъемлющую абстракцию, которая определяет точку доступа к приложениям в модулях. Эта абстракция обеспечивает необходимую непрерывность, поскольку модули могут быть отключены и перезапущены, и может быть несколько модулей, выполняющих одну службу.
А теперь немного волнения! Вы собираетесь развернуть развертывание и службу базы данных Mongo в своем кластере GKE.
Используйте следующую команду:
kubectl apply -f deployment-mongo.yml
Вы должны увидеть:
deployment.apps "mongodb" created service "mongodb" created
Проверьте модуль, запустив:
$ kubectl get pods
Вы должны увидеть:
NAME READY STATUS RESTARTS AGE mongodb-c5b8bf947-rkw5f 1/1 Running 0 21s
Если статус указан как Контейнер, создающий
, подождите немного и снова запустите команду. Если он застрянет на Контейнер создает
более нескольких минут, вероятно, что-то пошло не так. Вы можете использовать kubectl для описания модулей
и kubectl получает события
команды, чтобы получить представление о том, что происходит.
Это настроило базу данных Mongo, работающую на порту 27017, используя стандартный образ docker монго:3.6.6
.
Довольно здорово, да? Следующая остановка – ракетостроение!
Разверните приложение Spring Boot в кластере
Добавьте файл с именем Dockerfile
в корневой каталог:
FROM openjdk:8-jdk-alpine ENV APP_FILE springbootkbe-0.1.0-SNAPSHOT.jar ENV APP_HOME /usr/app EXPOSE 8000 COPY build/libs/*.jar $APP_HOME/ WORKDIR $APP_HOME ENTRYPOINT ["sh", "-c"] CMD ["exec java -jar $APP_FILE"]
Обновите src/main/resources/application.properties
:
server.port=8000 spring.data.mongodb.host=mongodb spring.data.mongodb.port=27017
Это настраивает ваш загрузочный порт Spring на порт, который вы предоставляете в Dockerfile
, а также настраивает хост и порт MongoDB. Хостом по умолчанию будет имя службы внутри кластера.
Создайте свое приложение снова (вы же удалили зависимость flapdoodle
, верно?):
gradle clean build
Создайте другой сценарий развертывания Kubernetes с именем deployment.yml
в корневом каталоге проекта:
apiVersion: v1 kind: Service metadata: name: kayak-service labels: app: kayak-service spec: ports: - name: http port: 8000 selector: app: kayak-service --- apiVersion: extensions/v1beta1 kind: Deployment metadata: name: kayak-service spec: replicas: 1 template: metadata: labels: app: kayak-service version: v1 spec: containers: - name: kayak-app image: gcr.io/spring-boot-gke-/kayak-app:1.0 imagePullPolicy: IfNotPresent env: - name: MONGODB_HOST value: mongodb ports: - containerPort: 8000 livenessProbe: httpGet: path: / port: 8000 initialDelaySeconds: 5 periodSeconds: 5
ПРИМЕЧАНИЕ: Внимательно посмотрите на строку с gcr.io/spring-boot-gke/kayak-app:1.0
. Эта средняя часть – название проекта Google Cloud. Это должно соответствовать имени проекта, которое вы использовали, вместе с присвоенным идентификационным номером (что-то вроде spring-boot-gke-43234
).
gcr.io
указывает облачный хост Google для образа docker в Соединенных Штатах. Можно указать другие местоположения. См. Документы реестра контейнеров Google для получения дополнительной информации.
Краткое описание того, что должно произойти, так как здесь много движущихся частей. Приложение Spring Boot будет настроено на docker: встроено в образ docker. Когда вы запустите сценарий развертывания в своем кластере, он попытается извлечь это изображение из реестра контейнеров Google. Поэтому вам нужно поместить изображение в реестр контейнеров и пометить его, чтобы Kubernetes мог найти правильное изображение.
Если вы используете локальный рабочий стол Docker, запустите его и дождитесь его запуска.
Прежде чем вы что-либо сделаете, вам нужно будет настроить Google Cloud и docker так, чтобы они хорошо работали вместе:
gcloud auth configure-docker
Создайте образ docker:
docker build -t kayak-app:1.0 .
Пометьте изображение тегом и поместите его в реестр контейнеров Google (снова обратите внимание на название проекта Google Cloud).:
docker tag kayak-app:1.0 gcr.io/$PROJECT_NAME/kayak-app:1.0; docker push gcr.io/$PROJECT_NAME/kayak-app:1.0
Теперь примените файл deployment.yml
к кластеру GKE:
kubectl apply -f deployment.yml
Проверьте, правильно ли развернут модуль:
kubectl get pods
NAME READY STATUS RESTARTS AGE kayak-service-7df4fb9c88-srqkr 1/1 Running 0 56s mongodb-c5b8bf947-dmghb 1/1 Running 0 16m
Однако на данный момент ваш кластер еще не совсем готов. Это не общедоступно.
Создайте файл с именем istio-gateway.yml
.
apiVersion: networking.istio.io/v1alpha3 kind: Gateway metadata: name: kayak-gateway spec: selector: istio: ingressgateway # use Istio default gateway implementation servers: - port: name: http number: 80 protocol: HTTP hosts: - '*' --- apiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata: name: kayak-service spec: hosts: - "*" gateways: - kayak-gateway http: - match: - uri: prefix: / route: - destination: port: number: 8000 host: kayak-service
И применяйте его:
kubectl apply -f istio-gateway.yml
Вы должны получить:
gateway.networking.istio.io "kayak-gateway" created virtualservice.networking.istio.io "kayak-service" created
Протестируйте развернутое приложение Google Kubernetes Engine + Spring Boot
Теперь, когда вы успешно развернули приложение Spring Boot в кластере Google Kubernetes и создали шлюз, связывающий вашу службу с внешним миром, вы захотите протестировать конечную точку.
На веб-сайте History есть несколько хороших документов о входящем трафике , в которых содержится много полезной информации. Ниже, скопированные с этой страницы, приведены некоторые команды, которые будут определять общедоступный хост/ip-адрес и порты и сохранять их в переменных оболочки.
export INGRESS_HOST=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.status.loadBalancer.ingress[0].ip}'); export INGRESS_PORT=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath=);
В вашей конфигурации INGRESS_PORT
, скорее всего, будет просто 80 по умолчанию для HTTP (без SSL).
Выполните следующую команду, чтобы увидеть хост и порты:
echo "$INGRESS_HOST, HTTP PORT=$INGRESS_PORT";
Общедоступный IP-адрес также можно найти, просмотрев IP-адрес балансировщика нагрузки в Панель инструментов облачной платформы -> Движок Kubernetes -> Сервисы . Найдите istio-входной шлюз сервис типа LoadBalancer .
Протестируйте приложение!
http $INGRESS_HOST:$INGRESS_PORT/
Вы должны увидеть:
HTTP/1.1 200 OK content-type: text/plain;charset=UTF-8 ... Alive
И попали в /байдарки
конечная точка:
http $INGRESS_HOST:$INGRESS_PORT/kayaks
Вы должны увидеть:
HTTP/1.1 200 OK content-type: application/json;charset=UTF-8 ... [ { "makeModel": "NDK", "name": "sea", "owner": "Andrew", "value": 300.12 }, { "makeModel": "Piranha", "name": "creek", "owner": "Andrew", "value": 100.75 }, { "makeModel": "Necky", "name": "loaner", "owner": "Andrew", "value": 75 } ]
Добро пожаловать в мир микросервисов!
Очевидно, что с GLEE и Istio можно сделать гораздо больше. На практике микросервисы обычно управляют большой сетью служб и развернутых модулей, которые можно масштабировать вверх и вниз по мере необходимости, а сложными архитектурами безопасности можно управлять между различными частями и с внешним миром. В этом руководстве мы не будем вдаваться в подробности, но остался еще один шаг: добавление аутентификации веб-токена JSON с помощью Okta.
Создайте приложение OpenID Connect на Okta
Войдите в ваш developer.okta.com счет (Вы ведь зарегистрировались в одной из их бесплатных учетных записей разработчиков, верно? Если нет, перейдите к developer.okta.com ).
Нажмите на Приложение верхнее меню, затем на кнопку Добавить приложение .
Выберите тип приложения Web .
Нажмите Следующий .
Дайте приложению имя. Я назвал свой “Весенний ботинок GKE”.
В разделе URI перенаправления входа в систему добавить https://oidcdebugger.com/debug
.
Внизу, в разделе Разрешенный тип предоставления , установите флажок Неявный (гибридный) .
Нажмите Готово .
Оставьте страницу открытой и обратите внимание на Идентификатор клиента и Секрет клиента . Они понадобятся вам через минуту, когда вы будете использовать отладчик OIDC для создания веб-токена JSON.
Обновите свои микросервисы Spring Boot для OAuth 2.0
Добавьте следующие зависимости в свой build.gradle
:
compile 'org.springframework.security:spring-security-oauth2-client' compile 'org.springframework.security:spring-security-oauth2-resource-server'
Вам также необходимо добавить следующее в свой файл src/main/resources/application.properties
(указав свой собственный URL-адрес Oktadeveloper, что-то вроде dev-123456.okta.com ):
spring.security.oauth2.resourceserver.jwt.issuer-uri=https://{yourOktaDomain}/oauth2/default
Это сообщает Spring, куда ему нужно перейти для аутентификации веб-токена JSON (JWT), который вы собираетесь сгенерировать через мгновение.
Наконец, вам нужно добавить новый класс Java с именем SecurityConfiguration.java
:
package com.okta.spring.springbootkbe; import org.springframework.context.annotation.Bean; import org.springframework.security.config.annotation.web.reactive.EnableWebFluxSecurity; import org.springframework.security.config.web.server.ServerHttpSecurity; import org.springframework.security.web.server.SecurityWebFilterChain; @EnableWebFluxSecurity @EnableReactiveMethodSecurity public class SecurityConfiguration { @Bean public SecurityWebFilterChain securityWebFilterChain(ServerHttpSecurity http) { http .authorizeExchange() .pathMatchers("/").permitAll() .anyExchange().authenticated() .and() .oauth2ResourceServer() .jwt(); return http.build(); } }
Этот файл настраивает проект так, чтобы разрешать все транзакции на корневой конечной точке, но разрешать все остальные транзакции.
Создайте новый образ Docker и переместите его в кластер GKE
Теперь, когда у вас есть новое приложение Spring Boot с поддержкой авторизации, вам нужно создать его, упаковать в контейнер Docker, поместить в реестр Google Cloud Docker и применить новое развертывание к вашему кластеру Kubernetes.
Перейдите в корневой каталог проекта из вашей командной оболочки.
Создайте приложение Spring Boot с обновлениями аутентификации:
gradle clean build
Создайте новый образ Docker. Обратите внимание на новое имя изображения (оно включает в себя -авт.
). Также: убедитесь, что ваш рабочий стол Docker запущен.
docker build -t kayak-app-auth:1.0 .
Пометьте и отправьте свое изображение Docker в реестр облачных контейнеров Google. При необходимости измените имя проекта в пути к репозиторию.
docker tag kayak-app-auth:1.0 gcr.io/$PROJECT_NAME/kayak-app-auth:1.0; docker push gcr.io/$PROJECT_NAME/kayak-app-auth:1.0;
Удалите развернутый модуль в кластере:
kubectl delete -f deployment.yml
Обновите файл deployment.yml
, чтобы отразить новое имя образа (строка 28 в файле):
spec: containers: - name: kayak-app image: gcr.io/spring-boot-gke/kayak-app-auth:1.0
Повторно разверните обновленное развертывание Kubernetes:
kubectl apply -f deployment.yml
Используйте kubectl get pods
для проверки состояния модуля. Полное обновление займет несколько секунд. Как только он будет готов, протестируйте конечную точку /
.
http $INGRESS_HOST:$INGRESS_PORT/ HTTP/1.1 200 OK ... Alive
И конечная точка /kayaks
, которая должна быть защищена:
$ http $INGRESS_HOST:$INGRESS_PORT/kayaks HTTP/1.1 401 Unauthorized ...
Так близко! Последнее, что вам нужно сделать, это использовать инструмент OIDC Debugger для создания токена и проверки подлинности JWT.
Создайте JWT и протестируйте OAuth 2.0
Перейдите в OIDC Debugger . Вам понадобится ваш Идентификатор клиента из вашего приложения Okta OIDC.
- Заполните URI авторизации:
https://{yourOktaDomain}/oauth2/default/v1/авторизовать
. - Заполните Идентификатор клиента .
- Поместите
abcdef
для состояния . - Внизу нажмите Отправить запрос .
Скопируйте сгенерированный токен и сохраните его в переменной оболочки для удобства:
TOKEN=eyJraWQiOiI4UlE5REJGVUJOTnJER0VGaEExekd6bWJqREp...
Снова запустите GET на конечной точке /kayaks
, на этот раз с помощью токена:
http $INGRESS_HOST:$INGRESS_PORT/kayaks Authorization:"Bearer $TOKEN"
ОБРАТИТЕ внимание на двойные кавычки! Одинарные кавычки не будут работать, потому что переменная не будет расширена в строке.
Вы должны получить:
HTTP/1.1 200 OK cache-control: no-cache, no-store, max-age=0, must-revalidate content-type: application/json;charset=UTF-8 ... [ { "makeModel": "NDK", "name": "sea", "owner": "Andrew", "value": 300.12 }, { "makeModel": "Piranha", "name": "creek", "owner": "Andrew", "value": 100.75 }, { "makeModel": "Necky", "name": "loaner", "owner": "Andrew", "value": 75 } ]
Продвигайтесь вперед с помощью микросервисов Spring Boot и Kubernetes
Вот и все! Вы покрыли здесь тонну земли. Вы создали кластер Kubernetes с историей, используя Google Kubernetes в Google Cloud. Вы настроили свою локальную систему для взаимодействия с кластером с помощью cloud
и kubectl
. Вы создали приложение Spring Boot, которое использовало серверную часть MongoDB, настроило его, поместило в облачный реестр Google и развернуло в своем кластере. Вы также добавили аутентификацию OIDC в приложение.
Вы можете найти исходный код для этого примера на GitHub по адресу oktadeveloper/okta-spring-boot-microservice-kubernetes .
Если вы увлекаетесь микросервисами и Spring Boot, вам тоже могут понравиться эти посты:
- Создавайте микросервисы Spring и настраивайте их для производства
- Безопасные микросервисы Spring от сервиса к сервису с поддержкой HTTPS и OAuth 2.0
- Создавайте и защищайте микросервисы с помощью Spring Boot 2.0 и OAuth 2.0
Если у вас есть какие-либо вопросы по поводу этого поста, пожалуйста, добавьте комментарий ниже. Для получения более потрясающего контента подписывайтесь на @oktadev в Twitter, ставьте нам лайки на Facebook или подписывайтесь на наш канал YouTube .
Оригинал: “https://dev.to/oktadev/build-a-microservice-architecture-with-spring-boot-and-kubernetes-3j3k”