将Spring Cloud项目改造为Spring-cloud-kubernetes项目

简介: 将Spring Cloud项目改造为Spring-cloud-kubernetes项目
  • 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 客户端的项目中换成下面这个引用:

<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 就可以了。

微信图片_20220906163144.png

基于 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的功能从而实现本地请求到本地,如下面这里的写的:

@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中指定对应的环境变量」 就可以了

微信图片_20220906163330.png

idea中配置环境变量

测试本地服务

访问某一个服务

直接访问a服务,a服务会调用b服务,响应正常。

微信图片_20220906163404.png

a服务正常

测试服务熔断

将b服务关了,测试熔断。

微信图片_20220906163427.png

从响应结果中看出,返回了熔断的信息

测试本地gateway

通过localhost:8060/hello访问本地的网关服务,测试gateway会访问a服务,a服务会调用b服务。

微信图片_20220906163444.png

从结果中可以看出,服务访问是正常的

基于微服务的思想,构建在 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。

微信图片_20220906163518.png

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

微信图片_20220906163555.png

没有权限放问出错

呀额,访问出错了,提示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删除后,让它们自动重启,再次访问看下结果:

微信图片_20220906163613.png

网关访问正常

本示例的代码地址为:https://github.com/puhaiyang/spring-boot-cloud

相关实践学习
深入解析Docker容器化技术
Docker是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的Linux机器上,也可以实现虚拟化,容器是完全使用沙箱机制,相互之间不会有任何接口。Docker是世界领先的软件容器平台。开发人员利用Docker可以消除协作编码时“在我的机器上可正常工作”的问题。运维人员利用Docker可以在隔离容器中并行运行和管理应用,获得更好的计算密度。企业利用Docker可以构建敏捷的软件交付管道,以更快的速度、更高的安全性和可靠的信誉为Linux和Windows Server应用发布新功能。 在本套课程中,我们将全面的讲解Docker技术栈,从环境安装到容器、镜像操作以及生产环境如何部署开发的微服务应用。本课程由黑马程序员提供。 &nbsp; &nbsp; 相关的阿里云产品:容器服务 ACK 容器服务 Kubernetes 版(简称 ACK)提供高性能可伸缩的容器应用管理能力,支持企业级容器化应用的全生命周期管理。整合阿里云虚拟化、存储、网络和安全能力,打造云端最佳容器化应用运行环境。 了解产品详情: https://www.aliyun.com/product/kubernetes
相关文章
|
4月前
|
监控 Java API
Spring Boot 3.2 结合 Spring Cloud 微服务架构实操指南 现代分布式应用系统构建实战教程
Spring Boot 3.2 + Spring Cloud 2023.0 微服务架构实践摘要 本文基于Spring Boot 3.2.5和Spring Cloud 2023.0.1最新稳定版本,演示现代微服务架构的构建过程。主要内容包括: 技术栈选择:采用Spring Cloud Netflix Eureka 4.1.0作为服务注册中心,Resilience4j 2.1.0替代Hystrix实现熔断机制,配合OpenFeign和Gateway等组件。 核心实操步骤: 搭建Eureka注册中心服务 构建商品
806 3
|
2月前
|
负载均衡 Java API
《深入理解Spring》Spring Cloud 构建分布式系统的微服务全家桶
Spring Cloud为微服务架构提供一站式解决方案,涵盖服务注册、配置管理、负载均衡、熔断限流等核心功能,助力开发者构建高可用、易扩展的分布式系统,并持续向云原生演进。
|
3月前
|
应用服务中间件 Nacos nginx
黑马头条_SpringCloud项目阶段一:环境搭建(Mac版本)
本文为 Mac 用户介绍微服务项目环境搭建,含阿里云服务器用 Docker 装 Nacos 1.2.0,本地通过 brew 装 OpenJDK 8、Maven 3.6.1、Redis,Docker 部署 MySQL 5.7 并配字符集,及 Nginx 安装与反向代理设置,附命令与配置步骤。
263 4
黑马头条_SpringCloud项目阶段一:环境搭建(Mac版本)
|
8月前
|
前端开发 安全 Java
Spring Boot 便利店销售系统项目分包设计解析
本文深入解析了基于Spring Boot的便利店销售系统分包设计,通过清晰的分层架构(表现层、业务逻辑层、数据访问层等)和模块化设计,提升了代码的可维护性、复用性和扩展性。具体分包结构包括`controller`、`service`、`repository`、`entity`、`dto`、`config`和`util`等模块,职责分明,便于团队协作与功能迭代。该设计为复杂企业级应用开发提供了实践参考。
325 0
|
5月前
|
Java 关系型数据库 数据库连接
Spring Boot项目集成MyBatis Plus操作PostgreSQL全解析
集成 Spring Boot、PostgreSQL 和 MyBatis Plus 的步骤与 MyBatis 类似,只不过在 MyBatis Plus 中提供了更多的便利功能,如自动生成 SQL、分页查询、Wrapper 查询等。
485 3
|
5月前
|
Java 测试技术 Spring
简单学Spring Boot | 博客项目的测试
本内容介绍了基于Spring Boot的博客项目测试实践,重点在于通过测试驱动开发(TDD)优化服务层代码,提升代码质量和功能可靠性。案例详细展示了如何为PostService类编写测试用例、运行测试并根据反馈优化功能代码,包括两次优化过程。通过TDD流程,确保每项功能经过严格验证,增强代码可维护性与系统稳定性。
258 0
|
5月前
|
存储 Java 数据库连接
简单学Spring Boot | 博客项目的三层架构重构
本案例通过采用三层架构(数据访问层、业务逻辑层、表现层)重构项目,解决了集中式开发导致的代码臃肿问题。各层职责清晰,结合依赖注入实现解耦,提升了系统的可维护性、可测试性和可扩展性,为后续接入真实数据库奠定基础。
459 0
|
5月前
|
前端开发 Java API
酒店管理系统基于 JavaFX Spring Boot 和 React 经典项目重构实操
本文介绍了基于现代技术栈的酒店管理系统开发方案,整合了JavaFX、Spring Boot和React三大技术框架。系统采用前后端分离架构,JavaFX构建桌面客户端,React开发Web管理界面,Spring Boot提供RESTful API后端服务。核心功能模块包括客房管理和客户预订流程,文中提供了JavaFX实现的客房管理界面代码示例和React开发的预订组件代码,展示了如何实现客房信息展示、添加修改操作以及在线预订功能。
347 1
|
5月前
|
Java 应用服务中间件 Maven
第01课:Spring Boot开发环境搭建和项目启动
第01课:Spring Boot开发环境搭建和项目启动
836 0

推荐镜像

更多