虚拟服务是服务网格ASM实现流量路由功能的关键资源之一。对于访问指定目标主机的流量,虚拟服务定义了一组流量路由规则,每个路由规则定义了特定的流量匹配条件。如果流量匹配,则将其转发到路由规则所指定的目标服务或者目标服务的版本(子集)。本文介绍虚拟服务CRD的配置示例和字段说明。
配置示例
以下示例表示根据请求是否来自特定的主机,将其路由到服务的不同版本。将服务划分为不同的版本(子集)的能力通过目标规则(DestinationRule)实现。更多信息,请参见目标规则(Destination Rule)CRD说明。
虚拟服务将匹配网格中所有发往reviews
主机的请求。若请求为HTTP请求且请求的Header中包含end-user:jason
时,请求将被转发到reviews服务的v2版本;否则将转发到reviews服务的v3版本。
字段说明
VirtualService
流量路由的相关配置。
字段 | 类型 | 是否必选 | 说明 |
hosts | string[] | 否 | 待匹配流量的目标主机,可配置为带通配符前缀的DNS名称或IP地址。在Kubernetes中也可以使用短名称,例如 hosts字段适用于HTTP和TCP服务。网格内的服务,例如集群服务注册表中注册的服务,必须始终使用它们的DNS名称进行引用。只有在网关规则(Gateway)中,hosts字段里定义的服务才允许通过IP地址引用。 说明 如果要将虚拟服务作为委托虚拟服务(delegate VirtualService),本字段必须为空。 |
gateways | string[] | 否 | 应用路由规则的网关规则和Sidecar的名称。其他命名空间中的网关可以通过 保留字mesh表示网格中的所有Sidecar。
|
http | 否 | 针对HTTP流量的路由规则有序列表。HTTP路由规则将应用于端口名为 | |
tls | TLSRoute[] | 否 | 针对Non-terminated TLS和HTTPS流量的路由规则有序列表。通常使用ClientHello消息提供的SNI值执行路由。TLS路由规则将应用于端口名为 说明 没有关联虚拟服务的 |
tcp | TCPRoute[] | 否 | 不透明TCP流量的路由规则有序列表。TCP路由将应用于任何不是HTTP或TLS端口的端口。首个与传入请求匹配的规则将被使用。 |
exportTo | string[] | 否 | 将此虚拟服务导出到的命名空间。导出虚拟服务后,其他命名空间中定义的Sidecar和网关规则将可以引用该虚拟服务。此功能为服务所有者和网格管理员提供一种跨命名空间边界控制虚拟服务可见性的机制。 如果未指定命名空间,则默认情况下将虚拟服务导出到所有命名空间。 保留字 |
Destination
Destination定义经过路由规则处理后,请求或连接将被发送到的网络可寻址服务。destination.host
应该明确地指向服务注册表中的一个服务。Istio的服务注册表由平台服务注册表中找到的所有服务(例如Kubernetes服务、Consul服务)以及通过ServiceEntry资源声明的服务组成。
针对Kubernetes的注意事项如下:
当使用短名称时,例如使用
reviews
而不使用reviews.default.svc.cluster.local
,Istio将根据路由规则的命名空间而不是服务来解析短名称。在default命名空间中包含一个名为reviews的主机的规则将被解释为
reviews.default.svc.cluster.local
,而与reviews服务的实际命名空间无关。为避免潜在的配置错误,建议始终使用完全限定域名,而不使用短名称。
字段 | 类型 | 是否必选 | 说明 |
host | string | 是 | 服务注册表中的服务名称。服务名称将在平台的服务注册表(例如Kubernetes服务、Consul服务等)和ServiceEntry声明的主机中查找。如果未能找到,转发到此目的地的流量将会被丢弃。 |
subset | string | 否 | 服务的版本(子集)名。仅适用于网格内的服务。该版本必须在服务相应的目标规则中定义。 |
port | 否 | 指定流量目标主机的端口。如果服务仅公开一个端口,则不需要显式选择端口。 |
HTTPRoute
HTTPRoute定义对HTTP/1.1、HTTP2和gRPC流量的匹配条件和操作。
字段 | 类型 | 是否必选 | 说明 |
name | string | 否 | 出于调试目的为路由设置的名称。路由的名称将与匹配条件的名称拼接,记录到与此路由或匹配项匹配的请求的访问日志中。 |
match | 否 | 激活规则需要满足的匹配条件。在单个匹配块内的所有条件都具有AND语义,而匹配块列表具有OR语义。匹配将从第一个匹配块开始依次进行,任何一个匹配块成功匹配,都将执行此路由规则。 | |
route | 否 | 对于匹配到的请求,HTTP规则可以进行路由的操作,包括直接响应、重定向或转发流量。本字段用于设置流量转发规则。流量转发目标可以是服务或者服务的版本(子集)。您可以通过为服务版本配置权重决定其接收到的流量比例。 | |
redirect | 否 | 对于匹配到的请求,HTTP规则可以进行路由的操作,包括直接响应、重定向或转发流量。本字段用于设置重定向规则。重定向原语可以用于向不同的URI或Authority发送HTTP 301重定向。 如果在目标规则中指定流量直通( | |
directResponse | 否 | 对于匹配到的请求,HTTP规则可以进行路由的操作,包括直接响应、重定向和转发流量。本字段用于设置直接响应规则。直接响应可以用于指定应发送给客户端的固定响应。 仅当route和redirect字段为空时才可以设置直接响应。 | |
delegate | 否 | 本字段用于指定用于委托HTTPRoute的虚拟服务。 仅当route和redirect字段为空时才能设置本字段。委托虚拟服务的路由规则将与当前路由规则合并。 说明
| |
rewrite | 否 | 重写HTTP URI和Authority头部。重写不能与重定向原语一起使用。重写将在转发之前执行。 | |
timeout | 否 | HTTP请求的超时时间,默认禁用。 | |
retries | 否 | HTTP请求的重试策略。 | |
fault | 否 | 应用于客户端HTTP流量的故障注入策略。在客户端启用故障时,不会启用超时或重试。 | |
mirror | 否 | 除了将请求转发到预期目标外,将HTTP流量镜像到另一个目的地。镜像流量基于尽力而为的原则,即Sidecar或网关规则不会等待镜像集群响应后再返回原始目的地的响应。服务网格将为镜像目的地生成统计数据。 | |
mirrorPercentage | 否 | 被mirror字段镜像的流量百分比。如果该字段不存在,则所有流量(100%)都将被镜像。最大值为100。 | |
corsPolicy | 否 | 跨域资源共享策略(CORS)。关于跨域资源共享的更多信息,请参见CORS。 | |
headers | 否 | HTTP头部操作规则。 |
Delegate
指定委托的虚拟服务。例如,下方的虚拟服务中的路由规则将通过委托虚拟服务productpage来转发发往/productpage
的流量;通过委托虚拟服务reviews转发发往/reviews
的流量。被委托的虚拟服务的hosts字段必须为空。
字段 | 类型 | 是否必选 | 说明 |
name | string | 否 | 指定委托虚拟服务的名称。 |
namespace | string | 否 | 指定委托虚拟服务所在的命名空间。默认情况下,它与根虚拟服务相同。 |
Headers
当Envoy转发请求到达目标服务或从目标服务返回响应时,可以对消息的头部进行一些修改操作。Headers可以为特定路由目标或所有目标指定消息头的操纵规则。
字段 | 类型 | 是否必选 | 说明 |
request | 否 | 在将请求转发到目标服务之前应用的头部操作规则。 | |
response | 否 | 在向调用者返回响应之前应用的头部操作规则。 |
TLSRoute
TLSRoute定义对于unterminated TLS流量(TLS/HTTPS)的匹配条件和操作。
字段 | 类型 | 是否必选 | 说明 |
match | 是 | 激活规则需要满足的匹配条件。单个匹配块内的所有条件都具有AND语义,而匹配块列表具有OR语义。匹配将从第一个匹配块开始依次进行,任何一个匹配块成功匹配,都将执行此路由规则。 | |
route | 否 | 连接应该被转发到的目的地。 |
TCPRoute
TCPRoute定义用于路由TCP流量的匹配条件和操作。
字段 | 类型 | 是否必选 | 说明 |
match | 否 | 激活规则需要满足的匹配条件。单个匹配块内的所有条件都具有AND语义,而匹配块列表具有OR语义。匹配将从第一个匹配块开始依次进行,任何一个匹配块成功匹配,都将执行此路由规则。 | |
route | 否 | 连接应转发到的目的地。 |
HTTPMatchRequest
HTTPMatchRequest指定一组规则用于匹配HTTP请求。当配置HTTPMatchRequest字段时,下表中的字段需至少配置一个。
如果根VirtualService已经通过正则表达式匹配了任何属性(路径、头部等),则委托的VirtualService不应在相同属性上有任何其他匹配项。
如果委派的VirtualService已经通过正则表达式匹配了任何属性(路径、头部等),则根VirtualService不应在相同属性上有任何其他匹配项。
字段 | 类型 | 是否必选 | 说明 |
name | string | 否 | 匹配项的名称。匹配的名称将与父路由规则的名称拼接,并记录在与该路由匹配的请求的访问日志中。 |
uri | 否 | 匹配的URI,区分大小写。示例如下:
说明 支持通过配置项ignoreUriCase启用不区分大小写的匹配。 | |
scheme | 否 | URI Scheme值,区分大小写。示例如下:
| |
method | 否 | HTTP方法,区分大小写。示例如下:
| |
authority | 否 | HTTP Authority值,区分大小写。示例如下:
| |
headers | map<string, StringMatch> | 否 | 标头键必须小写并使用连字符(-)作为分隔符,例如x-request-id。 标头值区分大小写。示例如下:
说明
|
port | uint32 | 否 | 指定流量目标主机的端口。如果服务仅公开一个端口或者在端口名中使用了协议名进行标记(Istio要求服务端口名为 |
sourceLabels | map<string, string> | 否 | 请求的源工作负载应具有的标签,用于约束规则适用的源工作负载。 如果虚拟服务在顶级字段gateways中指定了网关,则它必须包含保留字mesh,本字段才会生效。 |
gateways | string[] | 否 | 应用路由规则的网关规则的名称。虚拟服务顶级字段gateways中指定的网关将被覆盖。网关的匹配独立于sourceLabels。 |
queryParams | map<string, StringMatch> | 否 | 用于匹配的查询参数。示例如下:
说明 目前暂不支持前缀匹配prefix。 |
ignoreUriCase | bool | 否 | 用于指定URI匹配是否不区分大小写。 说明 只有在使用exact和prefix的URI匹配时才会忽略大小写。 |
withoutHeaders | map<string, StringMatch> | 否 | withoutHeaders与header语法相同,但含义相反。如果一个标头匹配到withoutHeaders中的一条匹配规则,则该流量被判断为不匹配。 |
sourceNamespace | string | 否 | 请求源工作负载的命名空间。用于约束规则适用性的源工作负载的命名空间。 如果虚拟服务在顶级字段gateways中指定了网关,则它必须包含保留字mesh,本字段才会生效。 |
statPrefix | string | 否 | 为该路由生成统计信息时使用的前缀。统计信息生成时将会使用前缀 本字段应该针对高度关键的路由进行设置,以便获得路由粒度的统计信息。本字段仅适用于代理级别的统计数据( |
HTTPRouteDestination
每个路由规则都与一个或多个服务版本(子集)相关联。与该版本相关联的权重决定它接收的流量比例。
字段 | 类型 | 是否必选 | 说明 |
destination | 是 | Destination唯一标识应将请求或连接转发到的服务实例。 | |
weight | int32 | 否 | 指定要转发到目的地的流量的相对比例。目的地将接收weight或全部目的地weight总和的请求。如果规则中只有一个目的地,它将接收所有流量。若weight为0,目的地将不会收到任何流量。 |
headers | 否 | 标头操作规则。 |
RouteDestination
L4 (四层)级别的路由规则的加权目的地。
字段 | 类型 | 是否必选 | 说明 |
destination | 是 | Destination唯一标识应将请求或连接转发到的服务实例。 | |
weight | int32 | 否 | 指定要转发到目的地的流量的相对比例。目的地将接收weight或全部目的地weight总和的请求。如果规则中只有一个目的地,它将接收所有流量。若weight为0,目的地将不会收到任何流量。 |
L4MatchAttributes
L4级别连接的匹配属性。ASM对L4的连接匹配支持较为有限。
字段 | 类型 | 是否必选 | 说明 |
destinationSubnets | string[] | 否 | 目标的IPv4或IPv6地址,可以带有子网,例如 |
port | uint32 | 否 | 目标主机的端口。如果服务仅公开一个端口,则不需要显式指定端口。 |
sourceLabels | map<string, string> | 否 | 请求的源工作负载应该具有的标签,用于约束规则适用的源工作负载。 如果虚拟服务在顶级字段gateways中指定了网关,则必须包含保留字mesh,本字段才会生效。 |
gateways | string[] | 否 | 应用路由规则的网关规则的名称。虚拟服务顶级字段gateways中指定的网关将被覆盖。网关的匹配独立于sourceLabels。 |
sourceNamespace | string | 否 | 请求源工作负载的命名空间。用于约束规则适用性的源工作负载的命名空间。 如果虚拟服务在顶级字段gateways中指定了网关,则必须包含保留字mesh,本字段才会生效。 |
TLSMatchAttributes
TLS连接匹配属性。
字段 | 类型 | 是否必选 | 说明 |
sniHosts | string[] | 是 | 要匹配的SNI(服务器名称指示)。可以在SNI值中使用通配符前缀,例如 |
destinationSubnets | string[] | 否 | 目标的IPv4或IPv6地址,可以带有子网,例如 |
port | uint32 | 否 | 目标主机的端口。如果服务仅公开一个端口,则不需要显式指定端口。 |
sourceLabels | map<string, string> | 否 | 请求的源工作负载应该具有的标签,用于约束规则适用的源工作负载。 如果虚拟服务在顶级字段gateways中指定了网关,则它必须包含保留字mesh,本字段才会生效。 |
gateways | string[] | 否 | 应用路由规则的网关规则的名称。虚拟服务顶级字段gateways中指定的网关将被覆盖。网关的匹配独立于sourceLabels。 |
sourceNamespace | string | 否 | 请求源工作负载的命名空间。用于约束规则适用性的源工作负载的命名空间。 如果虚拟服务在顶级字段gateways中指定了网关,则必须包含保留字mesh,本字段才会生效。 |
HTTPRedirect
HTTPRedirect可用于向调用方发送301重定向响应,其中Authority
、Host
和响应中的URI可替换为指定的值。
字段 | 类型 | 是否必选 | 说明 |
uri | string | 否 | 在重定向时,用此值覆盖URL的路径部分。无论请求URI使用精确路径或前缀进行匹配,整个路径都将被替换。 |
authority | string | 否 | 在重定向时,用此值覆盖URL的 |
port | uint32 (oneof) | 否 | 在重定向时,用此值覆盖URL的端口部分。 |
derivePort | 否 | 在重定向时,动态设置端口。取值如下:
| |
scheme | string | 否 | 在重定向时,用此值覆盖URL的scheme部分,例如HTTP或HTTPS。如果未设置,将使用原来的scheme。 如果derivePort设置为FROM_PROTOCOL_DEFAULT,则本配置也会影响使用的端口。 |
redirectCode | uint32 | 否 | 在重定向时,指定重定向响应中要使用的HTTP状态码。默认响应代码为MOVED_PERMANENTLY(301)。 |
HTTPDirectResponse
HTTPDirectResponse可用于向客户端发送固定响应。
字段 | 类型 | 是否必选 | 说明 |
status | uint32 | 是 | 指定要返回的HTTP响应状态码。 |
body | 否 | 指定响应主体的内容。如果省略此配置,则生成的响应中不包含正文。 |
HTTPBody
字段 | 类型 | 是否必选 | 说明 |
string | string (oneof) | 否 | 作为字符串的响应主体。 |
bytes | bytes (oneof) | 否 | 响应主体为Base64编码字节。 |
HTTPRewrite
HTTPRewrite可用于在将请求转发到目标之前重写HTTP请求的特定部分。重写原语只能与HTTPRouteDestination一起使用。
字段 | 类型 | 是否必选 | 说明 |
uri | string | 否 | 使用本字段的值重写URI的路径(或前缀)部分。如果原始URI基于前缀匹配,则此字段中提供的值将替换相应的匹配前缀。 |
authority | string | 否 | 使用本字段的值重写 |
StringMatch
StringMatch定义如何匹配HTTP头部中的字符串。匹配区分大小写。
字段 | 类型 | 是否必选 | 说明 |
exact | string (oneof) | 否 | 精确的字符串匹配。 |
prefix | string (oneof) | 否 | 基于前缀的匹配。 |
regex | string (oneof) | 否 | RE2风格的基于正则表达式的匹配。更多信息,请参见wiki。 |
HTTPRetry
HTTPRetry定义在HTTP请求失败时使用的重试策略。例如,以下规则将在调用ratings:v1
服务时将最大重试次数设置为3,每次重试尝试的超时时间为2秒。如果发生连接失败、重置流(refused-stream)或上游服务器响应为服务不可用(503),则会尝试重试。
字段 | 类型 | 是否必选 | 说明 |
attempts | int32 | 是 | 请求允许重试的次数。重试之间的间隔将自动确定(一般大于25毫秒)。当配置了HTTP路由中的timeout或者perTryTimeout字段时,实际重试次数也取决于指定的请求超时时间和perTryTimeout值。 |
perTryTimeout | 否 | 对于给定的请求,在包括初始调用和任何重试在内的每次尝试中允许的超时时间。格式为 | |
retryOn | string | 否 | 指定重试发生的条件。可以使用英文半角逗号(,)分隔列表来指定一个或多个策略。如果retry_on指定了一个有效的HTTP状态码,它将被添加到Envoy的retriable_status_codes重试策略中。更多信息,请参见重试策略和gRPC重试策略。 |
retryRemoteLocalities | 否 | 用于指定重试是否应重试到其他地址的标志。更多信息,请参见重试插件配置。 |
CorsPolicy
CorsPolicy定义给定服务的跨源资源共享(CORS)策略。关于跨源资源共享的更多信息,请参见CORS。
字段 | 类型 | 是否必选 | 说明 |
allowOrigins | 否 | 用于匹配允许来源的字符串模式列表。如果任何一个模式匹配成功,则允许此来源。如果匹配,则响应的Access-Control-Allow-Origin将设置为客户端提供的Origin。 | |
allowMethods | string[] | 否 | 允许访问资源的HTTP方法列表。值将被序列化到Access-Control-Allow-Methods标头中。 |
allowHeaders | string[] | 否 | 请求资源时可以使用的HTTP标头列表。值将被序列化到Access-Control-Allow-Headers标头中。 |
exposeHeaders | string[] | 否 | 允许浏览器访问的HTTP标头列表。值将被序列化到Access-Control-Expose-Headers标头中。 |
maxAge | 否 | 设定预检请求的结果可以缓存的时间。值将会写入Access-Control-Max-Age标头中。 | |
allowCredentials | 否 | 设定是否允许调用这使用证书发送实际请求(而非预检)。值将会写入Access-Control-Allow-Credentials标头中。 |
HTTPFaultInjection
HTTPFaultInjection可以在将HTTP请求转发到路由中指定的目标时注入一个或多个故障。故障规则是虚拟服务规则的一部分。可添加的故障包括直接中止来自下游服务的HTTP请求,或者为请求添加延迟。如果定义了故障规则,则其中必须至少包含延迟或中止。
延迟和中止故障相互独立,即使是在同时指定的情况下。
字段 | 类型 | 是否必选 | 说明 |
delay | 否 | 在转发请求之前延迟一段时间,可以模拟例如网络问题,上游服务过载等故障。 | |
abort | 否 | 中止HTTP请求并将错误代码返回给下游服务,制造出一种上游服务出现故障的情景。 |
PortSelector
PortSelector指定用于匹配的端口号。
字段 | 类型 | 是否必选 | 说明 |
number | uint32 | 否 | 有效端口号。 |
Percent
字段 | 类型 | 是否必选 | 说明 |
value | double | 否 | 指定[0.0,100.0]范围内的百分比。 |
Headers.HeaderOperations
HeaderOperations定义要应用的标头操作。
字段 | 类型 | 是否必选 | 说明 |
set | map<string, string> | 否 | 用给定的值覆盖键指定的标头。 |
add | map<string, string> | 否 | 将给定值附加到由键指定的标头,将创建一个英文半角逗号(,)分隔的值列表。 |
remove | string[] | 否 | 删除指定的标头。 |
HTTPFaultInjection.Delay
延迟规范用于为请求转发路径添加延迟。
字段 | 类型 | 是否必选 | 说明 |
fixedDelay | 是 | 在转发请求之前添加固定延迟。格式为 | |
percentage | 否 | 注入延迟的请求的百分比。如果未指定,则不会延迟任何请求。 | |
percent | int32 | 否 | 使用int类型表示的注入延迟的请求百分比,取值为[0,100]。 重要 本字段已被标记为已废弃,请使用double类型的percentage。 |
HTTPFaultInjection.Abort
中止规范用于提前中止请求并返回指定的错误码。
字段 | 类型 | 是否必选 | 说明 |
httpStatus | int32 | 是 | 用于中止HTTP请求的HTTP状态码。 |
grpcStatus | string(oneof) | 否 | 用于中止请求的GRPC状态码。更多信息,请参见statuscodes.md。 若您需要返回状态 说明
|
percentage | 否 | 中止请求的百分比。如果未指定,则不会中止任何请求。 |
google.protobuf.UInt32Value
uint32的包装信息。
字段 | 类型 | 是否必选 | 说明 |
value | uint32 | 否 | uint32值。在JSON中该值需为一个JSON数字值。 |
HTTPRedirect.RedirectPortSelection
derivePort定义可以使用的枚举值。
字段 | 说明 |
FROM_PROTOCOL_DEFAULT | 对于HTTP自动设置为80,对于HTTPS自动设置为443。 |
FROM_REQUEST_PORT | 自动使用请求的端口。 |