从上述代码可见,K8sgatewaydemoApplication与普通环境下的SpringCloud Gateway并无差别,都是通过EnableDiscoveryClient注解获取服务列表,配置RouteLocator实现路由逻辑;
配置文件application.yml的内容:
spring: application: name: gateway cloud: gateway: discovery: locator: enabled: true lowerCaseServiceId: true以上就是k8sgatewaydemo应用的内容了,接下来要编译、构建、部署到minikube环境,在pom.xml执行以下命令即可:
mvn clean install fabric8:deploy -Dfabric8.generator.from=fabric8/java-jboss-openjdk8-jdk -Pkubernetes部署完成后终端输出类似如下成功信息:
[INFO] [INFO] <<< fabric8-maven-plugin:3.5.37:deploy (default-cli) < install @ k8sgatewaydemo <<< [INFO] [INFO] [INFO] --- fabric8-maven-plugin:3.5.37:deploy (default-cli) @ k8sgatewaydemo --- [INFO] F8: Using Kubernetes at https://192.168.121.133:8443/ in namespace default with manifest /usr/local/work/k8s/k8sgatewaydemo/target/classes/META-INF/fabric8/kubernetes.yml [INFO] Using namespace: default [INFO] Updating a Service from kubernetes.yml [INFO] Updated Service: target/fabric8/applyJson/default/service-k8sgatewaydemo.json [INFO] Using namespace: default [INFO] Updating Deployment from kubernetes.yml [INFO] Updated Deployment: target/fabric8/applyJson/default/deployment-k8sgatewaydemo.json [INFO] F8: HINT: Use the command `kubectl get pods -w` to watch your pods start up [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time: 16.538 s [INFO] Finished at: 2019-07-07T22:04:48+08:00 [INFO] ------------------------------------------------------------------------查看service和pod,确认一切正常:
[root@minikube k8sgatewaydemo]# clear [root@minikube k8sgatewaydemo]# kubectl get service NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE k8sgatewaydemo NodePort 10.97.94.238 <none> 8080:31352/TCP 129m kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 29d webdemo NodePort 10.106.98.137 <none> 8080:30160/TCP 145m [root@minikube k8sgatewaydemo]# kubectl get pod NAME READY STATUS RESTARTS AGE k8sgatewaydemo-6fbb79885c-r2jfn 1/1 Running 0 33s webdemo-c9f774b9-gsbgx 1/1 Running 0 32m使用minikube命令取得webdemo服务对外暴露的地址:
[root@minikube k8sgatewaydemo]# minikube service k8sgatewaydemo --url :31352可见外部通过地址::31352 即可访问到k8sgatewaydemo应用;
在浏览器输入地址::31352/customize/hello/time ,即可验证k8sgatewaydemo作为网关应用,能否将路径中带有customize的请求转发到webdemo应用,并且在请求header中添加名为entendtag的属性,如下图,浏览器展示的内容是webdemo的http接口返回的,并且extendtag的内容也不为空了,而是k8sgatewaydemo在转发前写入的:
上述结果表明已可以证明我们之前的推测是正确的:SpringCloud Gateway应用在使用了spring-cloud-kubernetes提供的注册发现能力后,可以将请求转发到kubernetes环境中的服务上;
也就是说,借助spring-cloud-kubernetes框架,你在SpringCloud环境开发的SpringCloud Gateway应用,可以以很小的代价迁移到kubernetes环境,与kubernetes环境中的service可以很好的交互,而原有的eureka注册中心也可以不用了; 解决权限问题
如果您的spring-cloud-kubernetes在向webdemo转发请求时抛出以下错误,那是因为遇到了kubernetes的权限问题:
2019-07-06 04:46:40.042 WARN 1 --- [erListUpdater-1] c.n.l.PollingServerListUpdater : Failed one update cycle io.fabric8.kubernetes.client.KubernetesClientException: Failure executing: GET at: https://10.96.0.1/api/v1/namespaces/default/endpoints/account-service. Message: Forbidden!Configured service account doesn't have access. Service account may have been revoked. endpoints "account-service" is forbidden: User "system:serviceaccount:default:default" cannot get resource "endpoints" in API group "" in the namespace "default". at io.fabric8.kubernetes.client.dsl.base.OperationSupport.requestFailure(OperationSupport.java:476) ~[kubernetes-client-4.1.0.jar!/:na] at io.fabric8.kubernetes.client.dsl.base.OperationSupport.assertResponseCode(OperationSupport.java:413) ~[kubernetes-client-4.1.0.jar!/:na] at io.fabric8.kubernetes.client.dsl.base.OperationSupport.handleResponse(OperationSupport.java:381) ~[kubernetes-client-4.1.0.jar!/:na] at io.fabric8.kubernetes.client.dsl.base.OperationSupport.handleResponse(OperationSupport.java:344) ~[kubernetes-client-4.1.0.jar!/:na] at io.fabric8.kubernetes.client.dsl.base.OperationSupport.handleGet(OperationSupport.java:313) ~[kubernetes-client-4.1.0.jar!/:na] at io.fabric8.kubernetes.client.dsl.base.OperationSupport.handleGet(OperationSupport.java:296) ~[kubernetes-client-4.1.0.jar!/:na] at io.fabric8.kubernetes.client.dsl.base.BaseOperation.handleGet(BaseOperation.java:794) ~[kubernetes-client-4.1.0.jar!/:na] at io.fabric8.kubernetes.client.dsl.base.BaseOperation.getMandatory(BaseOperation.java:210) ~[kubernetes-client-4.1.0.jar!/:na] at io.fabric8.kubernetes.client.dsl.base.BaseOperation.get(BaseOperation.java:177) ~[kubernetes-client-4.1.0.jar!/:na] at org.springframework.cloud.kubernetes.ribbon.KubernetesServerList .getUpdatedListOfServers(KubernetesServerList.java:75) ~[spring-cloud-kubernetes-ribbon-1.0.1.RELEASE.jar!/:1.0.1.RELEASE] at com.netflix.loadbalancer.DynamicServerListLoadBalancer.updateListOfServers(DynamicServerListLoadBalancer.java:240) ~[ribbon-loadbalancer-2.3.0.jar!/:2.3.0] at com.netflix.loadbalancer.DynamicServerListLoadBalancer$1.doUpdate(DynamicServerListLoadBalancer.java:62) ~[ribbon-loadbalancer-2.3.0.jar!/:2.3.0] at com.netflix.loadbalancer.PollingServerListUpdater$1.run(PollingServerListUpdater.java:116) ~[ribbon-loadbalancer-2.3.0.jar!/:2.3.0] at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) [na:1.8.0_191] at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:308) [na:1.8.0_191] at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(ScheduledThreadPoolExecutor.java:180) [na:1.8.0_191] at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:294) [na:1.8.0_191] at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [na:1.8.0_191] at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [na:1.8.0_191] at java.lang.Thread.run(Thread.java:748) [na:1.8.0_191]处理方法是创建ServiceAccount对象,步骤如下: