配置范围

为了对服务网格进行编程,Istio 控制平面 (Istiod) 会读取各种配置,包括像 ServiceNode 这样的核心 Kubernetes 类型,以及 Istio 自身的类型,比如 Gateway。这些配置随后会发送到数据平面(有关更多信息,请参阅 架构)。

默认情况下,控制平面将读取所有命名空间中的所有配置。每个代理实例也将接收所有命名空间的配置。这包括有关未加入网格的工作负载的信息。

这种默认设置可确保开箱即用的正确行为,但会带来可扩展性成本。每个配置都包含维护和更新的成本(主要是 CPU 和内存)。在大型规模上,限制配置范围以避免过度消耗资源至关重要。

范围机制

Istio 提供了一些工具来帮助控制配置范围,以满足不同的用例。根据您的要求,可以单独或一起使用这些工具。

  • Sidecar 提供了一种机制,使特定工作负载可以导入一组配置。
  • exportTo 提供了一种机制,使导出配置到一组工作负载。
  • discoverySelectors 提供了一种机制,使 Istio 可以完全忽略一组配置。

Sidecar 导入

Sidecar 中的 egress.hosts 字段允许指定要导入的配置列表。只有与指定条件匹配的配置才会被受 Sidecar 资源影响的 sidecar 看到。

例如

apiVersion: networking.istio.io/v1
kind: Sidecar
metadata:
  name: default
spec:
  egress:
  - hosts:
    - "./*" # Import all configuration from our own namespace
    - "bookinfo/*" # Import all configuration from the bookinfo namespace
    - "external-services/example.com" # Import only 'example.com' from the external-services namespace

exportTo

Istio 的 VirtualServiceDestinationRuleServiceEntry 提供一个 spec.exportTo 字段。类似地,Service 可以使用 networking.istio.io/exportTo 注释进行配置。

Sidecar 允许工作负载所有者控制其依赖关系不同,exportTo 的工作方式相反,允许服务所有者控制其自身服务的可见性。

例如,此配置使 details Service 仅对自身命名空间和 client 命名空间可见。

apiVersion: v1
kind: Service
metadata:
  name: details
  annotations:
    networking.istio.io/exportTo: ".,client"
spec: ...

DiscoverySelectors

虽然之前的控制操作在工作负载或服务所有者级别进行,但 DiscoverySelectors 提供了对配置可见性的网格范围控制。Discovery 选择器允许指定哪些命名空间对控制平面可见的条件。控制平面将完全忽略所有不匹配的命名空间。

这可以在安装期间作为 meshConfig 的一部分进行配置。例如

meshConfig:
  discoverySelectors:
    - matchLabels:
        # Allow any namespaces with `istio-discovery=enabled`
        istio-discovery: enabled
    - matchLabels:
        # Allow "kube-system"; Kubernetes automatically adds this label to each namespace
        kubernetes.io/metadata.name: kube-system

常见问题解答

如何理解特定配置的成本?

为了获得缩小配置范围的最佳投资回报率,了解每个对象的成本可能会有所帮助。不幸的是,没有一个简单的答案;可扩展性取决于许多因素。但是,有一些一般的指导原则。

配置更改在 Istio 中很昂贵,因为它们需要重新计算。虽然 Endpoints 更改(通常来自 Pod 的向上或向下扩展)经过高度优化,但大多数其他配置都很昂贵。当控制器不断对对象进行更改时,这尤其有害(有时会意外发生!)。一些工具可以检测哪些配置正在发生变化。

  • Istiod 将记录每个更改,例如:Push debounce stable 1 for config Gateway/default/gateway: ..., full=true。这显示了 default 命名空间中的 Gateway 对象已发生更改。full=false 代表 Endpoint 这样的优化更新。注意:对 ServiceEndpoints 的更改将全部显示为 ServiceEntry
  • Istiod 公开了针对每个更改的指标 pilot_k8s_cfg_eventspilot_k8s_reg_events
  • kubectl get <resource> --watch -oyaml --show-managed-fields 可以显示对对象(或对象)的更改,以帮助了解正在发生更改的内容以及由谁进行更改。

无头服务(除了声明为 HTTP 的服务)会随着实例数量的增加而扩展。这使得大型无头服务变得昂贵,并且适合使用 exportTo 或等效方法进行排除。

如果我连接到超出范围的服务会发生什么?

当连接到已通过其中一种范围机制排除的服务时,数据平面将不知道有关目的地的任何信息,因此将被视为 不匹配的流量

网关呢?

虽然 网关 将尊重 exportToDiscoverySelectors,但 Sidecar 对象不会影响网关。但是,与 sidecar 不同的是,网关默认情况下没有整个集群的配置。相反,每个配置都显式附加到网关,这在很大程度上避免了此问题。

但是,目前部分数据平面配置(用 Envoy 术语来说,是“集群”),始终针对整个集群发送,即使它没有被显式引用。

这些信息对您有帮助吗?
您有什么改进建议吗?

感谢您的反馈!