配置范围
为了对服务网格进行编程,Istio 控制平面 (Istiod) 会读取各种配置,包括像 Service
和 Node
这样的核心 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 的 VirtualService
、DestinationRule
和 ServiceEntry
提供一个 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
这样的优化更新。注意:对Service
和Endpoints
的更改将全部显示为ServiceEntry
。 - Istiod 公开了针对每个更改的指标
pilot_k8s_cfg_events
和pilot_k8s_reg_events
。 kubectl get <resource> --watch -oyaml --show-managed-fields
可以显示对对象(或对象)的更改,以帮助了解正在发生更改的内容以及由谁进行更改。
无头服务(除了声明为 HTTP 的服务)会随着实例数量的增加而扩展。这使得大型无头服务变得昂贵,并且适合使用 exportTo
或等效方法进行排除。
如果我连接到超出范围的服务会发生什么?
当连接到已通过其中一种范围机制排除的服务时,数据平面将不知道有关目的地的任何信息,因此将被视为 不匹配的流量。
网关呢?
虽然 网关 将尊重 exportTo
和 DiscoverySelectors
,但 Sidecar
对象不会影响网关。但是,与 sidecar 不同的是,网关默认情况下没有整个集群的配置。相反,每个配置都显式附加到网关,这在很大程度上避免了此问题。
但是,目前部分数据平面配置(用 Envoy 术语来说,是“集群”),始终针对整个集群发送,即使它没有被显式引用。