使用Open Service Mesh进行性能测试


上周微软刚刚发布了一款Service Mesh,这着实让我有点惊讶。

我们怀着异常兴奋的心情向大家介绍了Open Service Mesh(OSM),这是一款轻量、可扩展的#servicemesh,它实现了@SMI_spec并且是运行在@kubernetesio以及@EnvoyProxy上。欢迎来访:https://t.co/l6fy4OUorO
——Open Service Mesh (@openservicemesh) 2020年8月5日
Open Service Mesh(OSM)是一款使用Envoy proxy作为Sidecar,并根据Service Mesh接口(Service Mesh Interface)规范实现的Service Mesh。如果这些对你来说都不算什么,不要走开,在这篇博文,我们将向你展示OSM的实际应用。
o01.png

那么,我们先从头开始,讨论一下什么是Service Mesh。

什么是Service Mesh?

我还记得我第一次听说Service Mesh。那是2018年,位于加州的山景城,在一个炎热的8月的下午。我当时刚搬到美国才一个月,正盼望着能更好地融入这里的科技社区。那天下午,我骑着自行车去参加在山景城WSO2总部举行的会议。那次会议的主题是“Istio介绍”,而且当时的我根本不知道他们在聊什么。Google的Dan Curuli介绍了Istio及其所解决的问题。他做了一个非常棒的演示,当时我写了一篇博客分享我学到的一些经验。从那时起,Service Mesh和Istio越来越受欢迎,我很欣慰能从Dan那里了解到很多第一手信息。

那么,什么是Service Mesh呢?Service Mesh是帮助管理服务间通信的基础架构组件。换句话说,它是一种透明的技术,它能将应用程序代码中的某些服务间通信逻辑卸载到Service Mesh中。这种逻辑的一个很好的例子是调用API时的实例重试逻辑。如果没有Service Mesh,就必须将其编码到实际的代码中。通过Service Mesh,你将能够将重试逻辑卸载到Service Mesh中,并利用Service Mesh中的重试策略(例如Istio)。

Service Mesh通常在Kubernetes环境中使用,不过也可以在非Kubernetes环境中使用它。在Kubernetes集群中,Service Mesh通常使用Sidecar模式实现。Sidecar是一种被添加到应用Pod用以增加附加功能的容器,在本例中指的是Service Mesh功能。
o02.png

流量经由Service Mesh Sidecar,从而向应用程序添加功能

这种Sidecar代理可以包含很多内容。Envoy是一个很受欢迎的Sidecar选择,Istio也使用这个Sidecar (Open Service Mesh也是如此)。Envoy是Lyft最初开发的一个代理。Envoy在功能上与Nginx或HAProxy类似。然而,Envoy有一些明显的优势,包括高性能处理和集中的配置管理系统。Envoy不是唯一可以使用的Sidecar,其他选项包括Nginx或Linkerd2。通常,每个Service Mesh都有一个默认的/首选的Sidecar代理。

现在有很多非常流行的Service Mesh。Istio是最受欢迎的。Istio是Google、IBM和Lyft最初创建的一个项目。虽然它是最受欢迎的Service Mesh,但目前在开源社区中,关于Google为何要创建一个名为Open Usage Commons的新基金会来捐赠Istio,而不是直接将Istio捐赠给CNCF,还存在一些争议。Istio并不是唯一的Service Mesh。其他流行的Mesh包括Linkerd,Consul和Maesh。

Service Mesh领域仍处于早期阶段。每种Service Mesh都有自己的优缺点。然而,从一个Mesh切换到另一个Mesh并不简单。这是因为每个Mesh都有自己的配置语法。这就是SMI规范试图解决的问题。下一节就要探讨SMI规范。

SMI规范 (spec)

Service Mesh Interface(SMI)规范是在Kubernetes上运行的Service Mesh的标准接口。如果已经熟悉了Kubernetes中的Ingress资源,SMI是Service Mesh,Ingress是反向代理。意思就是,它是配置多个后端的标准方法。这样做的好处是,根本不用了解特定的实施细节,可以直接简单地使用SMI-spec来配置Service Mesh。

微软最初在2019年5月创建了SMI规范,并在2020年4月将该规范捐赠给了CNCF。现在,4个Service Mesh实现了SMI规范:
  • Istio(通过适配器)
  • Linkerd
  • Consul Connect(通过适配器)
  • Maesh


并且,现在又来了一个新的成员:Open Service Mesh。我们来看一下吧。

Open Service Mesh

Open Service Mesh(OSM)是一个新的Service Mesh,它使用Sidecar代理,并遵循SMI规范。虽然它刚刚公开没有多久,但从公网介绍可以看出,它已经可以支持一些特性了:
  • 轻松透明地为部署配置流量转移
  • 通过启用mTLS以源和目的证书在服务之间进行加密,以保护服务到服务的通信
  • 为服务定义和执行细粒度的访问控制策略
  • 对应用程序指标的调试和监控服务提供深入的可视化
  • 与外部证书管理服务/解决方案与可插入接口集成
  • 通过使用Envoy代理自动将Sidecar注入到Mesh上
  • 通过SMI和Envoy XDS API来处理简单和复杂的场景


那么,干嘛不去Kubernetes集群中安装一个OSM先试试呢?

开启OSM

在我的Azure上来安装一个OSM。OSM需要在v1.15.0或更高的Kubernetes集群才能运行,并需要一个config指向该集群。
o03.png

下一步就是下载OSM二进制文件,下面是我下载的v0.2.0版本,而且强烈建议大家先去GitHub查一下最新的版本。
wget https://github.com/openservicemesh/osm/releases/download/v0.2.0/osm-v0.2.0-linux-amd64.tar.gz
tar -xvzf osm-v0.2.0-linux-amd64.tar.gz
sudo mv linux-amd64/osm /usr/local/bin/osm
rm -rf linux-amd64

最后一步,安装OSM。
osm install

下面显示OSM已经安装好了。
o04.png

过程非常简单没什么可激动的。现在我们已经安装了OSM,我们可以搞一个应用demo,这个会比较令人兴奋!

使用OSM运行一个演示应用程序

基础配置

OSM背后的团队已经很好地创建了一个完整的演示应用程序(对于那些熟悉Istio的人来说,你们可能会在这里看到一个常见的主题)。我们先过一下。先创建几个命名空间并部署几个应用程序:
o05.jpg

演示应用程序的概要

从这个开始。首先,克隆OSM repo并导入到本地目录中。
git clone https://github.com/openservicemesh/osm.git
cd osm

现在,再创建4个命名空间,并将这4个命名空间加载到OSM:
for i in bookstore bookbuyer bookthief bookwarehouse; do kubectl create ns $i; done
for i in bookstore bookbuyer bookthief bookwarehouse; do osm namespace add $i; done

然后我们将部署这4个应用程序。它们的配置放在docs/example/manifest/apps/目录中。先看看目录里有什么。
o06.png

可以看到,有4个YAML文件定义应用程序,然后是一个traffic-split.yaml文件。我假设它包含了Service Mesh的配置。现在来研究一下该文件中的内容。
apiVersion: split.smi-spec.io/v1alpha2
kind: TrafficSplit
metadata:
name: bookstore-split
namespace: bookstore
spec:
service: bookstore.bookstore # <root-service>.<namespace>
backends:
- service: bookstore-v1
weight: 100

实际上,这就是SMI配置。正如所见,没有提到OSM的特定配置,这就是遵循了SMI规范。

现在来部署该文件夹中所有yaml文件,看看会发生什么。
kubectl create -f docs/example/manifests/apps/

o07.png

通过创建应用程序所创建的对象

在Kubernetes中创建了大量的对象。要查看已部署的实际应用程序,我们可以设置port forwarding并研究应用程序本身。建议在不同的终端窗口中完成此操作,这样你还可以继续使用本教程的主窗口。
cp .env.example .env
./scripts/port-forward-all.sh

这将使下面的endpoints能在你的本地主机上可用:


这些服务现在看起来是这样的:
o08.png

部署的前端并没有流量

流量允许

如果服务可以相互通信,我们应该会看到计数器增加。然而,现在这三种服务之间不允许有流量,这意味着没有书被买或偷。我们可以通过应用访问控制策略来改变这一点。这个示例策略存储在docs/example/manifest /access/目录中。在创建之前,先来看看这个:
kind: TrafficTarget
apiVersion: access.smi-spec.io/v1alpha2
metadata:
name: bookstore-v1
namespace: bookstore
spec:
destination:
kind: ServiceAccount
name: bookstore-v1
namespace: bookstore
rules:
- kind: HTTPRouteGroup
name: bookstore-service-routes
matches:
- buy-a-book
- books-bought
sources:
- kind: ServiceAccount
name: bookbuyer
namespace: bookbuyer
#- kind: ServiceAccount
#name: bookthief
#namespace: bookthief
---
apiVersion: specs.smi-spec.io/v1alpha3
kind: HTTPRouteGroup
metadata:
name: bookstore-service-routes
namespace: bookstore
spec:
matches:
- name: books-bought
pathRegex: /books-bought
methods:
- GET
headers:
- host: "bookstore.bookstore"
- "user-agent": ".*-http-client/*.*"
- "client-app": "bookbuyer"
- name: buy-a-book
pathRegex: ".*a-book.*new"
methods:
- GET
headers:
- host: "bookstore.bookstore"

在这个定义中有几个点:
  • 首先,bookthief服务帐户不允许做任何事情,因为那部分被注释掉了。

  • 其次,可以看到我们创建了两个对象:一个HTTPRouteGroup和一个TrafficTarget。
    • TrafficTarget将一组流量定义(规则)与分配给一组pods的服务标识关联起来。
    • 一个HTTPRouteGroup用来描述HTTP/1和HTTP/2流量。它列举了应用程序可以提供的路由。

  • 在我们的案例中,我们看到的是:
    • 我们正在创建一个到bookstore-v1的TrafficGroup,匹配两个HTTPRouteGroups。
    • 源现在只是bookbuyer的service账户,而不是小偷(因为他被注释掉了)。
    • 在下面,我们创建HTTPRouteGroups,解释流量流。


现在创建这个:
kubectl create -f docs/example/manifests/access/

一旦创建了访问策略,应该会看到计数器增加,这意味着书正在被买卖,但是还没有被偷。
o09.png

当流量开始流动时,计数器增加。

现在让我们启用“偷书贼”。为此,先来注释掉docs/example/manifests/access/traffic-access.yaml文件的这几行。
kind: TrafficTarget
apiVersion: access.smi-spec.io/v1alpha2
metadata:
name: bookstore-v1
namespace: bookstore
spec:
destination:
kind: ServiceAccount
name: bookstore-v1
namespace: bookstore
rules:
- kind: HTTPRouteGroup
name: bookstore-service-routes
matches:
- buy-a-book
- books-bought
sources:
- kind: ServiceAccount
name: bookbuyer
namespace: bookbuyer
- kind: ServiceAccount
name: bookthief
namespace: bookthief

重新部署TrafficTarget:
kubectl apply -f docs/example/manifests/access/traffic-access.yaml

o10.png

允许小偷也能进入书店

很快,就会看到bookthief的行动。
o11.png

小偷现在可以使用书店的服务了

快速回顾一下到目前为止我们所做的:
  1. 我们已经在集群里设置了OSM。
  2. 我们创建了4个命名空间,并将它们放到OSM的网格中。
  3. 我们创建了一个应用程序,发现流量在默认情况下被拦截。
  4. 我们使用TrafficTarget和HTTPRouteGroup对象创建了一个流量策略,以允许网格中特定的流量。


在演示的第二部分中,我们将创建书店的新版本(bookstore-v2),并且我们将能够将流量从一个服务引导到另一个服务。

流量分流(Traffic splitting)

本节,我们将部署书店的新版本,并缓慢地将所有流量引向它。首先,先部署书店的第二个版本。
kubectl apply -f docs/example/manifests/bookstore-v2/

在执行port-forwarding的终端窗口中,我们需要重启这个脚本,使port-forward到书店的第二个版本。

你可以看到柜台数量增加了,但是第二家书店没有卖任何书。这是因为TrafficSplit被配置为将100%的流量定向到主书店。我们可以通过检查该对象来证实这一点:
kubectl get trafficsplit bookstore-split -n bookstore

o12.png

所有的流量都走向了bookstore-v1

我们可以使用docs/example/manifests/split-v2/traffic-split-v2.yaml将流量重定向到v2。先看看这个文件里是什么。
apiVersion: split.smi-spec.io/v1alpha2
kind: TrafficSplit
metadata:
name: bookstore-split
namespace: bookstore
spec:
service: bookstore.bookstore # <root-service>.<namespace>
backends:
- service: bookstore-v1
weight: 0
- service: bookstore-v2
weight: 100

可以看到100%的流量都指向了v2。现在就部署它:
kubectl apply -f docs/example/manifests/split-v2/traffic-split-v2.yaml

马上就能看到v2的数量在增加:
o13.png

所有的流量都指向Bookstore-v2

当然,我们也可以做部分的分流,例如50/50的分流。这么做:
kubectl edit trafficsplit bookstore-split -n bookstore

o14.png

按照这种50/50的分流,可以看到两个书店的数量都在以相同指数增长:
o15.png

分流bookstore-v1和bookstore-v2之间的流量

那么,回顾一下刚才所做的:
  • 我们开了一家新书店
  • 我们第一次将100%的流量送到了这家新书店。我们只能看到书店-v2的更新。
  • 之后我们进行了50/50的分流,我们发现两家书店收到的流量大致相等。


最后,在这个演示应用程序中,再来看看OSM内置的一些监控。

流量监控

OSM预装了Prometheus、Grafana和Zipkin。这些工具允许创建关于流量的图表(prometheus/grafana)和分布式追踪系统(Zipkin)。

要访问Grafana,可以直接浏览器访问localhost:3000。默认登录是admin/admin。在Grafana中,打开仪表板管理视图:
o16.png

访问Grafana仪表板

先看一下service-to-service数据指标面板。
o17.png

查看服务到服务的流量

我们可以配置这个仪表板来显示不同系统或服务之间的流量。如果将其配置为监控bookbuyer和bookstore-v1之间的流量,我们就能清楚地看到哪里是100%的流量,哪里是50%的流量。此外,这个默认的仪表盘显示了请求延迟和其他一些指标。由于这是一个开源的工具,我们可以根据需求自由灵活地进行配置。
o18.png

service-to-service仪表板。可以清楚地看到流量从买家转移到v1书店,首先是100%,然后是0%,然后是50%

总结

在这篇文章中,我们介绍了Open Service Mesh。OSM是一个新的服务网格,使用Envoy Proxy,并且完全遵循SMI规范。我们部署了一个演示应用程序并做了一些分流测试。

这个Demo比较有趣,配置非常简单,内置的监控也不错。

原文链接:Taking the Open Service Mesh for a test drive(翻译:伊海峰)

0 个评论

要回复文章请先登录注册