新一代的微服务架构 Service Mesh

新一代的微服务架构 Service Mesh

博客原文地址 (https://elfgzp.cn/2020/06/21/新一代的微服务架构 Service Mesh html

因为最近在工做中在作 Service Mesh 的落地项目,有很是多的感触,因此想写一篇文章来分享这个「新一代的微服务架构 Service Mesh」。git

笔者会从如下顺序开始分享:github

  • Part 1 从「单体应用架构」到「微服务架构」开始提及
  • Part 2 从「Docker」到 「K8s」
  • Part 3 从「边车模式」到「服务网格」
  • Part 4 用「Istio Demo」来说一个实际的应用场景

首先会从 「单体应用架构」 演进到 「微服务架构」 产生的问题开始提及,到本身做为开发人员感触最深的痛点。web

而后简单介绍如下今天的主角 Istio 的服务编排环境 Kubernetesdocker

最后从 Sidecar 这种设计,说到 Service Mesh,最后到咱们的主角 Istioapi

到正式的主角以前的铺垫会比较多,这是为了让大多数开发者都能理解。安全

本文大部份内容都整理自笔者的学习资料加上本身的一些总结和体会,你们最后能够从文末找到他们。服务器

Part 1「单体应用架构」到「微服务架构」开始提及

1.1 单体应用架构与微服务架构对比

「单体」「分布式」演进(也就是微服务化)的缘由我相信你们都很了解了。网络

由于业务量愈来愈大,咱们须要多台机器才能应对大规模的应用,因此须要垂直或者水平拆分业务系统,让其变成一个分布式的架构架构

从上面的表格咱们能够看到,分布式系统虽然有一些优点,但也存在一些问题。

  • 架构设计变得复杂。
  • 部署单个服务会比较快,可是若是一次部署须要多个服务,流程会变得复杂。
  • 系统的吞吐量会变大,可是响应时间会变长。
  • 运维复杂度会由于服务变多而变得很复杂。
  • 架构复杂致使学习曲线变大。
  • 测试和查错的复杂度增大。
  • 技术多元化,公司中可能会有多个技术栈,这会带来维护和运维的复杂度。
  • 管理分布式系统中的服务和调度变得困难和复杂。

做为业务开发人员最直观的感觉

  • 接口为何这么慢,明明只依赖了一个服务。我须要更新个人服务,可是哪些服务依赖了个人服务,此次更新会对哪些服务形成影响。
  • 我须要在代码框架层编写客户端接入监控、日志、链路追踪、告警、健康检查等各类各样非业务相关的代码
  • 测试很不方便,测试一个服务须要全部依赖的服务,测试环境资源紧张。
  • ...

1.2 微服务架构的痛点和须要解决的问题

总结来讲,微服务架构有这些痛点和须要解决的问题:

  • 服务多,服务之间的依赖难以管理。
  • 服务之间的版本管理,不一样版本的服务可能会有兼容性的问题。
  • 须要对总体架构监控,快速发现问题。
  • 资源调度管理。
  • 须要作流量控制。负载均衡、服务路由、熔断、降级、限流、灰度发布等流量相关的控制。

图片引用自 《左耳听风 - 分布式系统技术栈》

针对这么多的须要去解决和处理的问题。

引出了咱们今天的主角 Istio

在介绍咱们今天的主角 Istio 以前,先简单介绍一下它的服务编排环境 Kubernetes。经过 Docker 以及其衍生出来的 Kubernetes 之类的软件或解决方案,大大地下降了作上面不少事情的门槛。

Part 2「Docker」到 「K8s」

2.1 Docker 容器的本质

Docker 相信你们都很是了解了,因此这里我就从 Docker 过分讲到 k8s

Docker 容器这个听起来玄而又玄的概念,其实是在建立容器进程时,指定了这个进程所须要启用的一组 Namespace 参数。这样,容器就只能“看”到当前 Namespace 所限定的资源、文件、设备、状态,或者配置。而对于宿主机以及其余不相关的程序,它就彻底看不到了。

int pid = clone(main_function, stack_size, CLONE_NEWPID | SIGCHLD, NULL);

咱们知道,在 Linux 系统中建立线程的系统调用是 clone(),就像这样。而当咱们用 clone() 系统调用建立一个新进程时,就能够在参数中指定 CLONE_NEWPID 参数。这时,新建立的这个进程将会“看到”一个全新的进程空间,在这个进程空间里,它的 PID1。之因此说“看到”,是由于这只是一个“障眼法”,在宿主机真实的进程空间里,这个进程的 PID 仍是真实的数值,好比 100

因此说,容器,实际上是一种特殊的进程而已。

感兴趣的同窗能够阅读 《本身动手写 Docker》 和尝试一下书中的代码。

2.2 K8s 最小调度单位 Pod

我花了不少精力去学习 Linux 容器的原理、理解了 Docker 容器的本质,终于, Namespace 作隔离, Cgroups 作限制, rootfs 作文件系统” 这样的“三句箴言”能够朗朗上口了。

为何 Kubernetes 又忽然搞出一个 Pod 来呢?

这里提一个概念: Pod, 是 Kubernetes 项目中最小的 API 对象。若是换一个更专业的说法,咱们能够这样描述: PodKubernetes 项目的原子调度单位。

这里经过一个实际的例子来讲明:

咱们经过 pstree 查看操做系统中运行的进程,进程并非“孤苦伶仃”地独自运行的,而是以进程组的方式,“有原则地”组织在一块儿。

好比,这里有一个叫做 rsyslogd 的程序,它负责的是 Linux 操做系统里的日志处理。能够看到, rsyslogd 的主程序 main, 和它要用到的内核日志模块 imklog 等,同属于 1632 进程组。这些进程相互协做,共同完成 rsyslogd 程序的职责。

若是说 「Docker 容器」的其实就是一个「特殊的进程」。

那么「K8s」就能够理解成操做系统。

Kubernetes 所作的,其实就是将 “进程组” 的概念映射到了容器技术中,并使其成为了这个云计算 “操做系统” 里的 “原子调度单位”

不过,相信此时你可能会有第二个疑问:

对于初学者来讲,通常都是先学会了用 Docker 这种单容器的工具,才会开始接触 Pod。而若是 Pod 的设计只是出于调度上的考虑,那么 Kubernetes 项目彷佛彻底没有必要非得把 Pod 做为“原子调度单位”吧?

首先,关于 Pod 最重要的一个事实是:它只是一个逻辑概念

具体的说: Pod 里的全部容器,共享的是同一个 Network Namespace,而且能够声明共享同一个 Volume

那这么来看的话,一个有 AB 两个容器的 Pod,不就是等同于一个容器(容器 A)共享另一个容器(容器 B)的网络和 Volume ?这好像经过 docker run --net --volumes-from 这样的命令就能实现,就像这样。

可是,你有没有考虑过,若是真这样作的话,容器 B 就必须比容器 A 先启动,这样一个 Pod 里的多个容器就不是对等关系,而是拓扑关系了。

因此,在 Kubernetes 项目里, Pod 的实现须要使用一个中间容器,在这个 Pod 中,中间容器永远都是第一个被建立的容器,而其余用户定义的容器,则经过 Join Network Namespace 的方式,与 中间容器关联在一块儿。

图片引用自 《Service Mesh 实战:用 Istio 软负载实现服务网格 3.1.3 Pause 容器》

图片引用自 《深刻剖析Kubernetes - 为何咱们须要 Pod》

如上图所示,这个 Pod 里有两个用户容器 AB,还有一个中间容器容器。很容易理解,在 Kubernetes 项目里,中间容器必定要占用极少的资源,因此它使用的是一个很是特殊的镜像,叫做: k8s.gcr.io/pause。这个镜像是一个用汇编语言编写的、永远处于“暂停”状态的容器,解压后的大小也只有 100~200 KB 左右。

这里就再也不深刻说明了,感兴趣的能够点击图片连接,或者在文章末尾我列出的参考资料。

其中 Pod 的一个重要的特性,它的全部容器都共享同一个 Network Namespace。这就使得不少与 Pod 网络相关的配置和管理,也均可以交给 Sidecar 完成,而彻底无须干涉用户容器。

这里最典型的例子莫过于 Istio 这个微服务治理项目了。

接下来就从 SidecarService Mesh 来一步一步介绍 Istio 的设计思想。这里提到的 Sidecar 究竟是什么呢, Sidecar 在国内翻译为边车模式,这个翻译真的很形象。

Part 3「边车模式」到「服务网格」

3.1 边车模式

所谓的边车模式,对应于咱们生活中熟知的边三轮摩托车。

图片引用自 《左耳听风 - 管理设计篇“边车模式”》

咱们能够经过给一个摩托车加上一个边车的方式来扩展示有的服务和功能。这样能够很容易地作到 "控制 ""逻辑" 的分离。

也就是说,咱们不须要在服务中实现控制面上的东西,如监视、日志记录、限流、熔断、服务注册、协议适配转换等这些属于控制面上的东西,而只须要专一地作好和业务逻辑相关的代码,而后,由“边车”来实现这些与业务逻辑没有关系的控制功能。

图片引用自 《左耳听风 - 管理设计篇“边车模式”》

那最终这个 Sidecar 的效果就会像上图所示。

那么在 Istio 中, [Envoy](https://github.com/envoyproxy/envoy) 就是默认的 Sidecar。它与服务容器在同一个 Pod 中,与服务容器共享同一个 Network Namespace,接管全部通过服务容器的流量。

图片引用自 《Kubernetes Istio Canary Deployment》

3.2 服务网格

而后, Sidecar 集群就成了 Service Mesh。图中的绿色模块是真实的业务应用服务蓝色模块则是 Sidecar, 其组成了一个网格。而咱们的应用服务彻底独立自包含,只须要和本机的 Sidecar 依赖,剩下的事全交给了 Sidecar

图片引用自 《左耳听风 - 管理设计篇之“服务网格”》

Service Mesh 这个服务网络专一于处理服务和服务间的通信。其主要负责构造一个稳定可靠的服务通信的基础设施,并让整个架构更为的先进和 Cloud Native。在工程中, Service Mesh 基原本说是一组轻量级的服务代理和应用逻辑的服务在一块儿,而且对于应用服务是透明的

说白了,就是下面几个特色。

  • Service Mesh 是一个基础设施
  • Service Mesh 是一个轻量的服务通信的网络代理
  • Service Mesh 对于应用服务来讲是透明无侵入的。
  • Service Mesh 用于解耦和分离分布式系统架构中控制层面上的东西。

3.3 Istio 与 Service Mesh

咱们今天的主角 Istio,它的伟大之处不仅是在设计自己,而是在于它是一个兼容并包的生态。它为整个行业提供了一种全新的开发及运维的方式。

图片引用自 zhaohuabing/istio-practice

微服务架构在网络链路上还有不少待解决的点,如链路跟踪、分布式日志、监控报警、压测演练、故障注入等。若让 Istio 官方来实现全部的功能,不只耗时,还会让整个系统变得很是臃肿。

接下来就用 Istio 的官方 Demo 来说一个实际的应用场景。

Part 4 用「Istio Demo」来说一个实际的应用场景

这部分会用 Istio 官方的 Demo 来演示,因此本文的大部份内容均可以在官方文档中找到。

若是有感兴趣的同窗能够跟着这个 Demo 来实践,可是可能须要一个 K8s 集群,这里推荐使用 Google Cloud Platform 的免费试用服务 GCP Free Tier - Free Extended Trials and Always Free

固然若是想本身折腾搭建 K8s 集群的同窗能够参考笔者的这篇文章 「K8s 学习日记」Kubeadm 部署 kubernetes 集群

可是笔者仍是建议使用谷歌的服务,体验云原生的方式。

4.1 Istio Demo「Bookinfo 应用」服务架构

Bookinfo 应用分为四个单独的微服务:

  • productpage. 这个微服务会调用 details 和 reviews 两个微服务,用来生成页面。
  • details. 这个微服务中包含了书籍的信息。
  • reviews. 这个微服务中包含了书籍相关的评论。它还会调用 ratings 微服务。
  • ratings. 这个微服务中包含了由书籍评价组成的评级信息。

reviews 微服务有 3 个版本:

  • v1 版本不会调用 ratings 服务。
  • v2 版本会调用 ratings 服务,并使用 1 到 5 个黑色星形图标来显示评分信息。
  • v3 版本会调用 ratings 服务,并使用 1 到 5 个红色星形图标来显示评分信息。

下图展现了这个应用的端到端架构。

图片引用自 《 ISTIO 文档示例 BOOKINFO 应用》

对 Reviews-v二、Reviews-v3 服务进行测试

在实际的应用场景中,咱们当前发布了两个 Reviews 服务的 feature 版本 v2v3 版本。可是若是须要对这些服务进行测试。

为了开发人员在测试本身开发的 Review 服务不受影响,咱们可能须要部署多个完整的 Bookinfo 应用Product pageRatingsDetails 的服务都须要部署,以下图所示 。

官方的 BookInfo 中的微服务数量仍是比较少的,在实际的场景中,一个完整的系统可能会有成百上千个微服务共同支撑和运行,若是为了开发测试方便就须要庞大的服务器资源提供给微服务进行部署,这也是目前笔者公司的一个痛点。

利用 Istio 对流量进行控制

在官方的 demo 中,有这样一个例子。

未来自名为 Jason 的用户的全部流量路由到服务 reviews:v2。将请求头中 end-user 值为 jason

的全部请求指向 reviews:v2

正常来讲,这样的功能应该须要在具体语言的 Web 框架层进行实现,可是因为 IstioSidecar 接管了全部的流量,这个功能就在 Istio 中已经集成了。

对于开发人员来时也就是简单的一个配置和一行命令:

$ kubectl apply -f samples/bookinfo/networking/virtual-service-reviews-test-v2.yaml
$ kubectl get virtualservice reviews -o yaml
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: reviews
  ...
spec:
  hosts:
  - reviews
  http:
  - match:
    - headers:
        end-user:
          exact: jason
    route:
    - destination:
        host: reviews
        subset: v2
  - route:
    - destination:
        host: reviews
        subset: v1

Istio 的流量控制放到实际的应用场景中时,测试环境就只须要一套完整的服务,和一些须要测试的不一样版本的服务了。

固然这只是其中一个应用场景,流量控制还能够用于 A/B 测试,灰度发布等。而且这只是 Istio 的其中一个功能。

笔者也不一一去介绍 Istio 的其余功能了,如:服务安全、链路追踪、网络拓扑、服务注册等等服务治理相关的功能,感兴趣的同窗能够阅读官方文档。

除了官方给出的 demo , 感兴趣的同窗还能够在这个网站上找到更多的例子,https://istiobyexample.dev/

结尾

以上就是笔者想分享的所有内容,在这个云计算时代,笔者相信 Service Mesh 将会成为微服务架构中的一个佼佼者,帮助咱们更好治理微服务架构。

参考文献

本文由博客一文多发平台 OpenWrite 发布!

相关文章
相关标签/搜索