当前位置:   article > 正文

Spring-cloud-k8s与SpringCloud Gateway

spring-cloud-kubernetes和gateways

微信公众号搜索DevOps和k8s全栈技术 ,即可关注我的公众号,也可通过扫描文章最后的二维码关注,每天都会分享技术文章供大家参考阅读~,拥抱开源,同大家共同进步~!!!

本文大纲

接下来的内容由以下几部分组成:

  1. 什么是SpringCloud Gateway

  2. SpringCloud Gateway实战参考

  3. kubernetes上的SpringCloud Gateway

  4. 实战环境信息

  5. 实战源码下载

  6. 开发webdemo

  7. 开发k8sgatewaydemo

  8. 解决权限问题

  9. 最后一个疑问

什么是SpringCloud Gateway

SpringCloud Gateway是SpringCloud技术栈下的网关服务框架,在基于SpringCloud的微服务环境中,外部请求会到达SpringCloud Gateway应用,该应用对请求做转发、过滤、鉴权、熔断等前置操作,一个典型的请求响应流程如下所示:



kubernetes上的SpringCloud Gateway

注意以下两个知识点:

  1. SpringCloud Gateway之所以能将外部请求路由到正确的后台服务上,是因为注册中心的存在,SpringCloud Gateway可以在注册中心取得所有服务的信息,因此它可以根据路径和服务的对应关系,将请求转发到对应的服务上;

  2. 如果您看过本系列的上一篇 《spring-cloud-kubernetes的服务发现和轮询实战(含熔断)》,您就知道spring-cloud-kubernetes框架可以获取kubernetes环境内的所有服务(这里说的服务就是kubernetes的service);

将以上两个知识点结合起来,于是可以推测:运行在kubernetes环境的SpringCloud Gateway应用,如果使用了spring-cloud-kubernetes框架就能得到kubernetes的service列表,因此可以承担网关的角色,将外部请求转发至kubernetes内的service上,最终到达对应的Pod;

架构如下图所示,请注意黄色背景的对话框,里面标识了关键操作:


至此,理论分析已经完成,我们来实战验证这个理论,接下来我们开发两个java应用:

  1. 先开发一个普通的web服务,名为webdemo,提供一个http接口;

  2. 再开发一个SpringCloud Gateway应用,名为k8sgatewaydemo;

环境信息

本次实战的环境和版本信息如下:

  1. 操作系统:CentOS Linux release 7.6.1810

  2. minikube:1.1.1

  3. Java:1.8.0_191

  4. Maven:3.6.0

  5. fabric8-maven-plugin插件:3.5.37

  6. spring-cloud-kubernetes:1.0.1.RELEASE

  7. spring cloud:Greenwich.SR2

  8. springboot:2.1.6.RELEASE

源码下载

如果您不打算写代码,也可以从GitHub上下载本次实战的源码,地址和链接信息如下表所示:

这个git项目中有多个文件夹,本章的两个应用分别在webdemo和k8sgatewaydemo文件夹下;下图红框中是webdemo应用的源码:

下图红框中是k8sgatewaydemo应用的源码:

下面是详细的编码过程;

开发webdemo

webdemo是个极其普通的spring boot应用,和SpringCloud没有任何关系;

1.webdemo提供一个http接口,将请求header中名为extendtag的参数返回给请求方,controller类如下:

  1. @RestController
  2. @RequestMapping("/hello")
  3. public class HelloController {
  4. @RequestMapping(value = "time", method = RequestMethod.GET)
  5. public String hello(HttpServletRequest request){
  6. return "hello, "
  7. + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date())
  8. + ", extendtag ["
  9. + request.getHeader("extendtag")
  10. + "]";
  11. }
  12. }
2.启动类WebdemoApplication.java:
  1. @SpringBootApplication
  2. public class WebdemoApplication {
  3. public static void main(String[] args) {
  4. SpringApplication.run(WebdemoApplication.class, args);
  5. }
  6. }
3.要注意的是pom.xml,里面通过名为fabric8-maven-plugin的maven插件,将webdemo快速部署到minikube环境:
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  3. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  4. <modelVersion>4.0.0</modelVersion>
  5. <parent>
  6. <groupId>org.springframework.boot</groupId>
  7. <artifactId>spring-boot-starter-parent</artifactId>
  8. <version>2.1.6.RELEASE</version>
  9. <relativePath/> <!-- lookup parent from repository -->
  10. </parent>
  11. <groupId>com.bolingcavalry</groupId>
  12. <artifactId>webdemo</artifactId>
  13. <version>0.0.1-SNAPSHOT</version>
  14. <name>webdemo</name>
  15. <description>Demo project for Spring Boot</description>
  16. <properties>
  17. <java.version>1.8</java.version>
  18. <spring-boot.version>2.1.6.RELEASE</spring-boot.version>
  19. <fabric8.maven.plugin.version>3.5.37</fabric8.maven.plugin.version>
  20. </properties>
  21. <dependencies>
  22. <dependency>
  23. <groupId>org.springframework.boot</groupId>
  24. <artifactId>spring-boot-starter-web</artifactId>
  25. </dependency>
  26. <dependency>
  27. <groupId>org.springframework.boot</groupId>
  28. <artifactId>spring-boot-starter-test</artifactId>
  29. <scope>test</scope>
  30. </dependency>
  31. </dependencies>
  32. <build>
  33. <plugins>
  34. <plugin>
  35. <groupId>org.springframework.boot</groupId>
  36. <artifactId>spring-boot-maven-plugin</artifactId>
  37. <version>${spring-boot.version}</version>
  38. <executions>
  39. <execution>
  40. <goals>
  41. <goal>repackage</goal>
  42. </goals>
  43. </execution>
  44. </executions>
  45. </plugin>
  46. <plugin>
  47. <!--skip deploy -->
  48. <groupId>org.apache.maven.plugins</groupId>
  49. <artifactId>maven-deploy-plugin</artifactId>
  50. <version>${maven-deploy-plugin.version}</version>
  51. <configuration>
  52. <skip>true</skip>
  53. </configuration>
  54. </plugin>
  55. <plugin>
  56. <groupId>org.apache.maven.plugins</groupId>
  57. <artifactId>maven-surefire-plugin</artifactId>
  58. <version>${maven-surefire-plugin.version}</version>
  59. <configuration>
  60. <skipTests>true</skipTests>
  61. <!-- Workaround for https://issues.apache.org/jira/browse/SUREFIRE-1588 -->
  62. <useSystemClassLoader>false</useSystemClassLoader>
  63. </configuration>
  64. </plugin>
  65. <plugin>
  66. <groupId>io.fabric8</groupId>
  67. <artifactId>fabric8-maven-plugin</artifactId>
  68. <version>${fabric8.maven.plugin.version}</version>
  69. <executions>
  70. <execution>
  71. <id>fmp</id>
  72. <goals>
  73. <goal>resource</goal>
  74. </goals>
  75. </execution>
  76. </executions>
  77. </plugin>
  78. </plugins>
  79. </build>
  80. <profiles>
  81. <profile>
  82. <id>kubernetes</id>
  83. <build>
  84. <plugins>
  85. <plugin>
  86. <groupId>io.fabric8</groupId>
  87. <artifactId>fabric8-maven-plugin</artifactId>
  88. <version>${fabric8.maven.plugin.version}</version>
  89. <executions>
  90. <execution>
  91. <id>fmp</id>
  92. <goals>
  93. <goal>resource</goal>
  94. <goal>build</goal>
  95. </goals>
  96. </execution>
  97. </executions>
  98. <configuration>
  99. <enricher>
  100. <config>
  101. <fmp-service>
  102. <type>NodePort</type>
  103. </fmp-service>
  104. </config>
  105. </enricher>
  106. </configuration>
  107. </plugin>
  108. </plugins>
  109. </build>
  110. </profile>
  111. </profiles>
  112. </project>

3.以上就是webdemo应用的内容了,接下来要编译、构建、部署到minikube环境,在pom.xml执行以下命令即可:

mvn clean install fabric8:deploy -Dfabric8.generator.from=fabric8/java-j
boss-openjdk8-jdk -Pkubernetes复制代码

部署完成后终端输出类似如下成功信息:

  1. [INFO]
  2. [INFO] <<< fabric8-maven-plugin:3.5.37:deploy (default-cli) < install @ webdemo <<<
  3. [INFO]
  4. [INFO]
  5. [INFO] --- fabric8-maven-plugin:3.5.37:deploy (default-cli) @ webdemo ---
  6. [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
  7. [INFO] Using namespace: default
  8. [INFO] Updating a Service from kubernetes.yml
  9. [INFO] Updated Service: target/fabric8/applyJson/default/service-webdemo.json
  10. [INFO] Using namespace: default
  11. [INFO] Updating Deployment from kubernetes.yml
  12. [INFO] Updated Deployment: target/fabric8/applyJson/default/deployment-webdemo.json
  13. [INFO] F8: HINT: Use the command `kubectl get pods -w` to watch your pods start up
  14. [INFO] ------------------------------------------------------------------------
  15. [INFO] BUILD SUCCESS
  16. [INFO] ------------------------------------------------------------------------
  17. [INFO] Total time: 11.804 s
  18. [INFO] Finished at: 2019-07-07T21:32:26+08:00
  19. [INFO] ------------------------------------------------------------------------

1.查看service和pod,确认一切正常

  1. [INFO]
  2. [INFO] <<< fabric8-maven-plugin:3.5.37:deploy (default-cli) < install @ webdemo <<<
  3. [INFO]
  4. [INFO]
  5. [INFO] --- fabric8-maven-plugin:3.5.37:deploy (default-cli) @ webdemo ---
  6. [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
  7. [INFO] Using namespace: default
  8. [INFO] Updating a Service from kubernetes.yml
  9. [INFO] Updated Service: target/fabric8/applyJson/default/service-webdemo.json
  10. [INFO] Using namespace: default
  11. [INFO] Updating Deployment from kubernetes.yml
  12. [INFO] Updated Deployment: target/fabric8/applyJson/default/deployment-webdemo.json
  13. [INFO] F8: HINT: Use the command `kubectl get pods -w` to watch your pods start up
  14. [INFO] ------------------------------------------------------------------------
  15. [INFO] BUILD SUCCESS
  16. [INFO] ------------------------------------------------------------------------
  17. [INFO] Total time: 11.804 s
  18. [INFO] Finished at: 2019-07-07T21:32:26+08:00
  19. [INFO] ------------------------------------------------------------------------

2.查看service和pod,确认一切正常:

  1. [root@minikube webdemo]# kubectl get service
  2. NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
  3. kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 29d
  4. webdemo NodePort 10.106.98.137 <none> 8080:30160/TCP 115m
  5. [root@minikube webdemo]# kubectl get pod
  6. NAME READY STATUS RESTARTS AGE
  7. webdemo-c9f774b9-gsbgx 1/1 Running 0 3m13s

3.使用minikube命令取得webdemo服务对外暴露的地址:

  1. [root@minikube webdemo]# minikube service webdemo --url
  2. http://192.168.121.133:30160

可见外部通过地址:http://192.168.121.133:30160 即可访问到webdemo应用;

4.在浏览器输入地址:http://192.168.121.133:30160/hello/time ,即可验证webdemo的http接口是否正常,如下图,由于header中没有extendtag属性,因此返回的extendtag为null:

至此,webdemo在minikue上已经正常运行,该开发gateway应用了;

开发k8sgatewaydemo

1.基于maven创建一个名为k8sgatewaydemo的springboot应用,pom.xml内容如下:

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  3. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  4. <modelVersion>4.0.0</modelVersion>
  5. <parent>
  6. <groupId>org.springframework.boot</groupId>
  7. <artifactId>spring-boot-starter-parent</artifactId>
  8. <version>2.1.6.RELEASE</version>
  9. <relativePath/> <!-- lookup parent from repository -->
  10. </parent>
  11. <groupId>com.bolingcavalry</groupId>
  12. <artifactId>k8sgatewaydemo</artifactId>
  13. <version>0.0.1-SNAPSHOT</version>
  14. <name>k8sgatewaydemo</name>
  15. <description>Demo project for Spring Boot</description>
  16. <properties>
  17. <java.version>1.8</java.version>
  18. <spring-boot.version>2.1.6.RELEASE</spring-boot.version>
  19. <maven-checkstyle-plugin.failsOnError>false</maven-checkstyle-plugin.failsOnError>
  20. <maven-checkstyle-plugin.failsOnViolation>false</maven-checkstyle-plugin.failsOnViolation>
  21. <maven-checkstyle-plugin.includeTestSourceDirectory>false</maven-checkstyle-plugin.includeTestSourceDirectory>
  22. <maven-compiler-plugin.version>3.5</maven-compiler-plugin.version>
  23. <maven-deploy-plugin.version>2.8.2</maven-deploy-plugin.version>
  24. <maven-failsafe-plugin.version>2.18.1</maven-failsafe-plugin.version>
  25. <maven-surefire-plugin.version>2.21.0</maven-surefire-plugin.version>
  26. <fabric8.maven.plugin.version>3.5.37</fabric8.maven.plugin.version>
  27. <springcloud.kubernetes.version>1.0.1.RELEASE</springcloud.kubernetes.version>
  28. <spring-cloud.version>Greenwich.SR2</spring-cloud.version>
  29. </properties>
  30. <dependencies>
  31. <dependency>
  32. <groupId>org.springframework.cloud</groupId>
  33. <artifactId>spring-cloud-starter-gateway</artifactId>
  34. </dependency>
  35. <dependency>
  36. <groupId>org.springframework.boot</groupId>
  37. <artifactId>spring-boot-starter-test</artifactId>
  38. <scope>test</scope>
  39. </dependency>
  40. <dependency>
  41. <groupId>org.springframework.cloud</groupId>
  42. <artifactId>spring-cloud-kubernetes-core</artifactId>
  43. <version>${springcloud.kubernetes.version}</version>
  44. </dependency>
  45. <dependency>
  46. <groupId>org.springframework.cloud</groupId>
  47. <artifactId>spring-cloud-kubernetes-discovery</artifactId>
  48. <version>${springcloud.kubernetes.version}</version>
  49. </dependency>
  50. <dependency>
  51. <groupId>org.springframework.cloud</groupId>
  52. <artifactId>spring-cloud-starter-kubernetes-ribbon</artifactId>
  53. <version>${springcloud.kubernetes.version}</version>
  54. </dependency>
  55. <dependency>
  56. <groupId>org.springframework.cloud</groupId>
  57. <artifactId>spring-cloud-commons</artifactId>
  58. </dependency>
  59. <dependency>
  60. <groupId>org.springframework.boot</groupId>
  61. <artifactId>spring-boot-starter</artifactId>
  62. </dependency>
  63. <dependency>
  64. <groupId>org.springframework.cloud</groupId>
  65. <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
  66. </dependency>
  67. <dependency>
  68. <groupId>org.springframework.cloud</groupId>
  69. <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
  70. </dependency>
  71. </dependencies>
  72. <dependencyManagement>
  73. <dependencies>
  74. <dependency>
  75. <groupId>org.springframework.cloud</groupId>
  76. <artifactId>spring-cloud-dependencies</artifactId>
  77. <version>${spring-cloud.version}</version>
  78. <type>pom</type>
  79. <scope>import</scope>
  80. </dependency>
  81. </dependencies>
  82. </dependencyManagement>
  83. <build>
  84. <plugins>
  85. <plugin>
  86. <groupId>org.springframework.boot</groupId>
  87. <artifactId>spring-boot-maven-plugin</artifactId>
  88. <version>${spring-boot.version}</version>
  89. <executions>
  90. <execution>
  91. <goals>
  92. <goal>repackage</goal>
  93. </goals>
  94. </execution>
  95. </executions>
  96. </plugin>
  97. <plugin>
  98. <!--skip deploy -->
  99. <groupId>org.apache.maven.plugins</groupId>
  100. <artifactId>maven-deploy-plugin</artifactId>
  101. <version>${maven-deploy-plugin.version}</version>
  102. <configuration>
  103. <skip>true</skip>
  104. </configuration>
  105. </plugin>
  106. <plugin>
  107. <groupId>org.apache.maven.plugins</groupId>
  108. <artifactId>maven-surefire-plugin</artifactId>
  109. <version>${maven-surefire-plugin.version}</version>
  110. <configuration>
  111. <skipTests>true</skipTests>
  112. <!-- Workaround for https://issues.apache.org/jira/browse/SUREFIRE-1588 -->
  113. <useSystemClassLoader>false</useSystemClassLoader>
  114. </configuration>
  115. </plugin>
  116. <plugin>
  117. <groupId>io.fabric8</groupId>
  118. <artifactId>fabric8-maven-plugin</artifactId>
  119. <version>${fabric8.maven.plugin.version}</version>
  120. <executions>
  121. <execution>
  122. <id>fmp</id>
  123. <goals>
  124. <goal>resource</goal>
  125. </goals>
  126. </execution>
  127. </executions>
  128. </plugin>
  129. </plugins>
  130. </build>
  131. <profiles>
  132. <profile>
  133. <id>kubernetes</id>
  134. <build>
  135. <plugins>
  136. <plugin>
  137. <groupId>io.fabric8</groupId>
  138. <artifactId>fabric8-maven-plugin</artifactId>
  139. <version>${fabric8.maven.plugin.version}</version>
  140. <executions>
  141. <execution>
  142. <id>fmp</id>
  143. <goals>
  144. <goal>resource</goal>
  145. <goal>build</goal>
  146. </goals>
  147. </execution>
  148. </executions>
  149. <configuration>
  150. <enricher>
  151. <config>
  152. <fmp-service>
  153. <type>NodePort</type>
  154. </fmp-service>
  155. </config>
  156. </enricher>
  157. </configuration>
  158. </plugin>
  159. </plugins>
  160. </build>
  161. </profile>
  162. </profiles>
  163. </project>

上述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冲突,启动时抛出以下异常:

  1. 2019-07-06 08:12:09.188 WARN 1 --- [ main] ConfigServletWebServerApplicationContext :
  2. Exception encountered during context initialization -
  3. cancelling refresh attempt:
  4. org.springframework.beans.factory.UnsatisfiedDependencyException:
  5. Error creating bean with name 'routeDefinitionRouteLocator' defined in class path resource [org/springframework/cloud/gateway/config/GatewayAutoConfiguration.class]:
  6. Unsatisfied dependency expressed through method 'routeDefinitionRouteLocator' parameter 1;
  7. nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException:
  8. Error creating bean with name 'modifyRequestBodyGatewayFilterFactory' defined in class path resource [org/springframework/cloud/gateway/config/GatewayAutoConfiguration.class]:
  9. Unsatisfied dependency expressed through method 'modifyRequestBodyGatewayFilterFactory' parameter 0;
  10. nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'org.springframework.http.codec.ServerCodecConfigurer' available:
  11. expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}

1.开发SpringCloud Gateway的启动类K8sgatewaydemoApplication.java,里面也包含了网关路由配置的实例化,除了配置路径和转发服务的关系,还在请求的header中添加了extendtag属性,请注意注释的内容:

  1. @SpringBootApplication
  2. @EnableDiscoveryClient
  3. public class K8sgatewaydemoApplication {
  4. public static void main(String[] args) {
  5. SpringApplication.run(K8sgatewaydemoApplication.class, args);
  6. }
  7. @Bean
  8. public RouteLocator customRouteLocator(RouteLocatorBuilder builder) {
  9. return builder.routes()
  10. //增加一个path匹配,以"/customize/hello/"开头的请求都在此路由
  11. .route(r -> r.path("/customize/hello/**")
  12. //表示将路径中的第一级参数删除,用剩下的路径与webdemo的路径做拼接,
  13. //这里就是"lb://webdemo/hello/",能匹配到webdemo的HelloController的路径
  14. .filters(f -> f.stripPrefix(1)
  15. //在请求的header中添加一个key&value
  16. .addRequestHeader("extendtag", "geteway-" + System.currentTimeMillis()))
  17. //指定匹配服务webdemo,lb是load balance的意思
  18. .uri("lb://webdemo")
  19. ).build();
  20. }
  21. }

从上述代码可见,K8sgatewaydemoApplication与普通环境下的SpringCloud Gateway并无差别,都是通过EnableDiscoveryClient注解获取服务列表,配置RouteLocator实现路由逻辑;

2.配置文件application.yml的内容:

  1. spring:
  2. application:
  3. name: gateway
  4. cloud:
  5. gateway:
  6. discovery:
  7. locator:
  8. enabled: true
  9. lowerCaseServiceId: true

3.以上就是k8sgatewaydemo应用的内容了,接下来要编译、构建、部署到minikube环境,在pom.xml执行以下命令即可:

mvn clean install fabric8:deploy -Dfabric8.generator.from=fabric8/java-jboss-openjdk8-jdk -Pkubernetes

部署完成后终端输出类似如下成功信息:

  1. [INFO]
  2. [INFO] <<< fabric8-maven-plugin:3.5.37:deploy (default-cli) < install @ k8sgatewaydemo <<<
  3. [INFO]
  4. [INFO]
  5. [INFO] --- fabric8-maven-plugin:3.5.37:deploy (default-cli) @ k8sgatewaydemo ---
  6. [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
  7. [INFO] Using namespace: default
  8. [INFO] Updating a Service from kubernetes.yml
  9. [INFO] Updated Service: target/fabric8/applyJson/default/service-k8sgatewaydemo.json
  10. [INFO] Using namespace: default
  11. [INFO] Updating Deployment from kubernetes.yml
  12. [INFO] Updated Deployment: target/fabric8/applyJson/default/deployment-k8sgatewaydemo.json
  13. [INFO] F8: HINT: Use the command `kubectl get pods -w` to watch your pods start up
  14. [INFO] ------------------------------------------------------------------------
  15. [INFO] BUILD SUCCESS
  16. [INFO] ------------------------------------------------------------------------
  17. [INFO] Total time: 16.538 s
  18. [INFO] Finished at: 2019-07-07T22:04:48+08:00
  19. [INFO] ------------------------------------------------------------------------

1.查看service和pod,确认一切正常:

  1. [root@minikube k8sgatewaydemo]# clear
  2. [root@minikube k8sgatewaydemo]# kubectl get service
  3. NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
  4. k8sgatewaydemo NodePort 10.97.94.238 <none> 8080:31352/TCP 129m
  5. kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 29d
  6. webdemo NodePort 10.106.98.137 <none> 8080:30160/TCP 145m
  7. [root@minikube k8sgatewaydemo]# kubectl get pod
  8. NAME READY STATUS RESTARTS AGE
  9. k8sgatewaydemo-6fbb79885c-r2jfn 1/1 Running 0 33s
  10. webdemo-c9f774b9-gsbgx 1/1 Running 0 32m

2.使用minikube命令取得webdemo服务对外暴露的地址:

  1. [root@minikube k8sgatewaydemo]# minikube service k8sgatewaydemo --url
  2. http://192.168.121.133:31352

可见外部通过地址:http://192.168.121.133:31352 即可访问到k8sgatewaydemo应用;

1.在浏览器输入地址:http://192.168.121.133: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的权限问题:

  1. 2019-07-06 04:46:40.042 WARN 1 --- [erListUpdater-1] c.n.l.PollingServerListUpdater : Failed one update cycle
  2. 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".
  3. at io.fabric8.kubernetes.client.dsl.base.OperationSupport.requestFailure(OperationSupport.java:476) ~[kubernetes-client-4.1.0.jar!/:na]
  4. at io.fabric8.kubernetes.client.dsl.base.OperationSupport.assertResponseCode(OperationSupport.java:413) ~[kubernetes-client-4.1.0.jar!/:na]
  5. at io.fabric8.kubernetes.client.dsl.base.OperationSupport.handleResponse(OperationSupport.java:381) ~[kubernetes-client-4.1.0.jar!/:na]
  6. at io.fabric8.kubernetes.client.dsl.base.OperationSupport.handleResponse(OperationSupport.java:344) ~[kubernetes-client-4.1.0.jar!/:na]
  7. at io.fabric8.kubernetes.client.dsl.base.OperationSupport.handleGet(OperationSupport.java:313) ~[kubernetes-client-4.1.0.jar!/:na]
  8. at io.fabric8.kubernetes.client.dsl.base.OperationSupport.handleGet(OperationSupport.java:296) ~[kubernetes-client-4.1.0.jar!/:na]
  9. at io.fabric8.kubernetes.client.dsl.base.BaseOperation.handleGet(BaseOperation.java:794) ~[kubernetes-client-4.1.0.jar!/:na]
  10. at io.fabric8.kubernetes.client.dsl.base.BaseOperation.getMandatory(BaseOperation.java:210) ~[kubernetes-client-4.1.0.jar!/:na]
  11. at io.fabric8.kubernetes.client.dsl.base.BaseOperation.get(BaseOperation.java:177) ~[kubernetes-client-4.1.0.jar!/:na]
  12. at org.springframework.cloud.kubernetes.ribbon.KubernetesServerList
  13. .getUpdatedListOfServers(KubernetesServerList.java:75) ~[spring-cloud-kubernetes-ribbon-1.0.1.RELEASE.jar!/:1.0.1.RELEASE]
  14. at com.netflix.loadbalancer.DynamicServerListLoadBalancer.updateListOfServers(DynamicServerListLoadBalancer.java:240) ~[ribbon-loadbalancer-2.3.0.jar!/:2.3.0]
  15. at com.netflix.loadbalancer.DynamicServerListLoadBalancer$1.doUpdate(DynamicServerListLoadBalancer.java:62) ~[ribbon-loadbalancer-2.3.0.jar!/:2.3.0]
  16. at com.netflix.loadbalancer.PollingServerListUpdater$1.run(PollingServerListUpdater.java:116) ~[ribbon-loadbalancer-2.3.0.jar!/:2.3.0]
  17. at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) [na:1.8.0_191]
  18. at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:308) [na:1.8.0_191]
  19. at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(ScheduledThreadPoolExecutor.java:180) [na:1.8.0_191]
  20. at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:294) [na:1.8.0_191]
  21. at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [na:1.8.0_191]
  22. at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [na:1.8.0_191]
  23. at java.lang.Thread.run(Thread.java:748) [na:1.8.0_191]

处理方法是创建ServiceAccount对象,步骤如下:

1.创建名为fabric8-rbac.yaml的文件,内容如下:

  1. # NOTE: The service account `default:default` already exists in k8s cluster.
  2. # You can create a new account following like this:
  3. #---
  4. #apiVersion: v1
  5. #kind: ServiceAccount
  6. #metadata:
  7. # name: <new-account-name>
  8. # namespace: <namespace>
  9. ---
  10. apiVersion: rbac.authorization.k8s.io/v1beta1
  11. kind: ClusterRoleBinding
  12. metadata:
  13. name: fabric8-rbac
  14. subjects:
  15. - kind: ServiceAccount
  16. # Reference to upper's `metadata.name`
  17. name: default
  18. # Reference to upper's `metadata.namespace`
  19. namespace: default
  20. roleRef:
  21. kind: ClusterRole
  22. name: cluster-admin
  23. apiGroup: rbac.authorization.k8s.io

1.执行以下命令即可创建ServiceAccount对象:

kubectl apply -f fabric8-rbac.yaml

2.再在浏览器上继续刚才的验证,可以操作成功;

最后一个疑问

再回顾一下k8sgatewaydemo的开发过程,您会发现除了依赖spring-cloud-kubernetes对应的maven库,我们并没有显式调用spring-cloud-kubernetes相关的API或者做相关配置,就获取了所在kubernetes环境的原生服务,这是怎么回事呢?为何成本如此的低?答案就在《spring-cloud-kubernetes背后的三个关键知识点》一文中,推荐您回顾一下此文。

至此,spring-cloud-kubernetes框架下的SpringCloud Gateway开发实战就完成了,希望本文能帮助您更好的理解和使用spring-cloud-kubernetes,更加高效的将应用向容器化迁移

往期精彩文章

kubernetes面试题汇总

DevOps视频和资料免费领取

kubernetes技术分享-可用于企业内部培训

kubernetes系列文章第一篇-k8s基本介绍

kubernetes系列文章第二篇-kubectl

kubernetes集群中部署EFK日志管理系统

Kubernetes中部署MySQL高可用集群

Prometheus+Grafana+Alertmanager搭建全方位的监控告警系统-超详细文档

k8s1.18多master节点高可用集群安装-超详细中文官方文档

Kubernetes Pod健康检查-livenessProbe和readinessProbe

kubernetes pod生命周期管理-postStart和preStop

k8s中蓝绿部署、金丝雀发布、滚动更新汇总

运维常见问题汇总-tomcat篇

运维常见问题汇总-tomcat部署java项目大量close_wait解决方案

关于linux内核参数的调优,你需要知道

kubernetes持久化存储volume

使用ingress暴露kubernetes集群内部的pod服务

通过jenkins构建一个多分支的Pipeline项目

报警神器Alertmanager发送报警到多个渠道

jenkins+kubernetes+harbor+gitlab构建企业级devops平台

在jenkins中连接kubernetes集群

helm部署gitlab-包含完整Chart

通过编写k8s的资源清单yaml文件部署gitlab服务

技术交流群

了解更多关于Kubernetes、docker、DevOps、Linux、Python、Go、云计算、Spring Cloud、Docker等相关内容,获取更多资料和免费视频,可按如下方式进入技术交流群

                                  扫码加群????

微信:luckylucky421302

微信公众号

                                长按指纹关注公众号????


                               点击在看少个 bug????

参考:

  1. 作者:程序员欣宸
  2. 链接:https://juejin.im/post/5d7064875188255d3d29b508

至此,spring-cloud-kubernetes框架下的SpringCloud Gateway开发实战就完成了,希望本文能帮助您更好的理解和使用spring-cloud-kubernetes,更加高效的将应用向容器化迁移。

本文内容由网友自发贡献,转载请注明出处:https://www.wpsshop.cn/w/凡人多烦事01/article/detail/708547
推荐阅读
相关标签
  

闽ICP备14008679号