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]

相关推荐
Gold Steps.3 小时前
OpenEBS — 云原生 CNS 高性能存储
云原生·kubernetes·存储
瑶山3 小时前
Spring Cloud微服务搭建四、集成RocketMQ消息队列
java·spring cloud·微服务·rocketmq·dashboard
码字的字节4 小时前
Spring Cloud服务注册与发现(一):手把手搭建Eureka Server,详解高可用配置
spring·spring cloud·eureka
大厂资深架构师4 小时前
Spring Cloud Eureka在后端系统中的服务剔除策略
spring·spring cloud·ai·eureka
岁岁种桃花儿5 小时前
SpringCloud从入门到上天:Nacos做微服务注册中心(二)
java·spring cloud·微服务
SoleMotive.10 小时前
谢飞机爆笑面经:Java大厂3轮12问真题拆解(Redis穿透/Kafka分区/MCP Agent)
redis·spring cloud·kafka·java面试·mcp
广州中轴线10 小时前
OpenStack on Kubernetes 生产部署实战(十三)
容器·kubernetes·openstack
切糕师学AI12 小时前
Helm Chart 是什么?
云原生·kubernetes·helm chart
MrSYJ12 小时前
Redis 做分布式 Session
后端·spring cloud·微服务
广州中轴线13 小时前
OpenStack on Kubernetes 生产部署实战(十七)
容器·kubernetes·openstack