A virtual service is a key resource that Service Mesh (ASM) uses to manage traffic routing. It defines a set of routing rules for traffic sent to a specified destination host. Each rule defines specific conditions for matching traffic. If traffic matches a rule, it is forwarded to the destination service or a service version (subset) specified in the rule. This topic describes the configuration examples and fields of the Virtual Service Custom Resource Definition (CRD).
Configuration example
The following example shows how requests are routed to different versions of a service based on the request host. These versions, or subsets, are defined in a destination rule (DestinationRule). For more information, see Destination Rule CRD Description.
The virtual service matches all requests sent to the reviews host in the mesh. If an HTTP request contains the end-user:jason header, the request is forwarded to version v2 of the reviews service. Otherwise, the request is forwarded to version v3 of the reviews service.
Field descriptions
VirtualService
Defines configurations for traffic routing.
Field | Type | Required | Description |
hosts | string[] | No | The destination hosts for the traffic to match. You can specify DNS names with a wildcard prefix or IP addresses. In Kubernetes, you can also use short names, such as The hosts field applies to HTTP and TCP services. Services within the mesh, such as services registered in the cluster's service registry, must always be referenced by their DNS names. Services defined in the hosts field can be referenced by IP addresses only in a Gateway. Note If you want to use the virtual service as a delegate VirtualService, this field must be empty. |
gateways | string[] | No | The names of the gateways and sidecars to which the routing rules apply. You can reference a gateway in another namespace using The reserved word mesh indicates all sidecars in the mesh.
|
http | No | An ordered list of routing rules for HTTP traffic. The HTTP routing rules apply to service ports with names that start with | |
tls | TLSRoute[] | No | An ordered list of routing rules for non-terminated TLS and HTTPS traffic. Routing is typically performed based on the Server Name Indication (SNI) value provided in the ClientHello message. The TLS routing rules apply to service ports with names that start with Note Without an associated virtual service, traffic on |
tcp | TCPRoute[] | No | An ordered list of routing rules for opaque TCP traffic. The TCP routing rules apply to any port that is not an HTTP or TLS port. The first rule that matches the incoming request is used. |
exportTo | string[] | No | The namespaces to which this virtual service is exported. After a virtual service is exported, sidecars and gateways defined in other namespaces can reference the virtual service. This feature provides a way for service owners and mesh administrators to control the visibility of virtual services across namespace boundaries. If you do not specify a namespace, the virtual service is exported to all namespaces by default. The reserved word |
Destination
Destination defines a network-addressable service that receives requests or connections after they are processed by a routing rule. The destination.host must explicitly point to a service in the service registry. The Istio service registry contains all services from the platform's service registry, such as Kubernetes services and Consul services, and services that are declared using ServiceEntry resources.
Notes for Kubernetes:
When you use a short name, such as
reviewsinstead ofreviews.default.svc.cluster.local, Istio resolves the short name based on the namespace of the routing rule, not the service.A rule in the default namespace that contains a host named `reviews` is interpreted as
reviews.default.svc.cluster.local, regardless of the actual namespace of the reviews service. To avoid potential configuration errors, always use fully qualified domain names instead of short names.
Field | Type | Required | Description |
host | string | Yes | The name of the service in the service registry. The service name is looked up in the platform's service registry (such as Kubernetes services or Consul services) and the hosts declared in ServiceEntry resources. If the service is not found, traffic forwarded to this destination is dropped. |
subset | string | No | The name of the service version (subset). This applies only to services within the mesh. The version must be defined in the corresponding destination rule for the service. |
port | No | Specifies the port on the destination host to which traffic is sent. If the service exposes only one port, you do not need to explicitly select a port. |
HTTPRoute
HTTPRoute defines the matching conditions and operations for HTTP/1.1, HTTP/2, and gRPC traffic.
Field | Type | Required | Description |
name | string | No | The name set for the route for debugging purposes. The route name is concatenated with the name of the matching condition and recorded in the access log for requests that match this route or matching item. |
match | No | The matching conditions that must be met to activate the rule. All conditions within a single match block have AND semantics, while the list of match blocks has OR semantics. Matching proceeds sequentially from the first match block. If any match block is successfully matched, this routing rule is executed. | |
route | No | For a matched request, an HTTP rule can perform routing operations, including sending a direct response, redirecting, or forwarding traffic. This field is used to set traffic forwarding rules. The traffic forwarding destination can be a service or a service version (subset). You can configure weights for service versions to determine the proportion of traffic they receive. | |
redirect | No | For a matched request, an HTTP rule can perform routing operations, including sending a direct response, redirecting, or forwarding traffic. This field is used to set redirect rules. The redirect primitive can be used to send an HTTP 301 redirect to a different URI or Authority. If traffic passthrough is specified in the destination rule ( | |
directResponse | No | For a matched request, an HTTP rule can perform routing operations, including sending a direct response, redirecting, and forwarding traffic. This field is used to set direct response rules. A direct response can be used to specify a fixed response to be sent to the client. A direct response can be set only when the route and redirect fields are empty. | |
delegate | No | This field specifies the virtual service to which the HTTPRoute is delegated. This field can be set only when the route and redirect fields are empty. The routing rules of the delegated virtual service are merged with the current routing rule. Note
| |
rewrite | No | Rewrites the HTTP URI and Authority header. The rewrite primitive cannot be used with the redirect primitive. Rewriting is performed before forwarding. | |
timeout | No | The timeout for HTTP requests. Disabled by default. | |
retries | No | The retry policy for HTTP requests. | |
fault | No | The fault injection policy to apply to client HTTP traffic. When fault injection is enabled on the client, timeouts and retries are not enabled. | |
mirror | No | In addition to forwarding requests to the intended destination, mirrors HTTP traffic to another destination. Traffic mirroring is performed on a best-effort basis. This means the sidecar or gateway does not wait for a response from the mirrored cluster before returning the response from the original destination. Service Mesh generates statistics for the mirrored destination. | |
mirrorPercentage | No | The percentage of traffic that is mirrored by the mirror field. If this field is not present, all traffic (100%) is mirrored. The maximum value is 100. | |
corsPolicy | No | The cross-origin resource sharing (CORS) policy. For more information about CORS, see CORS. | |
headers | No | The HTTP header manipulation rules. |
Delegate
Delegate specifies a delegated virtual service. For example, the routing rule in the following virtual service forwards traffic for /productpage by delegating to the `productpage` virtual service and forwards traffic for /reviews by delegating to the `reviews` virtual service. The hosts field of the delegated virtual service must be empty.
Field | Type | Required | Description |
name | string | No | Specifies the name of the delegated virtual service. |
namespace | string | No | Specifies the namespace where the delegated virtual service resides. By default, it is the same as the root virtual service. |
Headers
You can modify message headers when Envoy forwards a request to a destination service or returns a response from it. Headers specifies header manipulation rules for a specific route destination or for all destinations.
Field | Type | Required | Description |
request | No | Header manipulation rules to apply before forwarding a request to the destination service. | |
response | No | Header manipulation rules to apply before returning a response to the caller. |
TLSRoute
TLSRoute defines the matching conditions and operations for unterminated TLS (TLS/HTTPS) traffic.
Field | Type | Required | Description |
match | Yes | The matching conditions that must be met to activate the rule. All conditions within a single match block have AND semantics, while the list of match blocks has OR semantics. Matching proceeds sequentially from the first match block. If any match block is successfully matched, this routing rule is executed. | |
route | No | The destination to which the connection should be forwarded. |
TCPRoute
TCPRoute defines the matching conditions and operations for routing TCP traffic.
Field | Type | Required | Description |
match | No | The matching conditions that must be met to activate the rule. All conditions within a single match block have AND semantics, while the list of match blocks has OR semantics. Matching proceeds sequentially from the first match block. If any match block is successfully matched, this routing rule is executed. | |
route | No | The destination to which the connection should be forwarded. |
HTTPMatchRequest
HTTPMatchRequest specifies a set of rules for matching HTTP requests. If you configure the HTTPMatchRequest field, you must configure at least one of the fields in the following table.
If the root VirtualService matches an attribute, such as path or headers, using a regular expression, the delegated VirtualService must not have other matches on the same attribute.
If the delegated VirtualService matches an attribute, such as path or headers, using a regular expression, the root VirtualService must not have other matches on the same attribute.
Field | Type | Required | Description |
name | string | No | The name of the matching item. The name of the match is concatenated with the name of the parent routing rule and recorded in the access log for requests that match this route. |
uri | No | The URI to match, which is case-sensitive. Examples:
Note You can enable case-insensitive matching using the ignoreUriCase configuration item. | |
scheme | No | The URI scheme value, which is case-sensitive. Examples:
| |
method | No | The HTTP method, which is case-sensitive. Examples:
| |
authority | No | The HTTP Authority value, which is case-sensitive. Examples:
| |
headers | map<string, StringMatch> | No | Header keys must be lowercase and use a hyphen (-) as a separator, such as x-request-id. Header values are case-sensitive. Examples:
Note
|
port | uint32 | No | Specifies the port on the destination host to which traffic is sent. If the service exposes only one port or if the port name is marked with the protocol name (Istio requires service port names to be in the |
sourceLabels | map<string, string> | No | The labels that the source workload of the request should have. This is used to constrain the source workloads to which the rule applies. If the virtual service specifies a gateway in the top-level gateways field, it must include the reserved word mesh for this field to take effect. |
gateways | string[] | No | The names of the gateways to which the routing rule applies. The gateways specified in the top-level gateways field of the virtual service are overwritten. The gateway match is independent of sourceLabels. |
queryParams | map<string, StringMatch> | No | The query parameters to match. Examples:
Note Prefix matching is not currently supported. |
ignoreUriCase | bool | No | Specifies whether the URI match is case-insensitive. Note Case is ignored only for URI matching with exact and prefix. |
withoutHeaders | map<string, StringMatch> | No | withoutHeaders has the same syntax as header but with the opposite meaning. If a header matches a rule in withoutHeaders, the traffic is considered not to match. |
sourceNamespace | string | No | The namespace of the source workload of the request. This is used to constrain the namespace of the source workloads to which the rule applies. If the virtual service specifies a gateway in the top-level gateways field, it must include the reserved word mesh for this field to take effect. |
statPrefix | string | No | The prefix to use when generating statistics for this route. The prefix This field should be set for highly critical routes to obtain route-granularity statistics. This field applies only to proxy-level statistics ( |
HTTPRouteDestination
Each routing rule is associated with one or more service versions (subsets). The weight associated with a version determines the proportion of traffic it receives.
Field | Type | Required | Description |
destination | Yes | Destination uniquely identifies the service instance to which requests or connections should be forwarded. | |
weight | int32 | No | Specifies the relative proportion of traffic to forward to the destination. The destination receives `weight` / sum of `weight` of all destinations. If there is only one destination in the rule, it receives all traffic. If the weight is 0, the destination does not receive any traffic. |
headers | No | Header manipulation rules. |
RouteDestination
RouteDestination specifies a weighted destination for Layer 4 (L4) routing rules.
Field | Type | Required | Description |
destination | Yes | Destination uniquely identifies the service instance to which requests or connections should be forwarded. | |
weight | int32 | No | Specifies the relative proportion of traffic to forward to the destination. The destination receives `weight` / sum of `weight` of all destinations. If there is only one destination in the rule, it receives all traffic. If the weight is 0, the destination does not receive any traffic. |
L4MatchAttributes
L4MatchAttributes specifies the matching attributes for L4 connections. ASM has limited support for L4 connection matching.
Field | Type | Required | Description |
destinationSubnets | string[] | No | The destination IPv4 or IPv6 address, which can be specified with a subnet, such as |
port | uint32 | No | The port on the destination host. If the service exposes only one port, you do not need to explicitly specify the port. |
sourceLabels | map<string, string> | No | The labels that the source workload of the request should have. This is used to constrain the source workloads to which the rule applies. If the virtual service specifies a gateway in the top-level gateways field, it must include the reserved word mesh for this field to take effect. |
gateways | string[] | No | The names of the gateways to which the routing rule applies. The gateways specified in the top-level gateways field of the virtual service are overwritten. The gateway match is independent of sourceLabels. |
sourceNamespace | string | No | The namespace of the source workload of the request. This is used to constrain the namespace of the source workloads to which the rule applies. If the virtual service specifies a gateway in the top-level gateways field, it must include the reserved word mesh for this field to take effect. |
TLSMatchAttributes
Properties for TLS connection matching.
Field | Type | Required | Description |
sniHosts | string[] | Yes | The Server Name Indication (SNI) to match. You can use a wildcard prefix in the SNI value. For example, |
destinationSubnets | string[] | No | The destination IPv4 or IPv6 address, which can be specified with a subnet, such as |
port | uint32 | No | The port on the destination host. If the service exposes only one port, you do not need to explicitly specify the port. |
sourceLabels | map<string, string> | No | The labels that the source workload of the request should have. This is used to constrain the source workloads to which the rule applies. If the virtual service specifies a gateway in the top-level gateways field, it must include the reserved word mesh for this field to take effect. |
gateways | string[] | No | The names of the gateways to which the routing rule applies. The gateways specified in the top-level gateways field of the virtual service are overwritten. The gateway match is independent of sourceLabels. |
sourceNamespace | string | No | The namespace of the source workload of the request. This is used to constrain the namespace of the source workloads to which the rule applies. If the virtual service specifies a gateway in the top-level gateways field, it must include the reserved word mesh for this field to take effect. |
HTTPRedirect
HTTPRedirect sends a 301 redirect response to the caller. The Authority, Host, and URI in the response can be replaced with specified values.
Field | Type | Required | Description |
uri | string | No | When redirecting, overwrites the path portion of the URL with this value. The entire path is replaced, regardless of whether the request URI was matched with an exact path or a prefix. |
authority | string | No | When redirecting, overwrites the |
port | uint32 (oneof) | No | When redirecting, overwrites the port portion of the URL with this value. |
derivePort | No | Dynamically sets the port during redirection. The values are as follows:
| |
scheme | string | No | When redirecting, overwrites the scheme portion of the URL with this value, such as HTTP or HTTPS. If not set, the original scheme is used. If derivePort is set to FROM_PROTOCOL_DEFAULT, this configuration also affects the port used. |
redirectCode | uint32 | No | When redirecting, specifies the HTTP status code to use in the redirect response. The default response code is MOVED_PERMANENTLY (301). |
HTTPDirectResponse
HTTPDirectResponse sends a fixed response to the client.
Field | Type | Required | Description |
status | uint32 | Yes | Specifies the HTTP response status code to return. |
body | No | Specifies the content of the response body. If this configuration is omitted, the generated response does not include a body. |
HTTPBody
Field | Type | Required | Description |
string | string (oneof) | No | The response body as a string. |
bytes | bytes (oneof) | No | The response body as Base64-encoded bytes. |
HTTPRewrite
HTTPRewrite rewrites specific parts of an HTTP request before the request is forwarded to the destination. The rewrite primitive can be used only with HTTPRouteDestination.
Field | Type | Required | Description |
uri | string | No | Rewrites the path (or prefix) portion of the URI with the value of this field. If the original URI was matched based on a prefix, the value provided in this field replaces the corresponding matched prefix. |
authority | string | No | Rewrites the |
StringMatch
StringMatch defines how to match a string in an HTTP header. The match is case-sensitive.
Field | Type | Required | Description |
exact | string (oneof) | No | Exact string match. |
prefix | string (oneof) | No | Prefix-based match. |
regex | string (oneof) | No | RE2-style regular expression-based match. For more information, see the wiki. |
HTTPRetry
HTTPRetry defines the retry policy to use when an HTTP request fails. For example, the following rule sets the maximum number of retries to 3 when calling the ratings:v1 service, with a 2-second timeout for each retry attempt. Retries are attempted for connection failures, refused streams, or 503 (service unavailable) responses from the upstream server.
Field | Type | Required | Description |
attempts | int32 | Yes | The number of times a request is allowed to be retried. The interval between retries is determined automatically (generally greater than 25 ms). When the timeout or perTryTimeout field is configured in the HTTP route, the actual number of retries also depends on the specified request timeout and the perTryTimeout value. |
perTryTimeout | No | The timeout allowed for each attempt of a given request, including the initial call and any retries. The format is | |
retryOn | string | No | Specifies the conditions under which a retry occurs. You can specify one or more policies in a comma-separated list. If retry_on specifies a valid HTTP status code, it is added to Envoy's retriable_status_codes retry policy. For more information, see Retry policies and gRPC retry policies. |
retryRemoteLocalities | No | A flag that specifies whether retries should be attempted on other localities. For more information, see Retry plugin configuration. |
CorsPolicy
CorsPolicy defines the cross-origin resource sharing (CORS) policy for a service. For more information about CORS, see CORS.
Field | Type | Required | Description |
allowOrigins | No | A list of string patterns used to match allowed origins. If any pattern matches, the origin is allowed. If a match occurs, the Access-Control-Allow-Origin header in the response is set to the origin provided by the client. | |
allowMethods | string[] | No | A list of HTTP methods that are allowed to access the resource. The values are serialized into the Access-Control-Allow-Methods header. |
allowHeaders | string[] | No | A list of HTTP headers that can be used when requesting the resource. The values are serialized into the Access-Control-Allow-Headers header. |
exposeHeaders | string[] | No | A list of HTTP headers that the browser is allowed to access. The values are serialized into the Access-Control-Expose-Headers header. |
maxAge | No | Sets the duration for which the result of a preflight request can be cached. The value is written to the Access-Control-Max-Age header. | |
allowCredentials | No | Indicates whether the caller is allowed to send the actual request (not the preflight request) using credentials. The value is written to the Access-Control-Allow-Credentials header. |
HTTPFaultInjection
HTTPFaultInjection injects one or more faults when an HTTP request is forwarded to the destination specified in the route. Fault rules are part of the virtual service rules. You can inject faults, such as aborting HTTP requests from downstream services or adding a delay to requests. If a fault rule is defined, it must include at least a delay or an abort.
Delay and abort faults are independent, even when specified at the same time.
Field | Type | Required | Description |
delay | No | Delays for a period of time before forwarding the request. This can be used to simulate faults such as network issues or an overloaded upstream service. | |
abort | No | Aborts an HTTP request and returns an error code to the downstream service. This can be used to simulate a failure of the upstream service. |
PortSelector
PortSelector specifies the port number to match.
Field | Type | Required | Description |
number | uint32 | No | A valid port number. |
Percent
Field | Type | Required | Description |
value | double | No | Specifies a percentage in the range of [0.0, 100.0]. |
Headers.HeaderOperations
HeaderOperations defines the header operations to apply.
Field | Type | Required | Description |
set | map<string, string> | No | Overwrites the header specified by the key with the given value. |
add | map<string, string> | No | Appends the given value to the header specified by the key, creating a comma-separated list of values. |
remove | string[] | No | Removes the specified headers. |
HTTPFaultInjection.Delay
A delay specification adds a delay to the request forwarding path.
Field | Type | Required | Description |
fixedDelay | Yes | Adds a fixed delay before forwarding the request. The format is | |
percentage | No | The percentage of requests to which the delay is injected. If not specified, no requests are delayed. | |
percent | int32 | No | The percentage of requests to which the delay is injected, represented as an int type with a value in the range of [0, 100]. Important This field is deprecated. Use the double-typed percentage. |
HTTPFaultInjection.Abort
An abort rule aborts a request and returns a specified error code.
Field | Type | Required | Description |
httpStatus | int32 | Yes | The HTTP status code used to abort the HTTP request. |
grpcStatus | string(oneof) | No | The gRPC status code used to abort the request. For more information, see statuscodes.md. To return the status Note
|
percentage | No | The percentage of requests to abort. If not specified, no requests are aborted. |
google.protobuf.UInt32Value
A wrapper message for uint32.
Field | Type | Required | Description |
value | uint32 | No | The uint32 value. In JSON, this value must be a JSON number. |
HTTPRedirect.RedirectPortSelection
derivePort defines the enumeration values that can be used.
Field | Description |
FROM_PROTOCOL_DEFAULT | Automatically sets the port to 80 for HTTP and 443 for HTTPS. |
FROM_REQUEST_PORT | Automatically uses the port of the request. |