在Istio体系中,数据平面主要组件是istio proxy(envoy),关于istio proxy,有两个问题我们比较关注:

  • 请求延迟
  • 资源消耗

关于请求延迟我们很好理解,毕竟我们的业务在mesh中,多了一层代理。

今天我们主要讲述Istio代理的资源消耗以及如何使用新的Sidecar自定义资源来减少消耗。

Sidecar 自定义资源

与 VirtualService 和 DestinationRule 这些常用资源不同,Sidecar 资源并不是被所有人熟知。

Sidecar描述了sidecar代理的配置,其可协调与其连接的工作负载实例的入站和出站通信。默认情况下,Istio将使用到达网格中每个工作负载实例所需的必要配置对网格中的所有sidecar代理进行编程,并在与工作负载相关的所有端口上接受流量。 Sidecar配置提供了一种微调端口集的功能,代理在将流量转发到工作负载或从工作负载转发流量时代理将接受的协议。此外,当转发来自工作负载实例的出站流量时,可以限制代理可以访问的服务集。

每个命名空间只能具有一个Sidecar配置,而没有任何工作负载选择器,该负载指定该命名空间中所有Pod的默认值。对于命名空间范围的sidecar,建议使用默认名称。如果给定命名空间中存在多个不使用选择器的Sidecar配置,则系统的行为是不确定的。如果两个或多个带有工作负载选择器的Sidecar配置选择相同的工作负载实例,则系统的行为是不确定的。
默认情况下,MeshConfig根名称空间中的Sidecar配置将应用于所有没有Sidecar配置的命名空间。此全局默认Sidecar配置不应具有任何工作负载选择器。

接下来我们通过一些官方示例去更好地理解。

下面的示例在根命名空间中声明了全局默认的Sidecar配置default,该配置在所有命名空间中配置了sidecar,以仅允许将流量发送到同一命名空间中的其他工作负载以及istio-system命名空间中的服务。

apiVersion: networking.istio.io/v1beta1
kind: Sidecar
metadata:
  name: default
  namespace: istio-config
spec:
  egress:
  - hosts:
    - "./*"
    - "istio-system/*"

下面的示例在prod-us1命名空间中声明Sidecar配置,该配置将覆盖上面定义的全局默认值,并在命名空间中配置sidecar,以允许访问prod-us1prod-apisistio-system命名空间中的服务。

apiVersion: networking.istio.io/v1beta1
kind: Sidecar
metadata:
  name: default
  namespace: prod-us1
spec:
  egress:
  - hosts:
    - "prod-us1/*"
    - "prod-apis/*"
    - "istio-system/*"

以下示例在prod-us1命名空间中为所有带有标签app: ratings的pod声明Sidecar配置,这些pod属于rating.prod-us1服务。工作负载在端口9080上接受入站HTTP通信。然后,将通信转发到侦听Unix域套接字的附加工作负载实例。在出站方向上,除了istio-system命名空间外,sidecar仅代理绑定到端口9080的prod-us1命名空间中的服务的HTTP通信。

apiVersion: networking.istio.io/v1beta1
kind: Sidecar
metadata:
  name: ratings
  namespace: prod-us1
spec:
  workloadSelector:
    labels:
      app: ratings
  ingress:
  - port:
      number: 9080
      protocol: HTTP
      name: somename
    defaultEndpoint: unix:///var/run/someuds.sock
  egress:
  - port:
      number: 9080
      protocol: HTTP
      name: egresshttp
    hosts:
    - "prod-us1/*"
  - hosts:
    - "istio-system/*"

Sidecar 描述包含以下4部分:

  • workloadSelector -- 用于选择应在其上应用此Sidecar配置的特定Pod/VM组的条件。如果省略,则Sidecar配置将应用于同一名称空间中的所有工作负载实例。
  • ingress -- ingress 指定工作负载实例的入站流量的Sidecar的配置。如果省略,Istio将基于从业务流程平台获得的有关工作负载的信息(例如,公开的端口,服务等)自动配置sidecar。如果指定,则仅当工作负载实例与服务关联时,才配置入站端口。
  • egress -- egress指定用于处理从连接的工作负载实例到网格中其他服务的出站流量的Sidecar的配置。如果未指定,则从命名空间范围或全局默认Sidecar继承检测到的系统默认值。
  • outboundTrafficPolicy -- 出站流量策略的配置。如果您的应用程序使用未知的一项或多项外部服务,则将该策略设置为ALLOW_ANY将导致sidecar将源自该应用程序的所有未知流量路由到其请求的目的地。如果未指定,则从命名空间范围或全局默认Sidecar继承检测到的系统默认值。

为什么应该使用 Sidecar 自定义资源?

在不使用此自定义资源的情况下,Pilot会自动将相同的配置发送到代理,其中包含有关网格中每个工作负载实例的信息。

那么使用Sidecar 自定义资源有什么好处?

  • 安全。Istio 运维可以限制从特定名称空间或工作负载访问的服务集,因此可以确保这些工作负载将无法访问其范围之外的任何内容。
  • 性能。默认情况下,集群中的所有Envoy代理通过xDS从Pilot接收相同的配置,该配置包含集群中的所有Pod。这种配置可能非常庞大,尤其是在大型集群中,而在大多数情况下,简单的工作负载只能与少数几个通信。将此配置更改为仅包含一组必要的服务可能会对Istio代理的内存占用量产生很大影响。

下面我们看下测试数据,来对比一下。

上面的两个仪表板显示了基本相同的内存消耗指标,但是第一个仪表板是每个sidecar,而第二个仪表板是集群中所有Istio代理的总内存使用量。

当集群处于空闲状态时,配置命名空间隔离时,Envoy代理消耗的内存减少约40%。当集群处于负载状态时,百分比差异会缩小一点,仍然超过30%。而且这只是一个具有约150个Pod的10节点集群,出站流量仅限于名称空间!在生产集群中,Pod数量很容易达到数百甚至数千,而且这些限制可以进一步严格到工作负载级别。因此,通过正确的设置,您可以轻松节省约40-50%的sidecar代理内存消耗。


iyacontrol
1.4k 声望2.7k 粉丝

专注kubernetes,devops,aiops,service mesh。