目标规则是服务网格ASM实现流量路由功能的关键资源之一。目标规则定义在路由发生后,发往目标服务的流量策略。目标规则指定了负载均衡、来自Sidecar的连接池大小以及异常检测设置的相关配置,以便从负载均衡池中检测并清除不健康的主机。本文介绍目标规则的配置示例和字段说明。
配置示例
示例一:简单负载均衡策略
以下目标规则使用最少请求(LEAST_REQUEST)负载均衡算法。在将负载分配给端点时,优先考虑未完成请求最少的端点。
apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
name: bookinfo-ratings
spec:
host: ratings.prod.svc.cluster.local
trafficPolicy:
loadBalancer:
simple: LEAST_REQUEST
示例二:针对端口进行自定义配置
流量策略可以针对特定端口进行定制。以下目标规则使用最少请求(LEAST_REQUEST)负载均衡策略处理所有到80端口的流量,同时将使用轮询(ROUND_ROBIN)负载均衡设置处理到9080端口的流量。
apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
name: bookinfo-ratings-port
spec:
host: ratings.prod.svc.cluster.local
trafficPolicy: # Apply to all ports.
portLevelSettings:
- port:
number: 80
loadBalancer:
simple: LEAST_REQUEST
- port:
number: 9080
loadBalancer:
simple: ROUND_ROBIN
示例三:针对特定工作负载进行自定义配置
以下示例使用workloadSelector
配置将目标规则应用于特定工作负载。
apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
name: configure-client-mtls-dr-with-workloadselector
spec:
host: example.com
workloadSelector:
matchLabels:
app: ratings
trafficPolicy:
loadBalancer:
simple: ROUND_ROBIN
portLevelSettings:
- port:
number: 31443
tls:
credentialName: client-credential
mode: MUTUAL
字段说明
DestinationRule
目标规则定义在路由发生后,发往目的服务的流量策略。
字段 | 类型 | 是否必选 | 说明 |
host | string | 是 | 服务注册表中的服务名称。服务名称将在平台的服务注册表(例如Kubernetes服务、Consul服务等)和ServiceEntry声明的主机中查找。对于服务注册表中不存在服务定义的规则将被忽略。该字段适用于HTTP服务和TCP服务。 针对Kubernetes的说明如下:
|
trafficPolicy | 否 | 应用的流量策略(负载均衡策略、连接池大小、异常检测)。 | |
subsets | 否 | 代表服务的各个版本的一个或多个子集。服务基本的流量策略可以被子集级别覆盖。 | |
exportTo | string[] | 否 | 目标规则导出到的命名空间列表。将目标规则解析应用于服务时,会在命名空间层级的上下文中进行。导出的目标规则允许被包含在其他命名空间中的服务解析层次结构中。此功能提供了一种机制,使服务所有者和网格管理员可以控制跨命名空间边界的目标规则的可见性。
|
workloadSelector | 否 | 选择应用此目标规则的Pods的条件。
|
TrafficPolicy
应用到指定目的地的流量策略,作用于目的地的全部端口。
字段 | 类型 | 是否必选 | 说明 |
loadBalancer | 否 | 设置负载均衡算法。 | |
connectionPool | 否 | 设置上游服务的连接池。 | |
outlierDetection | 否 | 设置如何从负载平衡池中清除不健康主机。 | |
tls | 否 | 与上游服务连接的TLS相关设置。 | |
portLevelSettings | 否 | 端口级别的流量策略。端口级别的设置将覆盖目的地级别的设置。当端口级别的流量策略覆盖了目的地级别的设置时,目的地级别的其他字段的设置将不会被继承,即在端口级别的流量策略中省略的字段将应用默认值。 | |
tunnel | 否 | 对于目标规则中指定的主机,将TCP使用其他传输层或者应用层协议进行隧道传输。TunnelSettings可应用于TCP或TLS路由,但不能应用于HTTP路由。 |
Subset
服务全部端点(endpoints)的一个子集。子集可用于A/B测试或路由到服务的特定版本等场景。服务级别定义的流量策略可以在子集级别被覆盖。关于子集的更多信息,请参见虚拟服务(Virtual Service)CRD说明。
您可以使用目标规则指定命名的服务子集,例如按版本为所有给定服务的实例分组。在虚拟服务的路由规则中使用这些服务子集来控制到服务不同实例的流量。在子集中可以指定特定版本的策略并覆盖在服务级别指定的设置。以下目标规则使用轮询(ROUND_ROBIN)负载平衡策略,将所有流量发送到名为testversion
的子集。该子集由具有标签version:v3
的Endpoints组成。
对子集指定的负载均衡策略,仅当目标规则将流量发送到该子集时生效。
通常需要一个或多个标签来指定子集包含的目标。当目标规则代表的主机名支持多个SNI主机名时(例如出口网关),没有标签的子集可能有意义。在这种情况下,可以使用包含ClientTLSSettings的流量策略来识别与命名子集对应的特定SNI主机。
字段 | 类型 | 是否必选 | 说明 |
name | string | 是 | 子集的名称。服务名称和子集名称可用于路由规则中的流量拆分。 |
labels | map<string, string> | 否 | 标签用于创建过滤器,筛选服务注册表中服务的端点。 |
trafficPolicy | 否 | 要应用到该子集的流量策略。子集继承在DestinationRule级别指定的流量策略。在子集级别指定的设置将覆盖在DestinationRule级别指定的相应设置。 |
LoadBalancerSettings
应用于特定目的地的负载平衡策略。更多信息,请参见Load Balancing。
以下目标规则对所有发往ratings服务的流量使用Robin负载平衡策略。
以下目标规则为ratings服务配置会话保持功能。使用基于哈希的负载均衡器并使用
httpCookie
字段user
作为哈希的Key。
下表类型列的oneof表示该字段的取值有多个,但是您只能任选其一进行配置。
字段 | 类型 | 是否必选 | 说明 |
simple | 否 | 指定一种简单负载平衡的算法。 | |
consistentHash | 否 | 指定一种一致性哈希负载均衡的算法。 | |
localityLbSetting | 否 | 本地负载均衡器设置。此配置将完全覆盖网格范围的设置。此对象和MeshConfig中的对象不会进行合并。 | |
warmupDurationSecs | 否 | 服务的预热持续时间。如果设置了该字段,服务的新端点将在其创建时间开始保持预热模式,持续该字段指定的时间。在此期间Istio将逐渐增加该端点的流量,而不是发送相应比例的流量。
|
ConnectionPoolSettings
连接到上游主机的连接池设置。这些设置适用于上游服务中的每个主机。更多信息,请参见Envoy的circuit breaker。连接池设置可应用于TCP级别和HTTP级别。
例如,以下规则对名为myredissrv的Redis服务设置100个连接的上限,并设置连接超时为30毫秒。
字段 | 类型 | 是否必选 | 说明 |
tcp | 否 | HTTP和TCP上游连接的通用设置。 | |
http | 否 | HTTP连接池设置。 |
OutlierDetection
跟踪上游服务中主机的状态的熔断器,适用于HTTP和TCP服务。
对于HTTP服务,API调用不断返回5xx错误的主机将在指定时间内从可用主机池中排除。
对于TCP服务,给定主机的连接超时或连接失败在计算连续错误指标时都被视为错误。更多信息,请参见Envoy的outlier detection。
以下目标规则将连接池大小设置为100个HTTP1连接,发送到reviews服务的请求或连接不超过10个。为HTTP2请求设置1000并发的上限,并将上游主机配置为每5分钟扫描一次。任何连续7次出现502、503或504错误代码的主机将被熔断15分钟。
字段 | 类型 | 是否必选 | 说明 |
splitExternalLocalOriginErrors | bool | 否 | 指定是否区分本地源故障和外部错误。默认为false。设置为true,consecutiveLocalOriginFailures将被用于异常值检测计算。 以下场景时,您可以使用此功能。
|
consecutiveLocalOriginFailures | 否 | 触发排除需要的连续本地故障数。默认为5。该字段仅在splitExternalLocalOriginErrors设置为true时生效。 | |
consecutiveGatewayErrors | 否 | 将主机排除出连接池需要的网关错误数。当通过HTTP访问上游主机时,502、503或504返回码被视为网关错误。当通过不透明的TCP连接访问上游主机时,连接超时和连接错误/失败事件被视为网关错误。默认情况或设置值为0时,此功能关闭。 说明
| |
consecutive5xxErrors | 否 | 将主机排除出连接池需要的5xx错误数量。当通过不透明的TCP连接访问上游主机时,连接超时、连接错误或失败、请求失败事件都被视为5xx错误。默认值为5。您可以通过将值设置为0来关闭此功能。 说明
| |
interval | 否 | 排除操作扫描的时间间隔。格式为1h/1m/1s/1ms。该值必须≥1毫秒。默认为10秒。 | |
baseEjectionTime | 否 | 最短排除时间。主机被排除出连接池的时间等于最短排除时间和主机被排除次数的乘积。该字段允许系统自动增加不健康的上游服务器的弹出时间。格式为1h/1m/1s/1ms。该值必须≥1毫秒。默认为30秒。 | |
maxEjectionPercent | int32 | 否 | 可以排除出负载均衡池的上游服务主机的最大百分比。默认为10%。 |
minHealthPercent | int32 | 否 | 当负载均衡池至少有min_health_percent比例的主机处于健康状态时,启用异常检测。当负载均衡池中健康主机的百分比低于此阈值时,异常检测将被禁用,代理将在池中的所有主机(健康和不健康)之间进行负载均衡。您可以通过将阈值设置为0%来禁用该阈值。默认值为0%,因为它通常不适用于每个服务只有几个Pod的K8s环境。 |
ClientTLSSettings
上游连接的SSL/TLS相关设置。该配置适用于HTTP和TCP上游。更多信息,请参见Envoy的TLS context。
以下目标规则将客户端配置为使用双向TLS连接到上游数据库集群。
以下目标规则将客户端配置为在与域名
*.foo.com
匹配的外部服务对话时使用TLS。以下目标规则将客户端配置为在与ratings服务通信时使用Istio双向TLS。
字段 | 类型 | 是否必选 | 说明 |
mode | 是 | 指定是使用TLS对此端口的连接进行安全保护。该字段的值决定TLS的应用方式。 | |
clientCertificate | string | 否 | 客户端侧TLS证书的文件路径。
|
privateKey | string | 否 | 客户端私钥的文件路径。
|
caCertificates | string | 否 | 用于验证证书的CA证书的文件路径。
|
credentialName | string | 否 | 保存包括CA证书在内的客户端TLS证书的密钥的名称。密钥必须存在于使用证书的代理所在的相同名称空间中。 支持generic和tls两种密钥类型。
说明 只有DestinationRule中指定了工作负载的选择器(workloadSelector)时,本字段才会对Sidecar生效。否则本字段仅适用于网关,Sidecar将继续使用证书路径。 |
subjectAltNames | string[] | 否 | 用于验证证书中主体身份的备用名称列表。
|
sni | string | 否 | 在TLS握手期间提供给服务器的SNI字符串。如果未指定,当将ENABLE_AUTO_SNI环境变量设置为true时,在简单TLS和相互TLS模式下,会基于下游HTTP Host或者Authority Header自动设置SNI。 |
insecureSkipVerify | 否 | 此字段指定代理是否跳过验证与主机对应的服务器证书的CA签名和SAN。默认为false。 仅当启用全局CA签名验证,并且将VerifyCertAtClient环境变量设置为true,但不希望对特定主机进行验证时,才应设置此标志。如果启用InsecureSkipVerify,无论是否启用VerifyCertAtClient,都将跳过CA签名和SAN的验证。 |
LocalityLoadBalancerSetting
提供一个区域加权的负载均衡,使管理员能够根据流量的源位置和终止位置来控制流量分配到端点的比例。区域信息可以使用任意标签指定。这些标签以{region}/{zone}/{sub-zone}
形式指定区域的层次结构。更多信息,请参见Locality Weight。
以下示例展示如何在整个网格中设置区域加权。假设有一个包含工作负载和服务的网格被部署到区域
hangzhou/zone1/
和hangzhou/zone2/
。本示例指定当访问服务的流量源自hangzhou/zone1/
的工作负载时,80%的流量将被发送到hangzhou/zone1/
中的端点(即同一区域),剩下的20%将被发送到hangzhou/zone2/
中的端点。此设置优先将流量路由到相同本地性的终点。对于源自hangzhou/zone2/
的流量,也指定了类似的设置。如果您的目标不是跨区域或可用区分配负载,而是限制故障转移的区域性,则可以设置
failover
策略而不是distribute
策略。以下示例设置区域故障转移策略。假设服务驻留在杭州、北京和上海的区域中。此策略指定当杭州的端点变为不健康时,流量应转移到北京区域或子区域中的端点。同理,当北京的端点变为不健康状态时,流量应该转移到上海的端点。
字段 | 类型 | 是否必选 | 说明 |
distribute | 否 | 明确指定跨不同区域和地理位置的负载均衡权重。如果为空,则根据其中的端点数设置区域权重。更多信息,请参见Locality weighted load balancing。 说明 只能设置distribute、failover、failoverPriority三者中的任意一项。 | |
failover | Failover[] | 否 | 明确指定当本地区域中的端点变为不健康时,流量将转移到哪个区域。该字段需要与OutlierDetection一起使用,以检测不健康的端点。如果未指定OutlierDetection,此设置将不会生效。 说明 只能设置distribute、failover、failoverPriority三者中的任意一项。 |
failoverPriority | string[] | 否 | 一个有序的标签列表,用于对端点进行排序以进行基于优先级的负载平衡。该字段用于支持跨不同端点组的流量故障转移。该字段需要与OutlierDetection一起使用,以检测不健康的端点。如果未指定OutlierDetection,此设置将不会生效。 假设一共指定了N个标签:
此字段可以是在客户端和服务端工作负载上指定的任何标签,并支持以下具有特殊语义的标签:
以下拓扑配置的优先级说明如下:
说明 只能设置distribute、failover、failoverPriority三者中的任意一项。 |
enabled | 否 | 启用区域负载均衡。该配置为DestinationRule级别,将完全覆盖网格级别的设置。例如,该字段配置为true表示无论网格级别是什么设置,都为此DestinationRule开启区域负载均衡。 |
TrafficPolicy.PortTrafficPolicy
服务特定端口的流量策略。
字段 | 类型 | 是否必选 | 说明 |
port | 否 | 指定应用此策略的目标服务上的端口号。 | |
loadBalancer | 否 | 控制负载均衡器算法。 | |
connectionPool | 否 | 控制与上游服务的连接量。 | |
outlierDetection | 否 | 控制从负载平衡池中排除不健康主机。 | |
tls | 否 | 与上游服务连接的TLS相关设置。 |
LoadBalancerSettings.ConsistentHashLB
Consistent Hash-based load balancing可用于提供基于HTTP头部、Cookie或其他属性的软会话保持。一致性哈希在会话保持方面弱于传统的基于HostName的会话保持。当一个或多个主机被添加或删除时,使用一致性哈希算法的负载均衡会导致一小部分请求的会话保持失效。基于HostName的会话保持通常在Cookie中编码特定目标,确保只要后端保持不变就会维持关联。
一致性哈希的优势在于可以实现更好的负载均衡,对云上系统更加友好。
一致性哈希取决于每个代理拥有一致的端点视图。当启用区域负载平衡时,不保证每个代理拥有一致的端点视图情况。区域负载平衡和一致性哈希只有在所有代理都在同一区域时才能一起生效,或者套一个更高层级的负载均衡去处理区域亲和性。
字段 | 类型 | 是否必选 | 说明 |
httpHeaderName | string | 否 | 基于特定HTTP标头的哈希。 httpHeaderName、httpCookie、useSourceIp、httpQueryParameterName这四个参数只能填一个。 |
httpCookie | 否 | 基于HTTP Cookie的哈希。 httpHeaderName、httpCookie、useSourceIp、httpQueryParameterName这四个参数只能填一个。 | |
useSourceIp | bool | 否 | 基于源IP地址的哈希,适用于TCP和HTTP连接。 httpHeaderName、httpCookie、useSourceIp、httpQueryParameterName这四个参数只能填一个。 |
httpQueryParameterName | string | 否 | 基于指定HTTP查询参数的哈希。 httpHeaderName、httpCookie、useSourceIp、httpQueryParameterName这四个参数只能填一个。 |
ringHash | 否 | Ring或Modulo负载均衡器实现的对后端主机的一致性哈希。 ringHash和maglev这两个参数只能填一个,都不填默认是ringHash。 | |
maglev | 否 | Maglev负载均衡器实现的对后端主机的一致性哈希。 ringHash和maglev这两个参数只能填一个,都不填默认是ringHash。 ASM从1.16开始支持maglev算法。 | |
minimumRingSize | uint64 | 否 | 已弃用。请改用ringHash。 |
LoadBalancerSettings.ConsistentHashLB.RingHash
字段 | 类型 | 是否必选 | 说明 |
minimumRingSize | uint64 | 否 | Ring算法的最小虚拟节点数。默认为1024。较大的环会导致更细粒度的负载分布。如果负载均衡池中的主机数量大于环大小,则每台主机将分配一个虚拟节点。 |
LoadBalancerSettings.ConsistentHashLB.MagLev
字段 | 类型 | 是否必选 | 说明 |
tableSize | uint64 | 否 | Maglev算法中散列表的大小,有助于控制当后端主机发生变化时的干扰。增加表格大小可以减少干扰的程度。 |
LoadBalancerSettings.ConsistentHashLB.HTTPCookie
指定将被用作一致性哈希负载均衡器的哈希键。如果该Cookie不存在,则将生成该Cookie。
字段 | 类型 | 是否必选 | 说明 |
name | string | 是 | 这个cookie的内容将会被用作Hash Key。如果这个cookie不存在并且下面的ttl没有设置,将不会生成hash。 |
path | string | 否 | 如果指定了,在这个Cookie不存在时,将会生成一个带有TTL的Cookie。如果TTL存在并且等于零,生成的Cookie将会作为Session Cookie。 |
ttl | 是 | Cookie的生命周期。 |
ConnectionPoolSettings.TCPSettings
HTTP和TCP上游连接通用的设置。
字段 | 类型 | 是否必选 | 说明 |
maxConnections | int32 | 否 | 到目标主机的最大HTTP1或TCP连接数。默认为2^32-1。 |
connectTimeout | 否 | TCP连接超时时长。格式:1h/1m/1s/1ms。必须≥1毫秒。默认为10秒。 | |
tcpKeepalive | 否 | 如果设置,则在Socket上设置SO_KEEPALIVE以启用TCP Keepalive。 | |
maxConnectionDuration | 否 | 连接的最长持续时间。持续时间定义为自建立连接的时间间隔。如果未设置,则没有最大持续时间。当达到maxConnectionDuration时,连接将被关闭。持续时间必须至少为1毫秒。 |
ConnectionPoolSettings.HTTPSettings
适用于HTTP1.1、HTTP2、GRPC连接的设置。
字段 | 类型 | 是否必选 | 说明 |
http1MaxPendingRequests | int32 | 否 | 队列中等待连接就绪的最大请求数。默认为1024。此配置适用于HTTP/1.1和HTTP2。关于何时为HTTP2创建新连接,请参见circuit_breaking。 |
http2MaxRequests | int32 | 否 | 发往一个目的地的最大活跃请求数。默认为1024。此配置适用于HTTP/1.1和HTTP2。 |
maxRequestsPerConnection | int32 | 否 | 每个连接的最大请求数。此参数设置为1,将禁用HTTP Keepalive。默认为0,表示无限制,最大为2^29。 |
maxRetries | int32 | 否 | 在给定时间对集群中所有主机可以进行的最大重试次数。默认为2^32-1。 |
idleTimeout | 否 | 上游连接池连接的空闲超时时间。空闲超时时间指没有活动请求的时间段。如果未设置,则默认为1小时。当达到空闲超时时间时,连接将被关闭。如果连接是HTTP/2连接,则在关闭连接之前将发送Drain Sequence。 基于请求的超时表明HTTP/2 PING不会使连接保持活动状态。该配置适用于HTTP1.1和HTTP2连接。 | |
h2UpgradePolicy | 否 | 指定是否将连接到相应目的地的HTTP1.1连接升级为HTTP2连接。 | |
useClientProtocol | bool | 否 | 如果设置为true,则在向后端发起连接时将保留客户端使用的协议,Ah2UpgradePolicy将会无效,即客户端连接不会升级到HTTP2。 |
ConnectionPoolSettings.TCPSettings.TcpKeepalive
TCP Keepalive的相关设置。
字段 | 类型 | 是否必选 | 说明 |
probes | uint32 | 否 | 在确定连接已死之前要发送而没有响应的最大保活探测数。默认使用操作系统级别的配置(除非被覆盖)。Linux默认为9。 |
time | 否 | 在开始发送保活探测之前连接需要空闲的持续时间。默认使用操作系统级别的配置(除非被覆盖)。Linux默认为7200秒,即两小时。 | |
interval | 否 | 保活探测之间的间隔时间。默认使用操作系统级别的配置(除非被覆盖)。Linux默认为75秒。 |
google.protobuf.UInt32Value
uint32的包装信息。
字段 | 类型 | 是否必选 | 说明 |
value | uint32 | 否 | uint32值。在JSON中UInt32Value需要表示成一个JSON数字值。 |
LoadBalancerSettings.SimpleLB
标准负载平衡算法。
字段 | 说明 |
UNSPECIFIED | 不指定负载均衡算法。Istio将选择一个合适的默认值。 |
RANDOM | 随机负载均衡算法随机选择一个健康的主机。如果没有配置健康检查策略,随机负载均衡器通常比轮询性能好。 |
PASSTHROUGH | 此选项会将连接转发到调用者请求的原始IP地址,而不进行任何形式的负载均衡。此项属于高级用法,请谨慎使用。更多信息,请参见Original destination。 |
ROUND_ROBIN | 基本的轮询循环负载均衡策略。在许多场景(例如使用端点加权时)不太安全,因为它会使端点负担过重。通常情况下,最好使用LEAST_REQUEST作为ROUND_ROBIN的替代方案。 |
LEAST_REQUEST | 最少请求负载均衡在将负载分配给端点时,会优先考虑未完成请求最少的端点。通常更加安全,几乎在所有情况下都优于ROUND_ROBIN。建议使用LEAST_REQUEST作为ROUND_ROBIN的替代方案。 |
LEAST_CONN | 已弃用。请改用LEAST_REQUEST。 |
ConnectionPoolSettings.HTTPSettings.H2UpgradePolicy
将HTTP1.1连接升级到HTTP2的策略。
字段 | 说明 |
DEFAULT | 使用全局默认值。 |
DO_NOT_UPGRADE | 不将连接升级到HTTP2。 |
UPGRADE | 将连接升级到HTTP2。 |
ClientTLSSettings.TLSmode
TLS连接模式。
字段 | 说明 |
DISABLE | 不建立与上游端点的TLS连接。 |
SIMPLE | 建立与上游端点的TLS连接。 |
MUTUAL | 通过提供客户端证书进行身份验证,使用双向TLS保护与上游的连接。 |
ISTIO_MUTUAL | 通过提供客户端证书进行身份验证,使用双向TLS保护与上游的连接。与Mutual模式相比,该模式使用Istio自动生成的证书进行mTLS身份验证。使用此模式时,ClientTLSSettings中所有其他字段都应为空。 |