javascript
使用Spring Boot和Kubernetes构建微服务架构
“我喜歡編寫身份驗證和授權代碼。” ?從來沒有Java開發人員。 厭倦了一次又一次地建立相同的登錄屏幕? 嘗試使用Okta API進行托管身份驗證,授權和多因素身份驗證。
在本教程中,您將使用Kubernetes將Spring Boot微服務架構部署到Google Cloud,特別是Google Kubernetes Engine(GKE)。 您還將使用Istio創建服務網格層并創建公共網關。 整個事情將使用Okta OAuth JWT身份驗證進行保護。
那是一堆爛話。 我們將不在這里深入解釋微服務。 簡而言之,微服務是一種設計模式,可將較大的單片服務拆分為較小的獨立“微”服務。 這些服務通過網絡松散耦合。 這種體系結構的好處是,每個服務都變得可測試,可維護且可獨立部署。 在互聯網規模上,在像Amazon和Netflix這樣的大型公司中,這種架構都很棒,因為它允許公司將小型團隊的職責分配給可管理的,離散的功能單元。 而不是擁有成千上萬的人監督巨大的整體代碼塊。 不利之處是復雜性和基礎架構的高昂初始成本,這對于無法規模化的較小項目可能沒有意義。
Kubernetes是用于部署容器化服務的平臺。 您可以將其視為Docker容器的容器協調器(這是一種簡化,但是可以使用)。 這將使我們能夠編寫YAML腳本,以自動將微服務架構部署到我們選擇的平臺GKE。 這是一個龐大的項目,需要深入研究。 看看他們的文檔以了解更多信息。
Istio在Kubernetes的基礎上又增加了一層功能,增加了一些出色的監視,安全性,訪問控制和負載平衡功能。 查看他們的網站以獲取更多信息。
微服務架構的最后一部分是Google Cloud和GKE 。 這是您將用于部署微服務的平臺。 本教程中未介紹的另一個選項是Minikube。 Minikube在您的計算機上本地運行,可能對某些人有用。 我發現Google Kubernetes Engine更易于使用且性能更高。
我們假設您熟悉Spring Boot和Java。 如果不是這樣,請查看教程末尾的一些鏈接以幫助您入門。
Spring Boot和Kubernetes的要求
HTTPie :從他們的網站安裝HTTPie,以便我們可以輕松地從終端運行HTTP請求。
Docker :如果尚未安裝Docker Desktop,請從其網站下載并安裝。
kubectl :這是Kubernetes的命令行界面。 有關安裝說明,請參見其網站 。
Google Cloud :您需要一個啟用了計費功能的Google Cloud帳戶。 有一個免費試用版,其中應包括足夠的學分和時間,以幫助您完成本教程。 轉到Google Cloud網站并注冊。
developer.okta.com :我們在開發人員網站上提供免費的開發人員帳戶。 請立即注冊一個。 您將在本教程結束時使用它。
gcloud :這是Google Cloud CLI。 按照其網站上的說明進行安裝。 。 完成此操作后,您需要通過運行以下命令來安裝gcloud kubectl組件:
gcloud components install kubectl我是否提到微服務的初始復雜性成本很高?
使用Istio創建一個Google Kubernetes Engine項目
您現在應該擁有一個啟用了結算功能的Google Cloud帳戶。 同樣,您實際上不需要花任何錢,但是如果不付款,您將無法訪問免費試用版。
創建一個新項目。 將其命名為spring-boot-gke (或任何您想使用的名稱,但是您需要各種命令的項目ID)。 等待項目創建。
項目名稱的結尾可能會帶有一個ID號,例如spring-boot-gke-232934 。 您將需要幾次該項目名稱,因此請繼續將其存儲在shell變量中并記下它。
PROJECT_NAME=<your project name and ID>項目準備就緒后,打開項目儀表板,打開導航菜單,然后單擊Kubernetes Engine 。 單擊啟用帳單按鈕(如果尚未啟用帳單),然后選擇一個帳單帳戶。
單擊創建集群 。
在左側面板中,選擇您的第一個集群 。
將集群命名為“ spring-boot-cluster”。
選擇區域“ us-west1-a”。
單擊集群配置面板底部的“ 高級選項”鏈接以顯示高級選項。 向下滾動到底部,然后選中Enable Istio(beta)復選框。 這將自動在群集上安裝Istio。
在底部,單擊創建以創建集群。 喝咖啡或休息一下; 創建集群將需要幾分鐘。
同時,如果尚未安裝,請繼續運行以下命令來初始化gcloud CLI:
gcloud init在初始化過程中,可以將新項目設置為默認項目,并將項目區域設置為默認區域。
部署集群后,您需要使用以下命令將本地gcloud和kubectl CLI連接到該集群:
gcloud container clusters get-credentials {yourClusterName} --zone us-west1-a --project {yourProjectId}如果您使用了其他項目名稱,則需要更改命令以反映該名稱。
注意:如果單擊Google Cloud Platform儀表板右側的“ 連接”按鈕,您將看到正確的命令,可輸入:
結果,您應該看到類似以下的內容:
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)現在,您需要檢查并確保Istio服務已安裝并正在運行。 有兩種檢查方法。 首先,在您的Google Cloud Platform Kubernetes Engine儀表板中,單擊“ 服務”按鈕。 您應該在spring-boot-cluster看到Istio服務的列表。 它們的狀態列下都應有綠色的“確定”。
在此期間,請注意類型為LoadBalancer名為istio-ingressgateway的服務。 這是群集的公共負載平衡器,該條目顯示公共IP和開放端口。
另一種檢查方法是使用kubectl CLI。
要檢查服務,請使用以下命令: kubectl get services --all-namespaces 。 必須使用--all-namespaces才能顯示istio-system命名空間中的Istio服務。
$ kubectl get services --all-namespaces NAMESPACE NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE default kubernetes ClusterIP 10.31.240.1 <none> 443/TCP 5m istio-system istio-citadel ClusterIP 10.31.252.214 <none> 8060/TCP,9093/TCP 3m istio-system istio-egressgateway ClusterIP 10.31.247.186 <none> 80/TCP,443/TCP 3m istio-system istio-galley ClusterIP 10.31.249.131 <none> 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 <none> 15010/TCP,15011/TCP,8080/TCP,9093/TCP 3m istio-system istio-policy ClusterIP 10.31.246.176 <none> 9091/TCP,15004/TCP,9093/TCP 3m istio-system istio-sidecar-injector ClusterIP 10.31.240.214 <none> 443/TCP 3m istio-system istio-telemetry ClusterIP 10.31.247.23 <none> 9091/TCP,15004/TCP,9093/TCP,42422/TCP 3m istio-system promsd ClusterIP 10.31.246.88 <none> 9090/TCP 3m kube-system default-http-backend NodePort 10.31.250.134 <none> 80:31955/TCP 4m kube-system heapster ClusterIP 10.31.250.242 <none> 80/TCP 4m kube-system kube-dns ClusterIP 10.31.240.10 <none> 53/UDP,53/TCP 4m kube-system metrics-server ClusterIP 10.31.245.127 <none> 443/TCP要檢查Kubernetes Pod,請使用: kubectl get pods --all-namespaces
$ 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各個Pod的狀態都必須為Completed或Running 。 我遇到了幾次問題,其中自動配置不起作用,并且某些吊艙從未達到Running狀態,并停留在ContainerCreating 。 我必須刪除群集并重新安裝它才能正常工作。
如果發生這種情況,您可以使用describe pods命令查看發生了什么: kubectl describe pods -n istio-system 。 這將為您提供有關istio-system名稱空間中所有Pod的istio-system ,這些信息是使用-n選項指定的。
如果到此為止沒有問題,那么現在您已經在安裝了Istio的GKE上部署了Kubernetes集群! 很甜
如果您遇到問題,Google和Istio都會提供一些非常有用的文檔。 查看Google GKE文檔和Istio GKE文檔以獲得進一步的支持。
為您的微服務創建Spring Boot項目
現在轉到Spring Initializer并創建您的啟動項目。
- 將構建工具從Maven更改為Gradle
- 使用Java和Spring Boot版本2.1.3
- 將組更新為: com.okta.spring
- 使用工件 : springbootkbe
- 添加三個依賴項 : Reactive Web , Reactive MongoDB和Lombok
單擊生成項目并下載項目。 將項目解壓縮到本地計算機上的某個位置,然后在您喜歡的IDE或編輯器中將其打開。
Spring Initializer已創建了帶有MongoDB支持的準系統響應式Webflux項目,供您擴展。
與我的其他一些教程一樣,并且由于我喜歡皮劃艇,因此您將構建一個簡單的反應式REST服務,該服務維護皮艇條目的數據庫。 它實際上只是為了演示基本的CRUD功能(創建,讀取,更新和刪除),并且可以推廣到任何類型的資源。
在src/main/java下的com.okta.spring.springbootkbe包中,創建一個名為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<Kayak, Long> { }在本教程中,我不會對這里發生的事情進行過多的詳細介紹。 Spring Boot在這兩個文件之間進行了大量自動匹配,以創建功能齊全的反應式Mongo文檔。
接下來,您需要添加一個控制器以允許訪問Kayak文檔數據模型。 在com.okta.spring.springbootkbe包中創建一個名為KayakController的文件。
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 @ResponseBodyMono<Kayak> addKayak(@RequestBody Kayak kayak) {return kayakRepository.save(kayak);}@GetMapping()public @ResponseBodyFlux<Kayak> getAllKayaks() {Flux<Kayak> result = kayakRepository.findAll();return result;}}該控制器向/kayaks端點添加了兩種方法,即POST和GET端點,它們分別添加了一個新的皮劃艇并列出了所有的皮劃艇。
最后,添加一個簡單的根控制器RootController 。
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 Flux<String> getRoot() { return Flux.just("Alive"); } }此控制器是必需的,因為Kuberenetes在我們服務的根端點上執行運行狀況檢查,并且需要返回響應,否則群集將認為您的服務已關閉。 實際的端點是可配置的,但您現在可以將其留在根目錄下。
要將一些示例數據引導到我們的數據庫中,請更新SpringbootkbeApplication類定義以匹配以下內容。
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);}@BeanApplicationRunner 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應用程序。
使用以下gradle bootRun運行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 (這會在默認的Spring Boot端口上運行get請求)。
HTTP/1.1 200 OK Content-Type: text/plain;charset=UTF-8 transfer-encoding: chunkedAlive并使用以下命令獲取/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 Pod,這種依賴性將導致集群部署出現問題。
compile 'de.flapdoodle.embed:de.flapdoodle.embed.mongo'為您的Spring Boot App部署MongoDB Kubernetes Pod
Kubernetes通過使用YAML部署腳本部署Docker容器來工作(大致概括和簡化)。
在項目的根目錄中創建一個名為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這定義了在集群上創建Mongo數據庫所需的MongoDB Kubernetes Deployment和Service 。 我不會嘗試完全解釋這些對象在這里,但是您可以閱讀Kubernetes 部署文檔和服務文檔 。 粗略地說,部署定義了在已部署的Pod中運行的微應用程序,而服務則提供了總體抽象,該抽象定義了Pod中對應用程序的訪問點。 這種抽象提供了必要的連續性,因為Pod可能會被殺死并重新啟動,并且可能有多個Pod運行一項服務。
現在有些激動! 您將把Mongo數據庫部署和服務部署到GKE集群。
使用以下命令:
kubectl apply -f deployment-mongo.yml您應該看到:
deployment.apps "mongodb" created service "mongodb" created通過運行以下命令來檢查Pod:
$ kubectl get pods您應該看到:
NAME READY STATUS RESTARTS AGE mongodb-c5b8bf947-rkw5f 1/1 Running 0 21s如果狀態列為ContainerCreating ,請稍等片刻,然后再次運行命令。 如果它在ContainerCreating停留超過幾分鐘,則可能出現了問題。 您可以使用kubectl describe pods和kubectl get events命令來了解正在發生的事情。
這使用標準docker映像mongo:3.6.6配置了在端口27017上運行的Mongo數據庫。
太好了吧? 下一站,火箭科學!
將Spring Boot App部署到集群
在根目錄中添加一個名為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這Dockerfile您的Spring Boot端口配置為要在Dockerfile公開的端口,并配置MongoDB主機和端口。 默認情況下,主機將是群集中服務的名稱。
再次構建您的應用程序(您確實刪除了flapdoodle依賴項,對嗎?):
gradle clean build在根項目目錄中創建另一個名為deployment.yml Kubernetes部署腳本:
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項目名稱。 這需要與您使用的項目名稱以及分配的ID號(例如spring-boot-gke-43234 ) spring-boot-gke-43234 。
gcr.io為美國的gcr.io指定了Google Cloud主機。 可以指定其他位置。 有關更多信息,請參見Google Container Registry文檔 。
即將發生的事情的簡要摘要,因為其中有很多活動的部分。 Spring Boot應用程序將進行docker化:內置于docker映像中。 在群集上運行部署腳本時,它將嘗試從Google Container注冊表中提取此映像。 因此,您需要將映像推送到容器注冊表并對其進行標記,以便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檢查以確保Pod正確部署:
kubectl get podsNAME 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 App
既然您已成功將Spring Boot應用程序部署到Google Kubernetes集群并創建了將服務鏈接到外部世界的網關,您將需要測試端點。
Istio網站上有一些關于入口流量的優秀文檔,這些文檔具有很多很好的信息。 下面是從該頁面復制的一些命令,這些命令將確定面向公眾的主機/ ip地址和端口并將其保存到shell變量中
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='{.spec.ports[?(@.name=="http2")].port}');在您的配置中, INGRESS_PORT可能只是HTTP的默認80(無SSL)。
運行以下命令以查看主機和端口:
echo "$INGRESS_HOST, HTTP PORT=$INGRESS_PORT";也可以通過在Cloud Platform儀表板-> Kubernetes Engine->服務中查看負載均衡器IP地址來找到公共IP地址。 尋找類型LoadBalancer的 istio-ingressgateway服務。
測試應用程序!
http $INGRESS_HOST:$INGRESS_PORT/您應該看到:
HTTP/1.1 200 OK content-type: text/plain;charset=UTF-8 ...Alive并點擊/kayaks端點:
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} ]歡迎來到微服務的世界!
顯然,GKE和Istio可以完成更多工作。 在實踐中,微服務通常管理大型服務網格和已部署的Pod,可以根據需要進行擴展和縮小,并且可以在不同部分之間以及與外部世界一起管理復雜的安全體系結構。 本教程將不涉及更多內容,但是還需要再走一步:使用Okta添加JSON Web令牌身份驗證。
在Okta上創建OpenID Connect應用程序
登錄到您的developer.okta.com帳戶(您確實注冊了他們的免費開發者帳戶之一,對嗎?如果不是,請前往developer.okta.com )。
單擊應用程序頂部菜單,然后單擊添加應用程序按鈕。
選擇應用程序類型Web 。
單擊下一步 。
為應用命名。 我將其命名為“ Spring Boot GKE”。
在登錄重定向URI下,添加https://oidcdebugger.com/debug 。
在底部,在允許的授予類型下 ,選中隱式(混合)框。
單擊完成 。
讓頁面保持打開狀態,并記下Client ID和Client Secret 。 使用OIDC調試器生成JSON Web令牌時,一分鐘之內將需要它們。
更新OAuth 2.0的Spring Boot微服務
將以下依賴項添加到您的build.gradle :
compile 'org.springframework.security:spring-security-oauth2-client' compile 'org.springframework.security:spring-security-oauth2-resource-server'您還需要將以下內容添加到src/main/resources/application.properties文件中(填寫您自己的Oktadeveloper URL,類似于dev-123456.okta.com):
spring.security.oauth2.resourceserver.jwt.issuer-uri=https://{yourOktaDomain}/oauth2/default這告訴Spring需要在什么地方對即將生成的JSON Web令牌(JWT)進行身份驗證。
最后,您需要添加一個名為SecurityConfiguration.java的新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 {@Beanpublic 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映像。 注意新的映像名稱(包括-auth )。 另外:確保您的Docker桌面正在運行。
docker build -t kayak-app-auth:1.0 .標記您的Docker映像并將其推送到Google Cloud容器注冊表。 如有必要,請在回購路徑中更改項目名稱。
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;刪除集群上已部署的Pod:
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檢查pod的狀態。 完全更新將需要幾秒鐘。 準備就緒后,測試/端點。
http $INGRESS_HOST:$INGRESS_PORT/ HTTP/1.1 200 OK ...Alive和/kayaks端點,應該對其進行保護:
$ http $INGRESS_HOST:$INGRESS_PORT/kayaks HTTP/1.1 401 Unauthorized ...很近! 您需要做的最后一件事是使用OIDC調試器工具生成令牌并測試JWT身份驗證。
生成一個JWT并測試OAuth 2.0
轉到OIDC調試器 。 您需要從Okta OIDC應用程序中獲取客戶ID 。
- 填寫授權URI: https://{yourOktaDomain} /oauth2/default/v1/authorize
- 填寫客戶ID 。
- 將abcdef為state 。
- 點擊底部的發送請求 。
復制生成的令牌,并將其存儲在shell變量中以方便使用:
TOKEN=eyJraWQiOiI4UlE5REJGVUJOTnJER0VGaEExekd6bWJqREp...再次在/kayaks端點上運行GET,這次使用令牌:
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向前發展
而已! 您已經在這里蓋了一噸土地。 您使用Istio在Google Cloud上使用Google Kubernetes創建了Kubernetes集群。 您已將本地系統配置為使用gcloud和kubectl與集群進行kubectl 。 您創建了一個使用MongoDB后端的Spring Boot應用,對其進行了docker化處理,并將其推送到Google Cloud注冊表中,然后將其部署到您的集群中。 您還向應用程序添加了OIDC身份驗證。
您可以在oktadeveloper / okta-spring-boot-microservice-kubernetes的 GitHub上找到此示例的源代碼。
如果您喜歡微服務和Spring Boot,那么您可能也喜歡這些帖子:
- 構建Spring微服務并對其進行Dockerize生產
- 使用HTTPS和OAuth 2.0保護服務到服務的Spring微服務
- 使用Spring Boot 2.0和OAuth 2.0構建并保護微服務
如果您對此帖子有任何疑問,請在下面添加評論。 有關更多精彩內容, 請在Twitter上關注@oktadev , 在Facebook上關注我們,或訂閱我們的YouTube頻道 。
“ 使用Spring Boot和Kubernetes構建微服務架構 ”最初于2019年4月1日發布在Okta開發者博客上。
“我喜歡編寫身份驗證和授權代碼。” ?從來沒有Java開發人員。 厭倦了一次又一次地建立相同的登錄屏幕? 嘗試使用Okta API進行托管身份驗證,授權和多因素身份驗證。
翻譯自: https://www.javacodegeeks.com/2019/04/build-microservice-architecture-spring-boot-kubernetes.html
總結
以上是生活随笔為你收集整理的使用Spring Boot和Kubernetes构建微服务架构的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: ark驯服恐龙快捷键(ARK怎么驯服恐龙
- 下一篇: 卡宴和揽胜哪个有面子(揽胜和卡宴级别哪个