试驾 Open Service Mesh

k8s技术圈

共 7731字,需浏览 16分钟

 · 2020-08-16

上周微软发布了全新的服务网格(Service Mesh)轻量级解决方案:Open Service Mesh(简称 OSM),OSM 是 Service Mesh Interface(SMI)规范的一个实现,同样使用 Envoy 作为 sidecar 代理。对于一些初学者来说,这些概念可能比较陌生,下面我们从头开始来介绍下服务网格。

什么是服务网格?

我记得第一次听说服务网格的时候,是在一个”Introduction to Istio and onto 1.0“ 的 meetup 上,来自 Google 的 Dan Curuli 介绍了Istio 和它所解决的问题,从那以后服务网格和 Istio 越来越受欢迎。

那么什么是服务网格呢?服务网格是一种基础设施组件,有助于管理服务间的通信。换句话说,它是一种透明的技术,它将服务间通信的某些逻辑从你的应用代码中剥离出来,转移到了服务网格中。一个很好的例子就是我们调用 API 时的重试逻辑,如果没有服务网格,我们就必须把这些逻辑写到应用代码中去,但是有了服务网格过后,我们就可以将重试逻辑转移到网格中来,利用网格中的重试策略来实现这个功能(参考 Istio 中的示例)。

服务网格通常使用在 Kubernetes 环境下,虽然也可以在非 Kubernetes 环境中使用。在 Kubernetes 集群中,服务网格通常使用 sidecar 模式来实现,sidecar 是一个伴生容器,被添加到应用程序的 Pod 中去,以实现服务网格中的额外功能。

流量通过服务网格的 sidecar 流动,为应用增加额外的功能

这个 sidecar 容器可以是很多种容器,不过作为 sidecar 使用 Envoy 是一个非常流行的代理,Istio 就是使用的这个 sidecar(OSM 也是使用的 Envoy)。Envoy 最初是由 Lyft 开发的代理工具,在功能上与 Nginx 或者 HAProxy 比较类似,但是 Envoy 有一些明显的优势,包括高性能处理和集中式配置管理系统。当然 Envoy 并不是唯一可以使用的 sidecar,你也可以使用 Nginx,通常情况下,每个服务网格都会有一个默认的 sidecar 代理。

目前最流行的服务网格实现要数 Istio 了,Istio 最初是由 Google、IBM 和 Lyft 共同创建的项目,虽然它是目前最流行的服务网格,但是最近在开源社区也引起了一些小骚动,因为 Google 将 Istio 捐献给了一个新的基金会:Open Usage Commons,而不是将 Istio 捐献给 CNCF 基金会。当然 Istio 也不是唯一的服务网格,其他流行的网格包括 Linkerd、Consul、Maesh 等。

服务网格领域目前仍然还处于早期阶段,每种服务网格都有自己的优势和劣势。但是从一个网格切换到另一个网格并不是很直接,有一定成本,这是因为每个网格都有自己的配置语言语法,这就是 SMI 规范视图解决的问题。

SMI 规范

Serivce Mesh Interface(SMI)规范是运行在 Kubernetes 上的服务网格的标准接口。如果你熟悉 Kubernetes 中的 Ingress 资源,SMI 对于服务网格,就类似于 Ingress 对于反向代理,它是一种配置多个后端实现的标准化方式。这样做的好处是,你不必学习特定实现的具体内容,就可以简单使用 SMI 规范来配置你的服务网格了。

微软最初在2019年5月创建了 SMI 规范,并在2020年4月将该规范捐献给了 CNCF 基金会。到目前为止,已经有4个服务网格实现了 SMI 规范:

  • Istio ( 通过适配器 )

  • Linkerd

  • Consul Connect ( 通过适配器 )

  • Maesh

当然现在又有一个新的服务网格实现实现了 SMI 规范,那就是 OSM

Open Service Mesh

Open Service Mesh(OSM)是一个新的服务网格,同样使用 Envoy 作为 sidecar 代理,并使用 SMI 规范进行配置。虽然这个服务网格才刚刚推出,但是已经实现了一些功能(摘自 OSM 官网:https://openservicemesh.io/):

  • 轻松、透明地配置应用的流量移动

  • 通过启用 mTLS 确保端到端服务间的通信安全

  • 定义并执行精细的服务访问控制策略

  • 可观测性和应用指标,用于服务调试和监控

  • 通过可插拔的接口与外部证书管理服务/解决方案集成

  • 可以启用自动注入 Envoy sidecar 代理,将应用程序纳入到网格

  • 足够灵活,可以通过 SMI 和 Envoy XDS API 来处理简单和复杂的各种场景

接下来我们就去 Kubernetes 集群中来安装体验下 OSM。

使用 OSM

我将在 Azure 中的现有集群上安装 OSM,OSM 需要一个 v1.15.0 版本或以上的 Kubernetes 集群。

然后下载 OSM 二进制文件,这里我们下载 GitHub 上的最新版本 v0.2.0:

wget https://github.com/openservicemesh/osm/releases/download/v0.2.0/osm-v0.2.0-linux-amd64.tar.gztar -xvzf osm-v0.2.0-linux-amd64.tar.gzsudo mv linux-amd64/osm /usr/local/bin/osmrm -rf linux-amd64

然后直接执行 osm install 命令安装 OSM 即可,安装结果如下图所示:

当安装完 OSM 过后,我们就可以来探索下如何使用了~

OSM 演示应用程序

基本设置

OSM 团队为我们提供了一个非常友好的完整演示应用程序,这里我们将创建几个 namespace 并部署几个应用。

demo 应用结构

首先将 OSM 的代码仓库 Clone 到本地:

git clone https://github.com/openservicemesh/osm.gitcd osm

接下来我们创建4个 namespace,并将这4个 namespace 加入到 OSM 中:

for i in bookstore bookbuyer bookthief bookwarehouse; do kubectl create ns $i; donefor i in bookstore bookbuyer bookthief bookwarehouse; do osm namespace add $i; done

然后部署4个应用程序,它们的配置在目录 docs/example/manifests/apps/ 中:

我们可以看到有4个应用的 YAML 资源清单文件,还有一个 traffic-split.yaml 的文件,这个文件中就包含了服务网格的配置,文件内容如下所示:

apiVersion: split.smi-spec.io/v1alpha2kind: TrafficSplitmetadata:  name: bookstore-split  namespace: bookstorespec:  service: bookstore.bookstore # .  backends:  - service: bookstore-v1    weight: 100

这就是 SMI 配置,并没有 OSM 的特殊配置,因为 OSM 是遵循 SMI 规范的,我们直接部署这个示例应用,看看会发生什么。

kubectl create -f docs/example/manifests/apps/

可以看到会部署一堆资源对象,部署完成后我们可以通过设置端口转发来查看应用程序:

cp .env.example .env./scripts/port-forward-all.sh

这会在本地开启如下几个端点绑定在应用程序上:

  • http://localhost:8080 – Bookbuyer

  • http://localhost:8081 – bookstore-v1

  • http://localhost:8083 – bookthief

可以默认访问服务的样子如下所示:

允许请求

正常情况下,如果服务之间能够互相通信,我们就可以看到页面上的计数器会增加。但是现在这三个服务之间不允许有任何流量,意味着没有 book 会被 buy 或者 stolen,我们可以通过应用访问控制策略来修改。在上面仓库代码的 docs/example/manifests/access/ 目录下面就有一个策略文件,内容如下所示:

kind: TrafficTargetapiVersion: access.smi-spec.io/v1alpha2metadata:  name: bookstore-v1  namespace: bookstorespec:  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/v1alpha3kind: HTTPRouteGroupmetadata:  name: bookstore-service-routes  namespace: bookstorespec:  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 这个 ServiceAccount 被注释掉了,意味着这个 sa 下面的应用不能访问其他服务

  • 然后,可以看到我们创建了两个对象:TrafficTargetHTTPRouteGroup

    • HTTPRouteGroup 用于描述 HTTP/1 和 HTTP/2 的流量,它枚举了可以通过应用程序进行服务的路由。

    • TrafficTarget 将一组流量定义(规则)与服务关联起来,服务和一组 Pods 进行关联。

  • 在我们这个示例,可以看到:

    • 现在的源只是 bookbuyer 这个 ServiceAccount,而不是 thief(被注释掉了)。

    • 我们创建了一个通往目标 bookstore-v1 的 TrafficGroup 匹配了两个 HTTPRouteGroup

    下面我们直接创建 HTTPRouteGroups 来查看流量请求:

    kubectl create -f docs/example/manifests/access/

    一旦创建了访问策略,我们就会看到计数器递增,这意味着书籍正在被买进或卖出,但没有被盗。

    计数器在流量开始流动时递增

    接下来我们启用 book thief,将上面文件docs/example/manifests/access/traffic-access.yaml 中的注释取消掉:

    kind: TrafficTargetapiVersion: access.smi-spec.io/v1alpha2metadata:  name: bookstore-v1  namespace: bookstorespec:  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

    重新更新我们的资源清单:

    kubectl apply -f docs/example/manifests/access/traffic-access.yaml
    允许 thief 也访问 bookstore

    现在我们再去访问我们的应用,就可以看到在  bookthief 中也有变化了。

    thief 现在也能够访问 bookstore 服务了

    我们来快速回顾下上面我们做的事情:

    • 在集群中安装了 OSM

    • 创建了4个命名空间,并将这些命名空间加入到 OSM 网格中

    • 创建了一个应用程序,看到流量默认被阻止

    • 使用 TrafficTargetHTTPRouteGroup 对象创建了一个流量策略,以允许特定的流量在我们的网格中流动

    下面我们将创建一个新版本的 bookstore(bookstore-v2),我们将能够将流量从一个服务引导到另一个服务。

    流量分流

    在本节中,我们将部署一个新版本的 bookstore,然后慢慢将所有流量导向它,首先,让我们部署第二版本的 bookstore:

    kubectl apply -f docs/example/manifests/bookstore-v2/

    在我们进行端口转发的终端窗口中,我们需要停掉脚本,然后再次启动该脚本,就可以转发到第二版本的 bookstore 应用了。

    当我们访问应用的时候可以看到计数器增加了,但是第二家书店没有卖出任何副本,这是因为 TrafficSplit 被配置为将 100% 的流量导入到了主要的书店。我们可以通过检查该对象来验证这一点。

    kubectl get trafficsplit bookstore-split -n bookstore
    所有流量到了 bookstore-v1

    我们可以通过部署 docs/example/manifests/split-v2/traffic-split-v2.yaml 文件将流量重定向到 v2 版本的书店,我们先来查看该文件的内容。

    apiVersion: split.smi-spec.io/v1alpha2kind: TrafficSplitmetadata:  name: bookstore-split  namespace: bookstorespec:  service: bookstore.bookstore # .  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 版本的书店计数器在增加了:

    bookstore-v2 获取了所有的流量

    我们也可以按照权重来拆分流量,比如 50/50 拆分,直接修改上面的资源对象:

    kubectl edit trafficsplit bookstore-split -n bookstore

    编辑后,现在我们可以看到两个版本的书店的计数器都在增加了,而且增长的速度差不多。

    v1 和 v2 两个版本 50% 流量

    同样我们来回顾下这里我们做了些什么操作:

    • 新建了一个新版本的 bookstore 应用

    • 先把 100% 的流量发送到新书店,只能看到 bookstore-v2 应用有流量

    • 然后我们做了 50/50% 的流量拆分,我们看到两个 bookstores 应用都收到了比例大致相等的流量。

    最后,我们来看看 OSM 内置的一些监控。

    流量监控

    OSM 预安装了 Prometheus、Grafana 和 Zipkin,这些工具允许我们创建关于应用的流量图表(prometheus/grafana)和进行分布式追踪(Zipkin)。

    要访问 Grafana,我们可以在浏览器中打开 localhost:3000,默认使用 admin/admin 进行登录,在Grafna 中,打开 dashboard 的管理视图:

    我们来看下服务到服务的数据平面指标数据:

    同样我们可以配置这个 dashboard,让我们看到不同系统/服务之间的流量。如果我们将其配置为监控 bookbuyer 和 bookstore-v1 之间的流量,我们就会清楚地看到哪里有 100% 的流量,哪里有 50% 的流量。此外,这个默认的 dashboard 还向我们展示了请求延迟和其他的一些指标,同样我们也可以自由配置自己的相关指标。

    我们可以清楚地看到流量从 buyer 到 bookstore-v1 的转变,先是 100%,然后是 0%,然后是 50%。

    关于 OSM 更多高级的用法可以去官方文档(https://openservicemesh.io/)上了解更多信息。

    ?

    原文链接:https://blog.nillsf.com/index.php/2020/08/11/taking-the-open-service-mesh-for-a-test-drive/




    K8S进阶训练营,点击下方图片了解详情

    浏览 39
    点赞
    评论
    收藏
    分享

    手机扫一扫分享

    举报
    评论
    图片
    表情
    推荐
    点赞
    评论
    收藏
    分享

    手机扫一扫分享

    举报