spring-cloud-kubernetes与SpringCloud Gateway

org.springframework.boot

spring-boot-maven-plugin

${spring-boot.version}

repackage

org.apache.maven.plugins

maven-deploy-plugin

${maven-deploy-plugin.version}

true

org.apache.maven.plugins

maven-surefire-plugin

${maven-surefire-plugin.version}

true

false

io.fabric8

fabric8-maven-plugin

${fabric8.maven.plugin.version}

fmp

resource

kubernetes

io.fabric8

fabric8-maven-plugin

${fabric8.maven.plugin.version}

fmp

resource

build

NodePort

  1. 以上就是webdemo应用的内容了,接下来要编译、构建、部署到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 @ webdemo \<\<\< \[INFO

INFO

INFO\] --- fabric8-maven-plugin:3.5.37:deploy (default-cli) @ webdemo --- \[INFO\] F8: Using Kubernetes at https://192.168.121.133:8443/ in namespace default with manifest /usr/local/work/k8s/webdemo/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-webdemo.json \[INFO\] Using namespace: default \[INFO\] Updating Deployment from kubernetes.yml \[INFO\] Updated Deployment: target/fabric8/applyJson/default/deployment-webdemo.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: 11.804 s \[INFO\] Finished at: 2019-07-07T21:32:26+08:00 \[INFO\] ------------------------------------------------------------------------ 5. 查看service和pod,确认一切正常: \[root@minikube webdemo\]# kubectl get service NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kubernetes ClusterIP 10.96.0.1 443/TCP 29d webdemo NodePort 10.106.98.137 8080:30160/TCP 115m \[root@minikube webdemo\]# kubectl get pod NAME READY STATUS RESTARTS AGE webdemo-c9f774b9-gsbgx 1/1 Running 0 3m13s 6. 使用minikube命令取得webdemo服务对外暴露的地址: \[root@minikube webdemo\]# minikube service webdemo --url http://192.168.121.133:30160 可见外部通过地址:[http://192.168.121.133:30160]() 即可访问到webdemo应用; 7. 在浏览器输入地址:[http://192.168.121.133:30160/hello/time]() ,即可验证webdemo的http接口是否正常,如下图,由于header中没有extendtag属性,因此返回的extendtag为null: ![在这里插入图片描述](https://img-blog.csdnimg.cn/20190707214211965.jpg) 至此,webdemo在minikue上已经正常运行,该开发gateway应用了; #### <>开发k8sgatewaydemo 1. 基于maven创建一个名为k8sgatewaydemo的springboot应用,pom.xml内容如下: \ \ 4.0.0 org.springframework.boot spring-boot-starter-parent 2.1.6.RELEASE com.bolingcavalry k8sgatewaydemo 0.0.1-SNAPSHOT k8sgatewaydemo Demo project for Spring Boot \1.8\ \2.1.6.RELEASE\ \false\ \false\ \false\ \3.5\ \2.8.2\ \2.18.1\ \2.21.0\ \3.5.37\ \1.0.1.RELEASE\ \Greenwich.SR2\ org.springframework.cloud spring-cloud-starter-gateway org.springframework.boot spring-boot-starter-test test org.springframework.cloud spring-cloud-kubernetes-core ${springcloud.kubernetes.version} org.springframework.cloud spring-cloud-kubernetes-discovery ${springcloud.kubernetes.version} org.springframework.cloud spring-cloud-starter-kubernetes-ribbon ${springcloud.kubernetes.version} org.springframework.cloud spring-cloud-commons org.springframework.boot spring-boot-starter org.springframework.cloud spring-cloud-starter-netflix-ribbon org.springframework.cloud spring-cloud-starter-netflix-hystrix org.springframework.cloud spring-cloud-dependencies ${spring-cloud.version} pom import org.springframework.boot spring-boot-maven-plugin ${spring-boot.version} repackage org.apache.maven.plugins maven-deploy-plugin ${maven-deploy-plugin.version} true org.apache.maven.plugins maven-surefire-plugin ${maven-surefire-plugin.version} true false io.fabric8 fabric8-maven-plugin ${fabric8.maven.plugin.version} fmp resource kubernetes io.fabric8 fabric8-maven-plugin ${fabric8.maven.plugin.version} fmp resource build NodePort 上述pom文件中有以下几点需要注意: 第一、 依赖spring-cloud-kubernetes-core和spring-cloud-kubernetes-discovery,这样能用到spring-cloud-kubernetes提供的服务发现能力; 第二、依赖spring-cloud-starter-gateway,这样能用上SpringCloud的gateway能力; 第三、不要依赖spring-boot-starter-web,会和spring-cloud-starter-gateway冲突,启动时抛出以下异常: 2019-07-06 08:12:09.188 WARN 1 --- \[ main\] ConfigServletWebServerApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'routeDefinitionRouteLocator' defined in class path resource \[org/springframework/cloud/gateway/config/GatewayAutoConfiguration.class\]: Unsatisfied dependency expressed through method 'routeDefinitionRouteLocator' parameter 1; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'modifyRequestBodyGatewayFilterFactory' defined in class path resource \[org/springframework/cloud/gateway/config/GatewayAutoConfiguration.class\]: Unsatisfied dependency expressed through method 'modifyRequestBodyGatewayFilterFactory' parameter 0; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'org.springframework.http.codec.ServerCodecConfigurer' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {} 2. 开发SpringCloud Gateway的启动类K8sgatewaydemoApplication.java,里面也包含了网关路由配置的实例化,除了配置路径和转发服务的关系,还在请求的header中添加了extendtag属性,请注意注释的内容: @SpringBootApplication @EnableDiscoveryClient public class K8sgatewaydemoApplication { public static void main(String\[\] args) { SpringApplication.run(K8sgatewaydemoApplication.class, args); } @Bean public RouteLocator customRouteLocator(RouteLocatorBuilder builder) { return builder.routes() //增加一个path匹配,以"/customize/hello/"开头的请求都在此路由 .route(r -\> r.path("/customize/hello/\*\*") //表示将路径中的第一级参数删除,用剩下的路径与webdemo的路径做拼接, //这里就是"lb://webdemo/hello/",能匹配到webdemo的HelloController的路径 .filters(f -\> f.stripPrefix(1) //在请求的header中添加一个key\&value .addRequestHeader("extendtag", "geteway-" + System.currentTimeMillis())) //指定匹配服务webdemo,lb是load balance的意思 .uri("lb://webdemo") ).build(); } } 从上述代码可见,K8sgatewaydemoApplication与普通环境下的SpringCloud Gateway并无差别,都是通过EnableDiscoveryClient注解获取服务列表,配置RouteLocator实现路由逻辑; 3. 配置文件application.yml的内容: spring: application: name: gateway cloud: gateway: discovery: locator: enabled: true lowerCaseServiceId: true 4. 以上就是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\] ------------------------------------------------------------------------ 5. 查看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 8080:31352/TCP 129m kubernetes ClusterIP 10.96.0.1 443/TCP 29d webdemo NodePort 10.106.98.137 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 6. 使用minikube命令取得webdemo服务对外暴露的地址: \[root@minikube k8sgatewaydemo\]# minikube service k8sgatewaydemo --url http://192.168.121.133:31352 可见外部通过地址:[http://192.168.121.133:31352]() 即可访问到k8sgatewaydemo应用; 7. 在浏览器输入地址:[http://192.168.121.133:31352/customize/hello/time]() ,即可验证k8sgatewaydemo作为网关应用,能否将路径中带有customize的请求转发到webdemo应用,并且在请求header中添加名为entendtag的属性,如下图,浏览器展示的内容是webdemo的http接口返回的,并且extendtag的内容也不为空了,而是k8sgatewaydemo在转发前写入的: ![在这里插入图片描述](https://img-blog.csdnimg.cn/20190707221023984.jpg) 上述结果表明已可以证明我们之前的推测是正确的: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.ScheduledThreadPoolExecutorScheduledFutureTask.access301(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]

相关推荐
GreenMountainEcho5 小时前
Kubernetes 入门篇之 Node 安装与部署
云原生·容器·kubernetes
ghostwritten7 小时前
Rancher Backup
kubernetes·rancher
alden_ygq8 小时前
k8s statefulset pod重启顺序
云原生·容器·kubernetes
ghostwritten8 小时前
k8s黑科技:Linux+Vagrant+VirtualBox开启Kubernetes奇幻之旅
linux·科技·kubernetes
云上艺旅11 小时前
K8S学习之基础七十二:Ingress基于Https代理pod
学习·云原生·容器·https·kubernetes
liux352811 小时前
k8s之Ingress讲解
云原生·容器·kubernetes
阁阁下11 小时前
springcloud configClient获取configServer信息失败导致启动configClient注入失败报错解决
后端·spring·spring cloud
小刘爱喇石( ˝ᗢ̈˝ )15 小时前
玛卡巴卡的k8s知识点问答题(六)
云原生·容器·kubernetes
rider18915 小时前
【1】搭建k8s集群系列(二进制部署)之系统初始化
云原生·容器·kubernetes
小刘爱喇石( ˝ᗢ̈˝ )16 小时前
玛卡巴卡的k8s知识点问答题(七)
云原生·容器·kubernetes