spring cloud项目改造为spring-cloud-kubernetes项目_水中加点糖-CSDN博客

标签: | 发表时间:2021-06-20 16:39 | 作者:
出处:https://blog.csdn.net

本系列相关推荐文章

其他相关文章

之前的spring cloud项目都是用的eurake作的注册中心,但是在项目部署到kubernetes中时如果想用k8s特有的功能,往往会达不到预期的效果,比如之前演示的 采用rancher2+kubernetes+skywalking部署springcloud项目(五[istio蓝绿部署]-错误演示)就没有演示成功

感觉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项目来改造。原项目地址为:https://github.com/zhangxd1989/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 Kubernetes来替换

也就是直接将原来的eurake项目删掉,在以前的eurake客户端的项目中换成下面这个引用:

      <dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-kubernetes</artifactId>
</dependency>

Discovery Client implementation that resolves service names to Kubernetes Services.

加入kubernetes的负载均衡器

      <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也就不需要了。

      <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了

      <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组件

      <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>

当然对于fabric8插件生成的deployment.yml和service.yml也可以重写,在项目的src\main目录下新建fabric8目录,然后重写deployment.yml和service.yml就可以了。
readinessProbe

本地调试方法

安装第三方程序调试(太复杂不推荐)

对于如何在本地运行改造后由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的功能从而实现本地请求到本地,如下面这里的写的:

      @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配置的目的地址去

而后,配置文件就可以这样写了:

      local:
  feign:
    server:
      svcb-service:
        url: http://192.168.1.66:8070

但是上面这样写不是很灵活,最好还是设成读取系统的环境变量,则可以修改成如下的写法

      local:
  feign:
    server:
      svcb-service:
        url: ${FEIGN_URL_SVCBSERVICE:}

这样当系统配置了环境变量 FEIGN_URL_SVCBSERVICE后,就会读取环境变量的值了,如果系统环境变量中没有配置对应的值的话,则还是会从loadbalancer中请求对应的服务。

在windows中对于环境变量的修改可能通过setx命令进行新增或修改,用wmic命令可进行删除
示例如下:

      //新增或修改值
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服务
网关正常
从结果中可以看出,服务访问是正常的

测试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列表

      # 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加端口就行了:

http://192.168.113.148:30860/hello

没有权限放问出错
呀额,访问出错了,提示default这个namespace下的default这个serviceaccount没有权限,因为spring-cloud-kubernetes需要访问集群中的services列表,但现在没有给这个default的serviceaccount授权,那么在K8S严格的RBAC中就报错了。
解决办法就是给它加添加权限,为了方便直接执行超级命令(不建议使用):

      kubectl create clusterrolebinding permissive-binding \
  --clusterrole=cluster-admin \
  --user=admin \
  --user=kubelet \
  --group=system:serviceaccounts

给所有的账号都加上超级权限,这样就有权限了,或者将default这个serviceaccount给它绑定一个role

      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看一下

      [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

相关 [spring cloud 项目] 推荐:

spring cloud项目改造为spring-cloud-kubernetes项目_水中加点糖-CSDN博客

- -
(一)基础k8s yaml脚本发布. (二)helm+shell脚本优化大量冗余配置发布. (三)jenkins用户审核的流水化方式部署. (四)service mesh(istio)服务网格化发布. (五)istio对项目进行金丝雀部署. spring-cloud-kubernetes之开发环境搭建.

大话 Spring Cloud

- - IT瘾-dev
研究了一段时间spring boot了准备向spirng cloud进发,公司架构和项目也全面拥抱了Spring Cloud. 在使用了一段时间后发现Spring Cloud从技术架构上降低了对大型系统构建的要求,使我们以非常低的成本(技术或者硬件)搭建一套高效、分布式、容错的平台,但Spring Cloud也不是没有缺点,小型独立的项目不适合使用.

Spring Cloud限流详解 | Spring Cloud|周立

- -
限流往往是一个绕不开的话题. 本文详细探讨在Spring Cloud中如何实现限流. Zuul上实现限流是个不错的选择,只需要编写一个过滤器就可以了,关键在于如何实现限流的算法. 常见的限流算法有漏桶算法以及令牌桶算法. https://www.cnblogs.com/LBSer/p/4083131.html,写得通俗易懂,你值得拥有,我就不拽文了.

Spring Cloud Kubernetes指南

- -
当我们构建微服务解决方案时,SpringCloud和Kubernetes都是最佳解决方案,因为它们为解决最常见的挑战提供组件. 但是,如果我们决定选择Kubernetes作为我们的解决方案的主要容器管理器和部署平台,我们仍然可以主要通过SpringCloudKubernetes项目使用SpringCloud的有趣特性.

Spring Cloud 快速入门

- - IT瘾-tuicool
Spring Cloud 是一套完整的微服务解决方案,基于 Spring Boot 框架,准确的说,它不是一个框架,而是一个大的容器,它将市面上较好的微服务框架集成进来,从而简化了开发者的代码量. 本课程由浅入深带领大家一步步攻克 Spring Cloud 各大模块,接着通过一个实例带领大家了解大型分布式微服务架构的搭建过程,最后深入源码加深对它的了解.

Deploy the spring cloud project using jenkins

- - Telami
先简单记录下Jenkins部署maven聚合工程要点. Root pom配置成项目根目录的pom.xml. maven命令单独install 欲构建的项目. 选项后可跟随{groupId}:{artifactId}或者所选模块的相对路径(多个模块以逗号分隔). 表示同时处理选定模块所依赖的模块. 表示同时处理依赖选定模块的模块.

Spring Cloud Gateway(限流) | Wind Mt

- -
限流可以保障我们的 API 服务对所有用户的可用性,也可以防止网络攻击. 一般开发高并发系统常见的限流有:限制总并发数(比如数据库连接池、线程池)、限制瞬时并发数(如 nginx 的 limit_conn 模块,用来限制瞬时并发连接数)、限制时间窗口内的平均速率(如 Guava 的 RateLimiter、nginx 的 limit_req 模块,限制每秒的平均速率);其他还有如限制远程接口调用速率、限制 MQ 的消费速率.

快速突击 Spring Cloud Gateway

- - 掘金后端
认识 Spring Cloud Gateway. Spring Cloud Gateway 是一款基于 Spring 5,Project Reactor 以及 Spring Boot 2 构建的 API 网关,是 Spring Cloud 微服务生态的主要组件之一. Spring Cloud Gateway 主要负责接口请求的路由分发,并且支持对请求的安全验证,流量监控和流量控制等扩展操作.

Spring Cloud Gateway2.0实践报告

- - 掘金后端
你的点赞就是对我最大的支持. 原创:小姐姐味道(微信公众号ID:xjjdog),欢迎分享,转载请保留出处. 本文将从知识拓扑讲起,谈一下api网关的功能,以及spring cloud gateway的使用方法. 一、知识拓扑 (使用和原理) 二、网关的作用 三、Predicate,路由匹配 四、Filter,过滤器编写 五、自定义过滤器 六、常见问题 复制代码.

微服务框架Spring Cloud介绍 Part2: Spring Cloud与微服务

- - skaka的博客
之前介绍过 微服务的概念与Finagle框架, 这个系列介绍Spring Cloud.. Spring Cloud还是一个相对较新的框架, 今年(2016)才推出1.0的release版本. 虽然Spring Cloud时间最短, 但是相比我之前用过的Dubbo和Finagle, Spring Cloud提供的功能最齐全..