背景:

对于微服务的应用,Spring Cloud 和 Kubernetes 都声称自己是开发和运行微服务的最佳环境。如何将SpringCloud的Java微服务应用与Kubernetes相结合,一直是企业想实践却又觉得无法下手的痛点。

主要原因是两者是有很多重叠交叉部分,如下表格的对比:

关于SpringCloud

Springcloud Netfix 是最流行的SpringCloud框架,服务发现Eureka,熔断器Hystrix,网关Zuul,负载均衡Ribbon。

SpringCloud Alibaba也开源了一套微服务框架,可以替换SpringCloud Netfix,但并不能完全替换,如负载均衡仍然使用Ribbon。但是Netfix的注册中心Eureka可以被Nacos替换。

Nacos的作用:服务发现、分布式配置、动态DNS。

SpringCloud Alibaba还开源了Sentinel组件,负责流量控制、并发、熔断、过载保护。

OpenFeign rest 客户端。

Kubernetes

Kubernetes 是一个多语言的通用容器管理平台,对容器进行管理与调度。它提供的服务,如配置管理、服务发现、负载均衡、指标收集、日志聚合,都可以被各种语言使用。这允许在组织中拥有一个平台,可以被多个团队使用(包括使用 Spring 框架的 Java 开发人员),并服务于多种目的:应用程序开发、测试环境、构建环境(用于运行源代码控制系统、构建服务)。

本文将使用KubeSphere的Devops Pipeline部署一套SpringCloud微服务,然后使用脚本自动注册成KubeSphere微服务,启用流量治理功能。该微服务的架构如下:

  • 使用Euraka Server当作注册中心,以StatefulSet部署
  • 使用Springboot Gateway
  • 使用统一的配置中心

源码地址

使用Devops Pipeline流水线部署应用

  1. 创建workspace(test)/项目Namespace(kubesphere-springcloud-sample)

  2. 创建GIthub Credential、Devops Project 、Pipeline

运行Pipeline创建流水线:

流水线运行成功后,检查负载创建成功。

当所有的pod正常后,未注入sidecar,能正常访问页面:

但是此时的流量拓扑是个黑盒,不清楚具体的服务调用关系。

转化为KubeSphere微服务

执行脚本,完成转化

curl https://raw.githubusercontent.com/zackzhangkai/spring-microservices-sample/master/app.sh | bash 

app.sh脚本说明

  1. 默认为部署一个application,名为springcloud-microservice

  2. 使用inject.sh对deployment/statefulset注入sidecar,需要使用Istioctl

istioctl的安装方法:

curl -L https://istio.io/downloadIstio | ISTIO_VERSION=1.6.10 TARGET_ARCH=x86_64 sh -
cp istio-1.6.10/bin/istioctl /usr/local/bin

如下,已经全部加入了sidecar:

再次访问页面,可以看到拓扑图:

链路追踪

看注册中心中的的所有的服务状态:

Springcloud Swagger文档

总结:

  1. SpringCloud

启动代码中添加 @EnableEurekaServer 注解

@EnableEurekaServer
public class DiscoveryApplication {

	public static void main(String[] args) {
		new SpringApplicationBuilder(DiscoveryApplication.class).run(args);
	}

}
  1. 如何修改应用端口

java的应用端口,需修改profile文件,如:

当环境中有PORT环境变量的时候,使用PORT;否则使用8088端口。

看kubernetes.yaml的部署文件中的定义:

  1. 为什么Eureka使用Statefulset?

使用statefulset后,会为每个POD分配一个DNS,如

  1. 路由

/department
/employee
/organization/2
/organization/2/with-employees

写在最后

对于springcloud向微服务的转换,因为有很多功能重叠,但是生产上每多一个功能,就会多一个故障点。因此需要对重叠的部分进行精简:

如:网关部分,可以移除zuul网关,改用KubeSphere的网关,本质上是使用Nginx Ingress;服务注册可以使用K8s DNS 提供的服务发现功能,直接使用服务名来访问;配置中心可以直接使用K8s的configmap;负载均衡也无需hypitrix,可以直接使用ipvs提供的功能,使用服务名来访问即可。

如下面的开源项目,作者讲述了如何从springcloud转向Kubernetes微服务,以及做的相关改造:

https://github.com/fenixsoft/microservice_arch_kubernetes

    zackzhang 提两个小建议:

    1. 把 app.sh 稍作一点解释,方便用户理解脚本原理后,能复用到用户自己的 SpringCloud 服务上
    2. 总结 部分的 1 、2 感觉缺少上下文不易理解

    我刚安装的kubesphere3.0,,为什么我找不到创建流水线的操作