点击上方“芋道源码”,选择“设为星标”
管她前浪,还是后浪?
能浪的浪,才是好浪!
每天 10:33 更新文章,每天掉亿点点头发...
源码精品专栏
- 原创 | Java 2021 超神之路,很肝~
- 中文详细注释的开源项目
- RPC 框架 Dubbo 源码解析
- 网络应用框架 Netty 源码解析
- 消息中间件 RocketMQ 源码解析
- 数据库中间件 Sharding-JDBC 和 MyCAT 源码解析
- 作业调度中间件 Elastic-Job 源码解析
- 分布式事务中间件 TCC-Transaction 源码解析
- Eureka 和 Hystrix 源码解析
- Java 并发源码
来源:blog.csdn.net/puhaiyang/
article/details/107181685
- spring cloud改造为spring cloud kubernetes
- 去掉eurake注册中心
- 加入kubernetes的负载均衡器
- 替换配置中心
- 加入打包配置
- 本地调试方法
- 安装第三方程序调试(太复杂不推荐)
- 本地调用kubernetes中的服务
- 本地调用本地的服务(重点)
- 测试本地服务
- 测试k8s中的服务
- 部署spring-boot-cloud到k8s中
- 测试k8s中的spring-boot-cloud
大部分的网友,在使用 spring cloud 项目时都是用的 eurake 或 nacos 作的注册中心,但是在项目部署到 kubernetes 中时如果想用 k8s 特有的功能,往往会达不到预期的效果。
spring cloud 和 kubernetes 中有很多组件是类似的,比如 spring cloud 中的 eurake 与 k8s 中 etcd 的类似,spring cloud 中 zuul 和 gateway 与 k8s 中 ingress 或 istio 的类似,spring cloud config 与 k8s configmap 的类似等,对于许多类似的功能组件其实只用一个就行了,比如注册中心只需要用 k8s 的 etcd 就可以了,如果再用上 eurake 部署在 k8s 环境中就确实感觉有点没有必要。
鉴于目前的部署环境都是 kubernetes,为了不让组件重复,我决定将 spring cloud 项目改造成 spring cloud kubernetes 项目,为了方便,就以之前的练习项目 spring boot cloud 项目来改造。
「以下为将spring-boot-cloud项目由spring cloud组件改为spring cloud kubernetes组件的主要内容。」
主要参考官方文档:https://cloud.spring.io/spring-cloud-static/spring-cloud-kubernetes/1.1.3.RELEASE/reference/html/
spring cloud改造为spring cloud kubernetes
去掉eurake注册中心
去掉 eurake 注册中心,使用 kubernetes 的 etcd 来替换。当然不可能真的直接连 kubernetes的 etcd,而是用 DiscoveryClient for Kuberneteshttps://cloud.spring.io/spring-cloud-static/spring-cloud-kubernetes/1.1.3.RELEASE/reference/html/#discoveryclient-for-kubernetes
来替换
也就是直接将原来的 eurake 项目删掉,在以前的 eurake 客户端的项目中换成下面这个引用:
代码语言:javascript复制<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-kubernetes</artifactId>
</dependency>
Discovery Client implementation that resolves service names to Kubernetes Services.
加入kubernetes的负载均衡器
代码语言:javascript复制<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-kubernetes-ribbon</artifactId>
</dependency>
Ribbon client-side load balancer with server list obtained from Kubernetes Endpoints.
替换配置中心
也可以根据自己的需要将配置中心换在k8s的configmap,为了配置文件方便追溯,这里就不进行替换了,有需要的自行替换,如果要进行替换的话,那么原项目中的config-server也就不需要了。
代码语言:javascript复制<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-kubernetes-config</artifactId>
</dependency>
Load application properties from Kubernetes ConfigMaps and Secrets. Reload application properties when a ConfigMap or Secret changes.
加入打包配置
在 pom 中添加 fabric8 插件的打包配置,这样就可以不用自己写 k8s 的 deployment 和 servcie 了。
代码语言:javascript复制<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>
<!--docker需要开启远程访问-->
<dockerHost>http://haiyang.dockerhost.com:2375</dockerHost>
<enricher>
<config>
<fmp-service>
<type>NodePort</type>
</fmp-service>
</config>
</enricher>
<!--registry地址,用于推送镜像-->
<!-- <registry>ccr.ccs.tencentyun.com</registry>-->
<!--认证配置,用于私有registry认证,如果忘记了可以去阿里的registry查看-->
<authConfig>
<push>
<username>your usernmae</username>
<password>your password</password>
</push>
</authConfig>
</configuration>
</plugin>
</plugins>
</build>
同时,fabric8 插件生成的 deployment 还会自动生成 readinessProbe 和 livenessProbe。通过测试发现,readinessProbe 和 livenessProbe 探测生成的端口默认会读取application.yml 配置文件的端口(默认为8080),以及探测地址默认为:actuator/health,所以记得添加 actuator 组件
代码语言:javascript复制<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
当然对于 fabric8 插件生成的 deployment.yml 和 service.yml 也可以重写,在项目的srcmain
目录下新建 fabric8 目录,然后重写 deployment.yml 和 service.yml 就可以了。
基于 Spring Boot MyBatis Plus Vue & Element 实现的后台管理系统 用户小程序,支持 RBAC 动态权限、多租户、数据权限、工作流、三方登录、支付、短信、商城等功能。 项目地址:https://github.com/YunaiV/ruoyi-vue-pro
本地调试方法
安装第三方程序调试(太复杂不推荐)
对于如何在本地运行改造后由spring cloud kubernetes构成的项目,网上的大佬们说说可以通过安装Telepresence和MicroK8s来操作,我大致浏览了下上面两种感觉差别都差不多,都是通过网络代理转发啥的来实现的。但看了下感觉安装在windows上的话还是有点麻烦的,正因为太复杂了所以这种方式不是很推荐,尽管这种方式很牛逼,这里就不仔细研究了,感兴趣的话自行搜索学习即可。
本地调用kubernetes中的服务
将spring.cloud.kubernetes.ribbon.mode修改为service,然后再将对应的服务开放一个端口出来,放一个nodeport出来就可以直接调用了。其实在开发中很少会遇到需要通过本地调远程k8s中的服务的情况,这里就暂不演示了,感兴趣的话自己配置一下就行,还是比较简单的就是有点麻烦。当然,用Telepresence或MicroK8s这种软件来解决也是可以的
本地调用本地的服务(重点)
在开发中最常见的应该就是本地的服务与服务之前的调用了。为了方便快捷与简单,如果是spring-cloud-kubernetes的服务,目前推荐的服务调另一个服务的方式是通过修改feign或ribbion的配置的方式来进行调试。如果在项目中调用另一个服务是用的@FeignClient注解来实现的,那么就可以在@FeignClient注解中添加url参数来实现忽略name的功能从而实现本地请求到本地,如下面这里的写的:
代码语言:javascript复制@FeignClient(name = "svcb-service",url = "${local.feign.server.svcb-service.url:}",fallback = ServiceBClient.ServiceBClientFallback.class)
public interface ServiceBClient {
「其原理是因为FeignClient注解中url参数的优先级要高于name,如果url参数有配置值的话,那么则会忽略name的配置,从而实现跳过ribbion直接将请求转发到url配置的目的地址去」
而后,配置文件就可以这样写了:
代码语言:javascript复制local:
feign:
server:
svcb-service:
url: http://192.168.1.66:8070
但是上面这样写不是很灵活,最好还是设成读取系统的环境变量,则可以修改成如下的写法
代码语言:javascript复制local:
feign:
server:
svcb-service:
url: ${FEIGN_URL_SVCBSERVICE:}
这样当系统配置了环境变量「FEIGN_URL_SVCBSERVICE」 后,就会读取环境变量的值了,如果系统环境变量中没有配置对应的值的话,则还是会从loadbalancer中请求对应的服务。
在windows中对于环境变量的修改可能通过setx命令进行新增或修改,用wmic命令可进行删除 示例如下:
代码语言:javascript复制//新增或修改值
setx FEIGN_URL_SVCBSERVICE http://127.0.0.1:8070
//删除值
wmic ENVIRONMENT where "name='FEIGN_URL_SVCBSERVICE'" delete
由于idea和windows系统的原因,如果这样修改用户的环境变量需重启idea才能生效,比较快的方法是「在启动程序的时候直接在idea中指定对应的环境变量」 就可以了
idea中配置环境变量
测试本地服务
访问某一个服务
直接访问a服务,a服务会调用b服务,响应正常。
a服务正常
测试服务熔断
将b服务关了,测试熔断。
从响应结果中看出,返回了熔断的信息
测试本地gateway
通过localhost:8060/hello访问本地的网关服务,测试gateway会访问a服务,a服务会调用b服务。
网关正常
从结果中可以看出,服务访问是正常的
基于微服务的思想,构建在 B2C 电商场景下的项目实战。核心技术栈,是 Spring Boot Dubbo 。未来,会重构成 Spring Cloud Alibaba 。 项目地址:https://github.com/YunaiV/onemall
测试k8s中的服务
部署spring-boot-cloud到k8s中
有了fabric8插件后对于项目的打包和部署就方便多了,点两下就自动完成项目部署到k8s。
点「fabric8:build」 完成项目打包,此过程会将对应的项目把成镜像,如果要推送的到私服的话,点push即可。
点「fabric8:deploy」 会自动完成对应项目部署到k8s中,此过程会执行对应项目下的deployment.yml和service.yml。
fabric8部署k8s项目
测试k8s中的spring-boot-cloud
直接返回网关吧! 先找一下网关的访问地址是多少,执行kubectl get svc获取service列表
代码语言:javascript复制# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
config NodePort 10.100.4.179 <none> 30876:30876/TCP 6h44m
gateway NodePort 10.107.190.176 <none> 8060:30860/TCP 77m
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 6h46m
svca-service ClusterIP 10.105.127.17 <none> 8080/TCP 120m
svcb-service ClusterIP 10.103.100.234 <none> 8070/TCP 6h43m
从上面可以看出,30860是gateway暴露出来的端口,那么直接访问minikube机器的ip加端口就行了:
代码语言:javascript复制http://192.168.113.148:30860/hello
没有权限放问出错
呀额,访问出错了,提示default这个namespace下的default这个serviceaccount没有权限,因为spring-cloud-kubernetes需要访问集群中的services列表,但现在没有给这个default的serviceaccount授权,那么在K8S严格的RBAC中就报错了。解决办法就是给它加添加权限,为了方便直接执行超级命令(不建议使用):
代码语言:javascript复制kubectl create clusterrolebinding permissive-binding
--clusterrole=cluster-admin
--user=admin
--user=kubelet
--group=system:serviceaccounts
给所有的账号都加上超级权限,这样就有权限了,或者将default这个serviceaccount给它绑定一个role
代码语言:javascript复制kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
name: default-crb
subjects:
- kind: ServiceAccount
name: default
namespace: default
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: cluster-admin
之所有将cluster-admin绑定给default是因为cluster-admin拥有所有namespace的所有权限,具体的可以describe看一下
代码语言:javascript复制[root@control-plane ~]# kubectl describe ClusterRole/cluster-admin
Name: cluster-admin
Labels: kubernetes.io/bootstrapping=rbac-defaults
Annotations: rbac.authorization.kubernetes.io/autoupdate: true
PolicyRule:
Resources Non-Resource URLs Resource Names Verbs
--------- ----------------- -------------- -----
*.* [] [] [*]
[*] [] [*]
将上面的赋权的yml执行后再访问接口看一下执行结果,如果没有生效果的话,可以先将pod删除后,让它们自动重启,再次访问看下结果:
网关访问正常
本示例的代码地址为:https://github.com/puhaiyang/spring-boot-cloud
欢迎加入我的知识星球,一起探讨架构,交流源码。加入方式,长按下方二维码噢:
已在知识星球更新源码解析如下:
最近更新《芋道 SpringBoot 2.X 入门》系列,已经 101 余篇,覆盖了 MyBatis、Redis、MongoDB、ES、分库分表、读写分离、SpringMVC、Webflux、权限、WebSocket、Dubbo、RabbitMQ、RocketMQ、Kafka、性能测试等等内容。
提供近 3W 行代码的 SpringBoot 示例,以及超 4W 行代码的电商微服务项目。
获取方式:点“在看”,关注公众号并回复 666 领取,更多内容陆续奉上。
代码语言:javascript复制文章有帮助的话,在看,转发吧。谢谢支持哟 (*^__^*)