基于 Kubernetes 的微服务项目设计与实现容器知识

  • 80

基于 Kubernetes 的微服务项目设计与实现

本文会从设计开始,设计一个简单的前后端分离的项目,并将它部署在 Kubernetes 集群上。期间我们将关注微服务和 Kubernetes 配合的各个方面,并且从系统的可用性,可靠性、强壮性、可扩展进行讨论,最终设计一个可以真正实用的系统。

微服务是一种设计思想,它并不局限于任何开发语言。在本例中我们选择 Java Spring Boot 框架来实现微服务。微服务之间的 RPC 方案也很多,我们这里选择 RESTful 这种最常见的方案。为了项目的简洁,项目也没有涉及数据库和缓存,配置中心相关的内容。我们主要注重项目的设计思想实践和项目改进。

 

第一章 微服务项目的设计

1.1 微服务设计的思想

首先我们简单地回顾一下微服务,微服务的定义当来自 Martin flowerler "Microservices a definition of this new architectural term" 一文,借用大佬的一张图 描述了微服务最本质的东西。

基于 Kubernetes 的微服务项目设计与实现

微服务把各个功能拆开了,每个模块的功能更加独立,也更加单一。每个模块都独立发展,可以说做到了功能的高内聚、低偶合。

 

基于 Kubernetes 的微服务项目设计与实现

再借一张,这样数据库也被彻底拆分开了。一个巨大复制的单体数据库也按照功能拆成了小的独立数据库。

微服务就是这么简单吗?

当然不是,里面有很多细节需要考虑,纸上得来终觉浅,绝知此事要躬行。这次让我们开始从 0 开始真正设计整套系统。

 

1.2 实践设计和改进
 

现在我们要设计一个最简单的微服务架构。为了更贴近真实的业务。我们假设这个系统是这样的。

基于 Kubernetes 的微服务项目设计与实现

图一

整个系统的前端是一个有着前后端分离站点。

 

  1. 用户访问了www.demo.com 这个前端站点,通过前端页面发起请求;

  2. www.demo.com 服务器将请求发往 a.demo.com;

  3. 然后 a.demo.com 再请求 b.demo.com;

  4. b.demo.com 再请求 c.demo.com;

  5. c.demo.com 将结果返回;

  6. 最终显示在前端站点,完成微服务的全套调用流程。

 

注意:一般业务系统在前端和微服务直接还存在一个网关部分,网关一般用于鉴权、请求分类、监控等功能。 这里因为比较简单,所以省略了这个部分。

 

最终,我们将这套架构将部署在 Kubernetes 上,开始真正的服务用户。

 

1.3 改进项目
 

从图一我们可以看到这是一个非常简单而单薄的架构,存在很多问题。我们需要不断地解决它们。

 

下面我们开始改进项目。

 

首先,我们要解决节点的可靠性。在图一所有的节点都只有一个实例,任何节点的崩溃都将造成项目无法运行,在真正的项目中这是不可接受的。

 

怎么解决呢?当然是多个实例。

 

1.3.1 加入多实例及注册中心

 

基于 Kubernetes 的微服务项目设计与实现

我们将各个模块的实例数目增加,多个实例才能保证整个系统的可靠性。如果一个实例有问题,我们还是可以其他相同的实例进行服务。

 

但是多个实例又带来一个问题,各个组件之间如何定位呢?

 

如果有 10 个 b.demo.com 实例,它的上下游又该如何找到它们呢?


解决方案之一是注册中心。注册中心解决的是应用之间的寻址问题。有了它,上下游之间的应用可以相互寻址,并且获知那些实例是可用的,应用挑选可用的实例进行工作。

 

注册中心的方案很多,有 Eureka、ZooKeeper、Console、Nacos 等等。关于讨论各种注册中心是 AP、CP 的区别、优劣的文章很多。这篇文章不是一篇微服务的开发教程,我们选择比较常见的 Eureka为演示的注册中心。

注意:在 Kubernetes 中部署微服务,对注册中心是没有任何限制的。所以不要被某些文章误导。按照这篇文章做,你完全可以做到代码零修改,直接在 Kubernetes 上运行。

 

1.3.2 监控系统 Metrics
 

在完成了注册中心的功能后,虽然整个系统可以运行了,我们会发现没有应用监控的情况下,我们对系统运转状态是完全摸黑的。这样相当于盲人骑马,非常危险。我们需要知道所有微服务运行的状态,必须将各个微服务的状态监控起来,只有这样才能做到运筹帷幄,决胜千里。

基于 Kubernetes 的微服务项目设计与实现

在这里,我们选择使用 Prometheus 和 Grafana 这套监控组合。Prometheus + Grafana是一个比较常见的组合,基本是现在容器监控的标准配置。

 

在 Kubernetes 上,我们需要每个微服务的实例里开启监控数据到导出功能。同时利用 Prometheus 的自动发现功能,这样 Prometheus 可以将数据收集存储起来。

 

这里的数据包括每个应用的各项指标比如内存大小、200 错误数目、500 错误数目、JVM 里线程数量、GC时间大小。配合 Granfana 的聚合显示能力,我们可以直观地对整个系统有完整把控。

 

在应用开发过程中,我们只需要在代码里加入一个类库就可以实现信息的导出,不需要专门写代码。

 

1.3.3 日志系统 Logging
 

目前已经有了监控,日志还有存在的必要吗?

 

下面这个图就反映监控的3个维度。

 

 

基于 Kubernetes 的微服务项目设计与实现

这 3 个维度分别是 Mertics、Tracing 和 Logging。

 

Metrics  主要就是指刚才说的监控,它主要反映的就是一个聚合的数据。比如,今天 200 错误是多少,QPS 是多少?它指的是一段时间内的数据聚合。

 

Logging 就是我们现在讨论的日志。的它描述一些离散的(不连续的)事件。比如各个系统里的错误、告警。所以我们需要将日志收集起来。

 

Tracing 则关注单次请求中信息。我们关注请求的质量和服务可行性,是我们优化系统,排查问题的工具。

 

说到日志,在一个分布式系统,日志是非常重要的一环。因为微服务和容器的缘故,导致日志收集不是这么简单了。因为在 Kubernetes 里 容器的销毁和重启都是经常可能出现的,我们需要第一时间就把日志收集起来。

 

日志收集的方案有很多,有些方案是在本地启动一个收集进程,将落地的日志转发到 Kakfa 组件再转发日志中心。也有的方案是直接写到 Kafka 组件直接进入日志中心。两者各有优劣。

 

在这里,我们的方案选择了后者。我们简单地利用一个组件将日志直接打入 Kafka 组件。这种方案的好处是我们日志不再落地,日志 IO 被消除了,日志的存储也和容器做到了分离。我们再也不用担心日志 IO 对宿主机造成的系统压力了。

基于 Kubernetes 的微服务项目设计与实现

1.3.4 追踪系统 Tracing
 

刚才我们讨论了监控(Metric)和日志(Logging),还有一个维度就是追踪(Tracing)。

 

随着微服务的实例越来越多,有一个很现实的问题出现了:当大规模分布式集群出现,应用构建在不同的容器集群里、有可能布在几千台容器里,横跨多个不同的数据中心。因此,就需要一些可以帮助理解系统行为、用于分析性能问题的工具。

 

这该怎么解决呢?可以看看 Google 的论文 Google Dapper。

 

基于 Kubernetes 的微服务项目设计与实现

Google 论文描述一种解决办法,我们一般称作 APM(Application Performance Monitor)。它把一次调用加入一个独立无二的标记,并且在各个系统里透传标记,从而达到追踪整个消息处理过程的能力。

 

市面上大多数实现都是基于这一思想。可选方案的有很多,如 CAT、Pippiont、Zipkin、Skywalking。它们有需要代码注入的,有无注入的。关于它们的优劣也有很多文章评述。在这里我们选用 Zipkin。Zipkin 需要在项目中加入一个库,并不需要写代码。这对业务的入侵很少,非常方便。

基于 Kubernetes 的微服务项目设计与实现

1.3.5 流量控制

 

你认为这一切就完了吗?当然不是。

微服务里还有一项非常重要的功能流量控制,我们还没有做。当海量的请求来临的时候,我们可以用增加容器数量的办法来提高我们的服务能力。但是简单地添加实例是很危险的,因为整个系统的服务能力是被系统短板所限制的。简单地添加实例并不总能起到提高服务能力的作用,反而可能引起反作用。最终导致整个系统的崩溃。

 

我们对整个系统的负载容量是有一个设计的。当超出我们设计的能力时,我们需要对多余的请求说 No。相应的方案分别是熔断限流降级

 

目前 Java领域的这方面的 Hystrix、Sentinel 在这方面都做得很好。Sentinel 在阿里接受了考验,并且使用起来也很简单,所以我们选它。

 

现在我们在整个系统里加上一个流量控中心。这样一个基本完整的、可靠的、高可靠的系统就基本完成了。

 

基于 Kubernetes 的微服务项目设计与实现

 

注意:在实际开发中,其实还有最关键的配置中心(Apollo)、数据库(DB)、缓存(Redis)等组件、服务化网格。我们可以把这些组件暂时放在 Kubernetes 之外,仍然是可以起到同样的效果。

 

好了,设计部分先到这里,开始实现。

 

第二章 微服务项目的具体实现

 

从前端向后端开始实现。

 

2.1 前端站点

前端站点的逻辑很简单,就是显示一个页面,页面中有一个按键。

 

  1. 当你点击按键的时候,前端页面发起 AJAX 请求,访问前端站点本身的一个接口;

  2. 这个接口被 Nginx代理,转发到 a.demo.com 微服务上;

  3. a. demo.com 微服务再将请求转发到 b. demo.com;

  4. b. demo.com 再将请求转发到 c. demo.com;

  5. 最终将结果返回给前端;

  6. 前端站点再将结果显示在页面上。

 

我们通过结果显示就能知道这次请求通过了哪些服务器,每台服务器的服务运行时间大概是多少。

 

前端站点代码大体如下:

 

基于 Kubernetes 的微服务项目设计与实现

然后看 a、b、 c 应用部分的 Java 代码,这就是个普通的多模块 Maven 项目。

 

基于 Kubernetes 的微服务项目设计与实现

项目很简单,分成了 3 个部分。

 

  • 一个是注册中心,也就是利用 Eureka 实现注册中心服务;

  • 另一个则是基础库项目,大部分功能都在这里实现;

  • 最后则是各个微服务项目,微服务项目只需要简单调用基础库就能完成。

 

2.2 注册中心

注册中心的代码非常简单,只需要加一个简单的声明。

 

基于 Kubernetes 的微服务项目设计与实现

这是注册中心的配置文件,在 Kubernetes 集群里运行时,我们会运行 3 个节点组成高可用的注册中心集群。

 

这时这个配置项需要相应的修改。

 

基于 Kubernetes 的微服务项目设计与实现

2.3 基础库

 

基于 Kubernetes 的微服务项目设计与实现

基于 Kubernetes 的微服务项目设计与实现

基于 Kubernetes 的微服务项目设计与实现

在基础库项目里,我们将很多的依赖都放在里面。这样应用项目只需要简单依赖基础库就可以,能够做到统一修改。

 

同时我们也可以看到,大部分依赖库只需要加入就可以,并不需编写代码就可以工作。这让开发工作变得轻松。

 

基于 Kubernetes 的微服务项目设计与实现

对于微服务的返回结果,我们做了一些美化格式。这样可以比较容易检查结果。

 

基于 Kubernetes 的微服务项目设计与实现

简单定义了一些返回的结构。可以通过这些结构,微服务可以把处理时的时间戳,线程号,实例 IP 这些信息返回出来。

基于 Kubernetes 的微服务项目设计与实现

基础模块的日志实现,从 Github 找的例子简单地进行了修改。这时我们利用logback.xml 的配置,可以选择我们是把日志写入本地磁盘还是直接写入 Kafka。

 

注意:这部分的实现比较简单,不要用于生产。

 

基于 Kubernetes 的微服务项目设计与实现

基于 Kubernetes 的微服务项目设计与实现

基于 Kubernetes 的微服务项目设计与实现

2.4 a.demo.com,b.demo.com,c.demo.com 应用实现

 

基于 Kubernetes 的微服务项目设计与实现

实现很简单,只是简单地调用基础库就可以了。

 

注意:每个应用需要实现一个探活接口 /hs。这样 Kubernetes 系统可以通过这个接口来探活。获知你这个应用是不是准备好了,能不能接入流量。否则应用可能还在启动过程中,但是流量已经接入了,那么肯定会出问题。

 

基于 Kubernetes 的微服务项目设计与实现

在每个应用的配置里,我们都预置了各个配置的项目。在本地运行的时候,我们可以填注入本地的配置,在 Kubernetes 里以容器运行,我们可以利用 yaml 来动态地修改它们,做到两种情况下完全兼容。

第三章 Kubernetes 部署

 

在完成应用的编写后,我们需要安装 Kubernetes 系统了。果已经有 Kubernetes 集群,可以直接跳过这个部分看下一章。

除了 Kubernetes 集群以外,你还需要 Prometheus 和 Grafana 这样的监控组件。所以这里我推荐一个牛逼的安装工具,和所有现有的 Kubernetes 安装工具比,它是最好的,没有之一。它的名字是 K8Seasy,优点在于:

 

  1. 可以一键安装整体 Kubernetes 系统,无需了解任何背景知识;

  2. 所有的镜像都已经内置,不会因为下载镜像失败而导致失败;

  3. 安装支持各种不同版本 Kubernetes 版本;

  4. 安装的服务是二进制版本的非容器版本,稳定高效;

  5. 支持安装 3 节点 高可用的生产环境集群。

3.1 安装过程
 

下载 K8Seasy。

 

官方主页:https://github.com/xiaojiaqi/K8seasy_release_page

 

基于 Kubernetes 的微服务项目设计与实现

演示的安装动画,安装就是这么简单。

 

基于 Kubernetes 的微服务项目设计与实现

安装下载页:http://dl.K8seasy.com/

 

基于 Kubernetes 的微服务项目设计与实现

将 3 个安装文件都下载下来, 其中 pack.2020.10.02.bin 和installer 都是安装文件。kubernetes-server-linux-amd64.tar.gz 是kubernetes 的官方软件包,你可以自己选择一个最新的版本。

如果要选择一个其他版本的 Kubernetes 可到这里选择。

 

基于 Kubernetes 的微服务项目设计与实现

基于 Kubernetes 的微服务项目设计与实现

基于 Kubernetes 的微服务项目设计与实现

安装的过程很简单,两条命令即可。这里我们以需要安装 Kubernetes 的网络为  192.168.2.0,Master 主机 192.168.2.50 为例。

 

第 1 步,创建密钥。

 

 
sudo ./installer --genkey -hostlist=192.168.2.1

基于 Kubernetes 的微服务项目设计与实现

第 2 步,创建集群。
 
 
sudo ./installer   -kubernetestarfile kubernetes-server-linux-amd64v1.18.2.tar.gz -masterip 192.168.2.50

 

稍等一会儿 就能看到类似如下输出:

 

基于 Kubernetes 的微服务项目设计与实现

就这么简单。一个 Kubernetes 已经装好了。此时相关的所有监控已经被完全安装好了。

 

第 3 步,配置各项监控。
 

以 Master 节点为 192.168.2.50 为例。输入 http://192.168.2.50:10000 可以直接打开 Dashboard,对整个集群有一个全面了解

 

基于 Kubernetes 的微服务项目设计与实现

打开 http://192.168.2.50:8080  可以直接访问 Alertmanager。

 

基于 Kubernetes 的微服务项目设计与实现

打开 http://192.168.2.50:8081 你可以直接使用 Grafana(用户 admin,密码 admin)。

 

基于 Kubernetes 的微服务项目设计与实现

基于 Kubernetes 的微服务项目设计与实现

打开 http://192.168.2.50:8082 可以访问 Prometheus.

基于 Kubernetes 的微服务项目设计与实现

所有的配套都已经安装好了。

 

第 4 步,配置多套环境监控。
 

这一切就完了吗?当然不是。

 

为了支持多集群管理,再推荐一个工具。刚才我们说到直接使用 http://192.168.2.50:1000 这个页面可以直接管理整个集群,但是在公司里如果有多个集群,该如何管理呢?

 

别担心,K8Seasy 已经有对应的解决方案。

 

基于 Kubernetes 的微服务项目设计与实现

仔细看刚才的安装好的日志,里面提示你专门生成了一个 lens.kubeconfig 的配置文件,并且有一个域名和 IP 的对应表。这时候,你只需要首先在本地 Host 文件里加入这个对应关系。

 

基于 Kubernetes 的微服务项目设计与实现

然后去 https://Kuberneteslens.dev/,

 

基于 Kubernetes 的微服务项目设计与实现

下载一个 lens 的安装包。安装 lens 以后,你只需要将 lens.kubeconfig 导入到 lens 里。

 

基于 Kubernetes 的微服务项目设计与实现

导入完成后,你就可以远程管理这个集群了。这样有多个集群,你也可以只用一套 lens  进行管理了。

 

Lens 的界面优美、使用方便,快试试吧。

 

基于 Kubernetes 的微服务项目设计与实现

基于 Kubernetes 的微服务项目设计与实现

好了,Kubernetes 的安装完成了。当然了 K8Seasy 的功能是非常强大的,你可以用下面的命令提供帮助。

 
#查看帮助sudo ./installer -h#查看各种场景的安装帮助sudo ./installer -demo

基于 Kubernetes 的微服务项目设计与实现

基于 Kubernetes 的微服务项目设计与实现

第四章 微服务高可用部署及验证

 

Kubernetes 装好了,现在开始将微服务部署上去了。

 

我们刚才的代码只是Java 源码,我们还需要将它们编译成 Jar 包,然后再打成 Docker 镜像才能部署。这部分比较简单,所以我不演示如何完成了。我将相关的 Dockerfile 和 最终 Yaml 都放Github 里了(GitHub 地址在文章结尾)。

 

在开始开发时,我提到将日志写入 Kafka,所以有两套配置。一套使用了Kafka,一套没有使用 Kafka,请注意区别。因为没有 Kafka 比较容易实施,我这里就演示没有 Kafka 的版本。这样,所有工作只需要一台Linux 就可以保证将整个流程实施成功。

4.1  服务部署

依次运行每条部署 Yaml 的命令即可,不需要做其他的操作。

 

注意:镜像托管在 Docker-Hub,可能需要一定时间能下载。

 

运行后在 Dashboard 查看,你可以看到类似的信息,所有的服务都已经成功运行。

查看Dashboard:
 

基于 Kubernetes 的微服务项目设计与实现

此时修改本地的 Hosts。

 

基于 Kubernetes 的微服务项目设计与实现

因为我们的 Kubernetes 是支持 nginx-ingress 的,所以你可以直接访问 Master 的物理 IP 来访问这些服务,不需要做任何转换。

 

首先,我们可以打开 Dashboard,从中查到 Eureka 服务器的具体 IP。然后访问 Eurka  服务。

 

查看注册中心

在页面中你可以发现,在 Kubernetes 集群里,我们启动了 3 个 Eureka 服务,它们相互注册,组成了一个高可用集群。

 

基于 Kubernetes 的微服务项目设计与实现

其次,我们在 Grafana 中导入 JVM 的监控项目。

 

基于 Kubernetes 的微服务项目设计与实现

基于 Kubernetes 的微服务项目设计与实现

这样 Grafana 可以帮助我们把各个 Java 服务的具体状态做一个收集,完成我们需要的监控。

 

前端验证

此时,打开 http://www.demo.com 网页。点击页面上的 get 请求按键,模拟发出请求。随后我们就会发现页面里显示出的信息在不断变化。

 

基于 Kubernetes 的微服务项目设计与实现

在页面显示的内容里可以清楚地发现,我们的消息由不同实例里处理。假设有一个实例出现了故障不会影响当前业务。

 

基于 Kubernetes 的微服务项目设计与实现

 

好了,现在开始验证整个系统。

模拟验证

 

使用一个简单的脚本模拟每 3 秒从前端访问一次后端。

 

基于 Kubernetes 的微服务项目设计与实现

调用关系验证

首先打开 Zipkin,zipkin.demo.com。

 

基于 Kubernetes 的微服务项目设计与实现

点击具体的请求,可以查看到每次请求在内部的细节。

 

基于 Kubernetes 的微服务项目设计与实现

限流熔断验证

其次,打开 Sentinel 站点。这个站点可以监控,也可以对微服务进行限流、限速、熔断等操作(密码口令都是 sentinel)。

 

基于 Kubernetes 的微服务项目设计与实现

进入控制台后,可以发现所有的服务已经自动被发现,并存在于左边的菜单。

 

基于 Kubernetes 的微服务项目设计与实现

分别点开 a、b、c 3个服务,可以看到规律的周期访问,和我们的脚本的测试速度是一致的。

 

基于 Kubernetes 的微服务项目设计与实现

基于 Kubernetes 的微服务项目设计与实现

基于 Kubernetes 的微服务项目设计与实现

Sentinel 里面内含强大的监控、流控降级等功能。具体的使用可以慢慢学习,相信你一定会受益良多。

 

应用状态验证

打开 Grafana 的监控页,你可以查看所有应用的状态,包括 heap 大小、启动时间、错误数目等等。

 

基于 Kubernetes 的微服务项目设计与实现

通过这张图可以了解每个应用本身的状态,使用了多少内存,响应的代码是多少,JVM 使用情况。

 

相信此时你已经对各个组件的情况、监控都有了一个全面了解。一个基于 Kubernetes 的微服务架构已经开始工作了。

 

基于 Kubernetes 的微服务项目设计与实现

最后送一张常用的系统架构图,希望大家能通过本文对高可用微服务如何架设 Kubernetes 上有一个基本的了解,将本文讨论的东西用于实践。谢谢!

📚文章说明:
1、本文章链接失效后,请通过右下角企鹅QQ告知管理员,24小时内补链接,谢谢。点击下载说明了解。
2、天天精品分享的资源均通过网络公开合法渠道获取的,仅阅读交流测试使用,请在下载后24小时内删除。
3、版权归作者或出版社方所有,本站不对涉及的版权问题负法律责任。点击免责申明了解详情。
4、若版权方认为天天精品侵权,请联系客服QQ或发送邮件myttjp@163.com处理。
5、会员和精品豆系对搜集搬运、整理及网站运营做的友情赞助,非购买文件费用,敬请谅解。点击关于本站了解本站。
6、每位访客应尊重版权方的知识产权,支持版权方和出版社。

发表评论