Istio 和 Linkerd 的 CPU 消耗基准

Istio 和 Linkerd 的 CPU 消耗基准

介绍

我们在 Shopify商铺 开始将 Istio 部署为服务网格。 原则上,一切都很好,除了一件事: 它是昂贵的.

В 发布的基准 对于 Istio 来说:

在 Istio 1.1 中,代理每秒每 0,6 个请求消耗大约 1000 个 vCPU(虚拟核心)。

对于服务网格中的第一个区域(连接的每一侧都有 2 个代理),我们将为代理提供 1200 个核心,速率为每秒 40 万个请求。 根据 Google 的成本计算器,配置费用约为 XNUMX 美元/月/核心 n1-standard-64,也就是说,每秒 50 万个请求,仅这个区域就会花费我们每月 1 万多美元。

伊万·西姆(伊万·西姆) 视觉比较 服务网格去年延迟并承诺内存和处理器相同,但没有成功:

显然,values-istio-test.yaml 会严重增加 CPU 请求。 如果我的计算正确的话,控制面板大约需要 24 个 CPU 核心,每个代理需要 0,5 个 CPU。 我没有那么多。 当更多资源分配给我时,我会重复测试。

我想亲眼看看 Istio 的性能与另一个开源服务网格有多么相似: 链接器.

服务网格安装

首先我是安装在集群中的 超级格鲁:

$ supergloo init
installing supergloo version 0.3.12
using chart uri https://storage.googleapis.com/supergloo-helm/charts/supergloo-0.3.12.tgz
configmap/sidecar-injection-resources created
serviceaccount/supergloo created
serviceaccount/discovery created
serviceaccount/mesh-discovery created
clusterrole.rbac.authorization.k8s.io/discovery created
clusterrole.rbac.authorization.k8s.io/mesh-discovery created
clusterrolebinding.rbac.authorization.k8s.io/supergloo-role-binding created
clusterrolebinding.rbac.authorization.k8s.io/discovery-role-binding created
clusterrolebinding.rbac.authorization.k8s.io/mesh-discovery-role-binding created
deployment.extensions/supergloo created
deployment.extensions/discovery created
deployment.extensions/mesh-discovery created
install successful!

我使用 SuperGloo 是因为它使引导服务网格变得更加容易。 我不需要做太多事情。 我们不在生产中使用 SuperGloo,但它非常适合此类任务。 我必须为每个服务网格使用几个命令。 我使用两个集群进行隔离——Istio 和 Linkerd 各一个。

该实验是在 Google Kubernetes Engine 上进行的。 我用过 Kubernetes 1.12.7-gke.7 和一个节点池 n1-standard-4 具有自动节点缩放功能(最少 4 个,最多 16 个)。

然后我从命令行安装了两个服务网格。

首先链接:

$ supergloo install linkerd --name linkerd
+---------+--------------+---------+---------------------------+
| INSTALL |     TYPE     | STATUS  |          DETAILS          |
+---------+--------------+---------+---------------------------+
| linkerd | Linkerd Mesh | Pending | enabled: true             |
|         |              |         | version: stable-2.3.0     |
|         |              |         | namespace: linkerd        |
|         |              |         | mtls enabled: true        |
|         |              |         | auto inject enabled: true |
+---------+--------------+---------+---------------------------+

然后是 Istio:

$ supergloo install istio --name istio --installation-namespace istio-system --mtls=true --auto-inject=true
+---------+------------+---------+---------------------------+
| INSTALL |    TYPE    | STATUS  |          DETAILS          |
+---------+------------+---------+---------------------------+
| istio   | Istio Mesh | Pending | enabled: true             |
|         |            |         | version: 1.0.6            |
|         |            |         | namespace: istio-system   |
|         |            |         | mtls enabled: true        |
|         |            |         | auto inject enabled: true |
|         |            |         | grafana enabled: true     |
|         |            |         | prometheus enabled: true  |
|         |            |         | jaeger enabled: true      |
+---------+------------+---------+---------------------------+

崩溃循环持续了几分钟,然后控制面板稳定下来。

(注:SuperGloo 目前仅支持 Istio 1.0.x。我用 Istio 1.1.3 重复了实验,但没有注意到任何明显的差异。)

设置 Istio 自动部署

为了让 Istio 安装 sidecar Envoy,我们使用 sidecar 注入器 - MutatingAdmissionWebhook。 我们在本文中不会讨论它。 我只想说,这是一个控制器,监控所有新pod的访问,并动态添加一个sidecar和initContainer,它负责任务 iptables.

我们 Shopify 编写了自己的访问控制器来实现 sidecar,但对于此基准测试,我使用了 Istio 附带的控制器。 当命名空间中有快捷方式时,控制器默认注入 sidecar istio-injection: enabled:

$ kubectl label namespace irs-client-dev istio-injection=enabled
namespace/irs-client-dev labeled

$ kubectl label namespace irs-server-dev istio-injection=enabled
namespace/irs-server-dev labeled

设置自动 Linkerd 部署

为了设置 Linkerd sidecar 嵌入,我们使用注释(我通过手动添加它们 kubectl edit):

metadata:
  annotations:
    linkerd.io/inject: enabled

$ k edit ns irs-server-dev 
namespace/irs-server-dev edited

$ k get ns irs-server-dev -o yaml
apiVersion: v1
kind: Namespace
metadata:
  annotations:
    linkerd.io/inject: enabled
  name: irs-server-dev
spec:
  finalizers:
  - kubernetes
status:
  phase: Active

Istio 容错模拟器

我们构建了一个名为 Istio 的容错模拟器来试验 Shopify 特有的流量。 我们需要一个工具来创建自定义拓扑,该拓扑将代表我们服务图的特定部分,并动态配置以对特定工作负载进行建模。

Shopify 的基础设施在闪购期间负载很重。 与此同时,Shopify 建议卖家更频繁地举办此类促销活动。 大客户有时会对计划中的闪购发出警告。 其他人会在白天或晚上的任何时间为我们出乎意料地进行这些活动。

我们希望我们的弹性模拟器能够对工作流程进行建模,以匹配过去压垮 Shopify 基础设施的拓扑和工作负载。 使用服务网格的主要目的是我们需要网络级别的可靠性和容错能力,并且服务网格有效地应对之前中断服务的负载对我们来说很重要。

容错模拟器的核心是工作节点,它充当服务网格节点。 工作节点可以在启动时静态配置,也可以通过 REST API 动态配置。 我们使用工作节点的动态配置以回归测试的形式创建工作流。

以下是此类过程的示例:

  • 我们启动 10 台服务器 bar 返回响应的服务 200/OK 100 毫秒后。
  • 我们启动 10 个客户端 - 每个客户端每秒发送 100 个请求 bar.
  • 每 10 秒我们删除 1 台服务器并监控错误 5xx 在客户端上。

在工作流程结束时,我们检查日志和指标并检查测试是否通过。 通过这种方式,我们了解服务网格的性能并运行回归测试来测试我们对容错的假设。

(注意:我们正在考虑开源 Istio 容错模拟器,但尚未准备好这样做。)

用于服务网格基准测试的 Istio 容错模拟器

我们设置了模拟器的几个工作节点:

  • irs-client-loadgen:3 个副本,每秒发送 100 个请求 irs-client.
  • irs-client:3个副本收到请求,等待100ms并将请求转发到 irs-server.
  • irs-server:返回 3 个副本 200/OK 100 毫秒后。

通过此配置,我们可以测量 9 个端点之间的稳定流量。 边车在 irs-client-loadgen и irs-server 每秒接收 100 个请求,并且 irs-client — 200(传入和传出)。

我们通过以下方式跟踪资源使用情况 DataDog因为我们没有 Prometheus 集群。

结果

控制面板

首先,我们检查了 CPU 消耗。

Istio 和 Linkerd 的 CPU 消耗基准
Linkerd 控制面板 ~22 毫核

Istio 和 Linkerd 的 CPU 消耗基准
Istio 控制面板:~750 毫核

Istio 控制面板大约使用 CPU 资源增加 35 倍比林克德。 当然,一切都是默认安装的,istio-telemetry在这里消耗了大量的处理器资源(可以通过禁用某些功能来禁用)。 如果我们删除这个组件,我们仍然会得到超过 100 毫核,即 4倍数比林克德。

边车代理

然后我们测试了代理的使用。 与请求数量应该存在线性关系,但是对于每个 sidecar 来说,都有一些影响曲线的开销。

Istio 和 Linkerd 的 CPU 消耗基准
Linkerd:irs-client 约为 100 毫核,irs-client-loadgen 约为 50 毫核

结果看起来合乎逻辑,因为客户端代理接收的流量是 loadgen 代理的两倍:对于 loadgen 的每个传出请求,客户端都有一个传入和一个传出。

Istio 和 Linkerd 的 CPU 消耗基准
Istio/Envoy:irs-client 约为 155 毫核,irs-client-loadgen 约为 75 毫核

我们在 Istio sidecar 中看到了类似的结果。

但总的来说,Istio/Envoy 代理消耗 CPU 资源增加大约 50%比林克德。

我们在服务器端看到同样的方案:

Istio 和 Linkerd 的 CPU 消耗基准
Linkerd:irs-server 约为 50 毫核

Istio 和 Linkerd 的 CPU 消耗基准
Istio/Envoy:irs-server 约为 80 毫核

在服务器端,sidecar Istio/Envoy 消耗 CPU 资源增加大约 60%比林克德。

结论

在我们的模拟工作负载中,Istio Envoy 代理消耗的 CPU 比 Linkerd 多 50% 以上。 Linkerd 控制面板消耗的资源比 Istio 少得多,尤其是核心组件。

我们还在思考如何降低这些成本。 如果您有想法,请分享!

来源: habr.com

添加评论