spring-cloud-kubernetes与SpringCloud Gateway
本文是《spring-cloud-kubernetes实战系列》的第五篇,主要内容是在kubernetes上部署一个springcloud gateway应用,该应用使用了spring-cloud-kubernetes框架,可以将请求转发到kubernetes环境中的其他服务上;
系列文章列表
本文大纲
接下来的内容由以下几部分组成:
- 什么是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框架可以获取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应用;
- 在浏览器输入地址: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> <groupid>org.springframework.cloud</groupid> <artifactid>spring-cloud-dependencies</artifactid> <version>${spring-cloud.version}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencymanagement> <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>
上述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: {}
- 开发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实现路由逻辑;
- 配置文件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 http://192.168.121.133:31352
可见外部通过地址:http://192.168.121.133:31352 即可访问到k8sgatewaydemo应用;
- 在浏览器输入地址: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的权限问题:
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对象,步骤如下:
- 创建名为fabric8-rbac.yaml的文件,内容如下:
# note: the service account `default:default` already exists in k8s cluster. # you can create a new account following like this: #--- #apiversion: v1 #kind: serviceaccount #metadata: # name: <new-account-name> # namespace: <namespace> --- apiversion: rbac.authorization.k8s.io/v1beta1 kind: clusterrolebinding metadata: name: fabric8-rbac subjects: - kind: serviceaccount # reference to upper's `metadata.name` name: default # reference to upper's `metadata.namespace` namespace: default roleref: kind: clusterrole name: cluster-admin apigroup: rbac.authorization.k8s.io
- 执行以下命令即可创建serviceaccount对象:
kubectl apply -f fabric8-rbac.yaml
- 再在浏览器上继续刚才的验证,可以操作成功;
最后一个疑问
再回顾一下k8sgatewaydemo的开发过程,您会发现除了依赖spring-cloud-kubernetes对应的maven库,我们并没有显式调用spring-cloud-kubernetes相关的api或者做相关配置,就获取了所在kubernetes环境的原生服务,这是怎么回事呢?为何成本如此的低?
答案就在一文中,推荐您回顾一下此文。
至此,spring-cloud-kubernetes框架下的springcloud gateway开发实战就完成了,希望本文能帮助您更好的理解和使用spring-cloud-kubernetes,更加高效的将应用向容器化迁移。
欢迎关注我的公众号:程序员欣宸
推荐阅读
-
springboot2.0和springcloud Finchley版项目搭建(包含eureka,gateWay,Freign,Hystrix)
-
SpringCloud之服务注册与发现Spring Cloud Eureka实例代码
-
跟我学SpringCloud | 第十四篇:Spring Cloud Gateway高级应用
-
springcloud使用之服务的注册发现与消费
-
跟我学SpringCloud | 第三篇:服务的提供与Feign调用
-
SpringCloud-微服务的注册与发现Eureka
-
SpringCloud之Eureka:服务发布与调用例子
-
SpringCloud(二):服务的注册与发现(Eureka)
-
SpringCloud:1章 Eureka服务注册与发现
-
SpringCloud第二代实战系列:一文搞定Nacos实现服务注册与发现