spring-cloud-kubernetes与SpringCloud Gateway
Posted 程序员欣宸
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了spring-cloud-kubernetes与SpringCloud Gateway相关的知识,希望对你有一定的参考价值。
本文是《spring-cloud-kubernetes实战系列》的第五篇,主要内容是在kubernetes上部署一个SpringCloud Gateway应用,该应用使用了spring-cloud-kubernetes框架,可以将请求转发到kubernetes环境中的其他服务上;
系列文章列表
- 《spring-cloud-kubernetes官方demo运行实战》
- 《你好spring-cloud-kubernetes》
- 《spring-cloud-kubernetes背后的三个关键知识点》
- 《spring-cloud-kubernetes的服务发现和轮询实战(含熔断)》
- 《spring-cloud-kubernetes与SpringCloud Gateway》
- 《spring-cloud-kubernetes与k8s的configmap》
本文大纲
接下来的内容由以下几部分组成:
- 什么是SpringCloud Gateway
- SpringCloud Gateway实战参考
- kubernetes上的SpringCloud Gateway
- 实战环境信息
- 实战源码下载
- 开发webdemo
- 开发k8sgatewaydemo
- 解决权限问题
- 最后一个疑问
什么是SpringCloud Gateway
SpringCloud Gateway是SpringCloud技术栈下的网关服务框架,在基于SpringCloud的微服务环境中,外部请求会到达SpringCloud Gateway应用,该应用对请求做转发、过滤、鉴权、熔断等前置操作,一个典型的请求响应流程如下所示:
SpringCloud Gateway实战参考
如果您之前没有使用过SpringCloud Gateway,推荐您阅读《速体验SpringCloud Gateway》,有时间的话动手实战效果更佳,只需编写少量代码就能快速熟悉这个SpringCloud技术栈中非常重要的功能;
kubernetes上的SpringCloud Gateway
注意以下两个知识点:
- SpringCloud Gateway之所以能将外部请求路由到正确的后台服务上,是因为注册中心的存在,SpringCloud Gateway可以在注册中心取得所有服务的信息,因此它可以根据路径和服务的对应关系,将请求转发到对应的服务上;
- 如果您看过本系列的上一篇 《spring-cloud-kubernetes的服务发现和轮询实战(含熔断)》,您就知道spring-cloud-kubernetes框架可以获取kubernetes环境内的所有服务(这里说的服务就是kubernetes的service);
将以上两个知识点结合起来,于是可以推测:运行在kubernetes环境的SpringCloud Gateway应用,如果使用了spring-cloud-kubernetes框架就能得到kubernetes的service列表,因此可以承担网关的角色,将外部请求转发至kubernetes内的service上,最终到达对应的Pod;
架构如下图所示,请注意黄色背景的对话框,里面标识了关键操作:
至此,理论分析已经完成,我们来实战验证这个理论,接下来我们开发两个java应用:
- 先开发一个普通的web服务,名为webdemo,提供一个http接口;
- 再开发一个SpringCloud Gateway应用,名为k8sgatewaydemo;
环境信息
本次实战的环境和版本信息如下:
- 操作系统:CentOS Linux release 7.6.1810
- minikube:1.1.1
- Java:1.8.0_191
- Maven:3.6.0
- fabric8-maven-plugin插件:3.5.37
- spring-cloud-kubernetes:1.0.1.RELEASE
- spring cloud:Greenwich.SR2
- springboot:2.1.6.RELEASE
源码下载
如果您不打算写代码,也可以从GitHub上下载本次实战的源码,地址和链接信息如下表所示:
名称 | 链接 | 备注 |
---|---|---|
项目主页 | https://github.com/zq2599/blog_demos | 该项目在GitHub上的主页 |
git仓库地址(https) | https://github.com/zq2599/blog_demos.git | 该项目源码的仓库地址,https协议 |
git仓库地址(ssh) | git@github.com:zq2599/blog_demos.git | 该项目源码的仓库地址,ssh协议 |
这个git项目中有多个文件夹,本章的两个应用分别在webdemo和k8sgatewaydemo文件夹下;
下图红框中是webdemo应用的源码:
下图红框中是k8sgatewaydemo应用的源码:
下面是详细的编码过程;
开发webdemo
webdemo是个极其普通的spring boot应用,和SpringCloud没有任何关系;
- webdemo提供一个http接口,将请求header中名为extendtag的参数返回给请求方,controller类如下:
@RestController
@RequestMapping("/hello")
public class HelloController
@RequestMapping(value = "time", method = RequestMethod.GET)
public String hello(HttpServletRequest request)
return "hello, "
+ new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date())
+ ", extendtag ["
+ request.getHeader("extendtag")
+ "]";
- 启动类WebdemoApplication.java:
@SpringBootApplication
public class WebdemoApplication
public static void main(String[] args)
SpringApplication.run(WebdemoApplication.class, args);
- 要注意的是pom.xml,里面通过名为fabric8-maven-plugin的maven插件,将webdemo快速部署到minikube环境:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.6.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.bolingcavalry</groupId>
<artifactId>webdemo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>webdemo</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
<spring-boot.version>2.1.6.RELEASE</spring-boot.version>
<fabric8.maven.plugin.version>3.5.37</fabric8.maven.plugin.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>$spring-boot.version</version>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<!--skip deploy -->
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-deploy-plugin</artifactId>
<version>$maven-deploy-plugin.version</version>
<configuration>
<skip>true</skip>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>$maven-surefire-plugin.version</version>
<configuration>
<skipTests>true</skipTests>
<!-- Workaround for https://issues.apache.org/jira/browse/SUREFIRE-1588 -->
<useSystemClassLoader>false</useSystemClassLoader>
</configuration>
</plugin>
<plugin>
<groupId>io.fabric8</groupId>
<artifactId>fabric8-maven-plugin</artifactId>
<version>$fabric8.maven.plugin.version</version>
<executions>
<execution>
<id>fmp</id>
<goals>
<goal>resource</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
<profiles>
<profile>
<id>kubernetes</id>
<build>
<plugins>
<plugin>
<groupId>io.fabric8</groupId>
<artifactId>fabric8-maven-plugin</artifactId>
<version>$fabric8.maven.plugin.version</version>
<executions>
<execution>
<id>fmp</id>
<goals>
<goal>resource</goal>
<goal>build</goal>
</goals>
</execution>
</executions>
<configuration>
<enricher>
<config>
<fmp-service>
<type>NodePort</type>
</fmp-service>
</config>
</enricher>
</configuration>
</plugin>
</plugins>
</build>
</profile>
</profiles>
</project>
- 以上就是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] ------------------------------------------------------------------------
- 查看service和pod,确认一切正常:
[root@minikube webdemo]# kubectl get service
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 29d
webdemo NodePort 10.106.98.137 <none> 8080:30160/TCP 115m
[root@minikube webdemo]# kubectl get pod
NAME READY STATUS RESTARTS AGE
webdemo-c9f774b9-gsbgx 1/1 Running 0 3m13s
- 使用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:
至此,webdemo在minikue上已经正常运行,该开发gateway应用了;
开发k8sgatewaydemo
- 基于maven创建一个名为k8sgatewaydemo的springboot应用,pom.xml内容如下:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.6.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.bolingcavalry</groupId>
<artifactId>k8sgatewaydemo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>k8sgatewaydemo</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
<spring-boot.version>2.1.6.RELEASE</spring-boot.version>
<maven-checkstyle-plugin.failsOnError>false</maven-checkstyle-plugin.failsOnError>
<maven-checkstyle-plugin.failsOnViolation>false</maven-checkstyle-plugin.failsOnViolation>
<maven-checkstyle-plugin.includeTestSourceDirectory>false</maven-checkstyle-plugin.includeTestSourceDirectory>
<maven-compiler-plugin.version>3.5</maven-compiler-plugin.version>
<maven-deploy-plugin.version>2.8.2</maven-deploy-plugin.version>
<maven-failsafe-plugin.version>2.18.1</maven-failsafe-plugin.version>
<maven-surefire-plugin.version>2.21.0</maven-surefire-plugin.version>
<fabric8.maven.plugin.version>3.5.37</fabric8.maven.plugin.version>
<springcloud.kubernetes.version>1.0.1.RELEASE</springcloud.kubernetes.version>
<spring-cloud.version>Greenwich.SR2</spring-cloud.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-kubernetes-core</artifactId>
<version>$springcloud.kubernetes.version</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-kubernetes-discovery</artifactId>
<version>$springcloud.kubernetes.version</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-kubernetes-ribbon</artifactId>
<version>$springcloud.kubernetes.version</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-commons</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency部署 spring-cloud-kubernetes kubernetes-hello-world-example 失败
#yyds干货盘点#spring-cloud-kubernetes与k8s的configmap
#yyds干货盘点#spring-cloud-kubernetes背后的三个关键知识点
想了解 spring-cloud-kubernetes,那就先来实战一把官方demo