consul/website/content/docs/connect/config-entries/service-splitter.mdx

788 lines
25 KiB
Markdown

---
layout: docs
page_title: Service Splitter configuration reference
description: >-
Service splitter configuration entries are L7 traffic management tools for redirecting requests for a service to
multiple instances. Learn how to write `service-splitter` config entries in HCL or YAML with a specification
reference, configuration model, a complete example, and example code by use case.
---
# Service Splitter configuration reference
This reference page describes the structure and contents of service splitter configuration entries. Configure and apply service splitters to redirect a percentage of incoming traffic requests for a service to one or more specific service instances.
## Configuration model
The following list outlines field hierarchy, language-specific data types, and requirements in a service splitter configuration entry. Click on a property name to view additional details, including default values.
<Tabs>
<Tab heading="HCL and JSON" group="hcl">
- [`Kind`](#kind): string | required
- [`Name`](#name): string | required
- [`Namespace`](#namespace): string <EnterpriseAlert inline />
- [`Partition`](#partition): string <EnterpriseAlert inline />
- [`Meta`](#meta): map
- [`Splits`](#splits): map | required
- [`Weight`](#splits-weight): number | required
- [`Service`](#splits-service): string | required
- [`ServiceSubset`](#splits-servicesubset): string
- [`Namespace`](#splits-namespace): string <EnterpriseAlert inline />
- [`Partition`](#splits-partition): string <EnterpriseAlert inline />
- [`RequestHeaders`](#splits-requestheaders): map
- [`Add`](#splits-requestheaders): map
- [`Set`](#splits-requestheaders): map
- [`Remove`](#splits-requestheaders): map
- [`ResponseHeaders`](#splits-responseheaders): map
- [`Add`](#splits-responseheaders): map
- [`Set`](#splits-responseheaders): map
- [`Remove`](#splits-responseheaders): map
</Tab>
<Tab heading="YAML" group="yaml">
- [`apiVersion`](#apiversion): string | required
- [`kind`](#kind): string | required
- [`metadata`](#metadata): object | required
- [`name`](#metadata-name): string | required
- [`namespace`](#metadata-namespace): string | optional <EnterpriseAlert inline />
- [`spec`](#spec): object | required
- [`splits`](#spec-splits): list | required
- [`weight`](#spec-splits-weight): float32 | required
- [`service`](#spec-splits-service): string | required
- [`serviceSubset`](#spec-splits-servicesubset): string
- [`namespace`](#spec-splits-namespace): string <EnterpriseAlert inline />
- [`partition`](#spec-splits-partition): string <EnterpriseAlert inline />
- [`requestHeaders`](#spec-splits-requestheaders): HTTPHeaderModifiers
- [`add`](#spec-splits-requestheaders): map
- [`set`](#spec-splits-requestheaders): map
- [`remove`](#spec-splits-requestheaders): map
- [`responseHeaders`](#spec-splits-responseheaders): HTTPHeaderModifiers
- [`add`](#spec-splits-responseheaders): map
- [`set`](#spec-splits-responseheaders): map
- [`remove`](#spec-splits-responseheaders): map
</Tab>
</Tabs>
## Complete configuration
When every field is defined, a service splitter configuration entry has the following form:
<Tabs>
<Tab heading="HCL" group="hcl">
```hcl
Kind = "service-splitter" ## string | required
Name = "config-entry-name" ## string | required
Namespace = "main" ## string
Partition = "partition" ## string
Meta = { ## map
key = "value"
}
Splits = [ ## list | required
{ ## map
Weight = 90 ## number | required
Service = "service" ## string
ServiceSubset = "v1" ## string
Namespace = "target-namespace" ## string
Partition = "target-partition" ## string
RequestHeaders = { ## map
Set = {
"X-Web-Version" : "from-v1"
}
}
ResponseHeaders = { ## map
Set = {
"X-Web-Version" : "to-v1"
}
}
},
{
Weight = 10
Service = "service"
ServiceSubset = "v2"
Namespace = "target-namespace"
Partition = "target-partition"
RequestHeaders = {
Set = {
"X-Web-Version" : "from-v2"
}
}
ResponseHeaders = {
Set = {
"X-Web-Version" : "to-v2"
}
}
}
]
```
</Tab>
<Tab heading="JSON" group="json">
```json
{
"Kind" : "service-splitter", ## string | required
"Name" : "config-entry-name", ## string | required
"Namespace" : "main", ## string
"Partition" : "partition", ## string
"Meta" : { ## map
"_key_" : "_value_"
},
"Splits" : [ ## list | required
{ ## map
"Weight" : 90, ## number | required
"Service" : "service", ## string
"ServiceSubset" : "v1", ## string
"Namespace" : "target-namespace", ## string
"Partition" : "target-partition", ## string
"RequestHeaders" : { ## map
"Set" : {
"X-Web-Version": "from-v1"
}
},
"ResponseHeaders" : { ## map
"Set" : {
"X-Web-Version": "to-v1"
}
}
},
{
"Weight" : 10,
"Service" : "service",
"ServiceSubset" : "v2",
"Namespace" : "target-namespace",
"Partition" : "target-partition",
"RequestHeaders" : {
"Set" : {
"X-Web-Version": "from-v2"
}
},
"ResponseHeaders" : {
"Set" : {
"X-Web-Version": "to-v2"
}
}
}
]
}
```
</Tab>
<Tab heading="YAML" group="yaml">
```yaml
apiVersion: consul.hashicorp.com/v1alpha1 # string | required
kind: ServiceSplitter # string | required
metadata: # object | required
name: config-entry-name # string | required
namespace: main # string
spec:
splits: # list
- weight: 90 # floating point | required
service: service # string
serviceSubset: v1 # string
namespace: target-namespace # string
partition: target-partition # string
requestHeaders:
set:
x-web-version: from-v1 # string
responseHeaders:
set:
x-web-version: to-v1 # string
- weight: 10
service: service
serviceSubset: v2
namespace: target-namespace
partition: target-partition
requestHeaders:
set:
x-web-version: from-v2
responseHeaders:
set:
x-web-version: to-v2
```
</Tab>
</Tabs>
## Specification
This section provides details about the fields you can configure in the service splitter configuration entry.
<Tabs>
<Tab heading="HCL" group="hcl">
### `Kind`
Specifies the type of configuration entry to implement.
#### Values
- Default: none
- This field is required.
- Data type: String value that must be set to `service-splitter`.
### `Name`
Specifies a name for the configuration entry. The name is metadata that you can use to reference the configuration entry when performing Consul operations, such as applying a configuration entry to a specific cluster.
#### Values
- Default: Defaults to the name of the node after writing the entry to the Consul server.
- This field is required.
- Data type: String
### `Namespace` <EnterpriseAlert inline />
Specifies the [namespace](/consul/docs/enterprise/namespaces) to apply the configuration entry.
#### Values
- Default: None
- Data type: String
### `Partition` <EnterpriseAlert inline />
Specifies the [admin partition](/consul/docs/enterprise/admin-partitions) to apply the configuration entry.
#### Values
- Default: `Default`
- Data type: String
### `Meta`
Specifies key-value pairs to add to the KV store.
#### Values
- Default: none
- Data type: Map of one or more key-value pairs
- keys: String
- values: String, integer, or float
### `Splits`
Defines how much traffic to send to sets of service instances during a traffic split.
#### Values
- Default: None
- This field is required.
- Data type: list of objects that can contain the following fields:
- `Weight`: The sum of weights for a set of service instances must add up to 100.
- `Service`: This field is required.
- `ServiceSubset`
- `Namespace` <Enterprise inline/>
- `Partition` <Enterprise inline/>
- `RequestHeaders`
- `ResponseHeaders`
### `Splits[].Weight`
Specifies the percentage of traffic sent to the set of service instances specified in the [`Service`](#service) field. Each weight must be a floating integer between `0` and `100`. The smallest representable value is `.01`. The sum of weights across all splits must add up to `100`.
#### Values
- Default: `null`
- This field is required.
- Data type: Floating number from `.01` to `100`.
### `Splits[].Service`
Specifies the name of the service to resolve.
#### Values
- Default: Inherits the value of the [`Name`](#name) field.
- Data type: String
### `Splits[].ServiceSubset`
Specifies a subset of the service to resolve. A service subset assigns a name to a specific subset of discoverable service instances within a datacenter, such as `version2` or `canary`. All services have an unnamed default subset that returns all healthy instances.
You can define service subsets in a [service resolver configuration entry](/consul/docs/connect/config-entries/service-resolver), which are referenced by their names throughout the other configuration entries. This field overrides the default subset value in the service resolver configuration entry.
#### Values
- Default: If empty, the `split` uses the default subset.
- Data type: String
### `Splits[].Namespace` <EnterpriseAlert inline />
Specifies the [namespace](/consul/docs/enterprise/namespaces) to use in the FQDN when resolving the service.
#### Values
- Default: Inherits the value of [`Namespace`](#Namespace) from the top-level of the configuration entry.
- Data type: String
### `Splits[].Partition` <EnterpriseAlert inline />
Specifies the [admin partition](/consul/docs/enterprise/admin-partitions) to use in the FQDN when resolving the service.
#### Values
- Default: By default, the `service-splitter` uses the [admin partition specified in the top-level configuration entry](#partition).
- Data type: String
### `Splits[].RequestHeaders`
Specifies a set of HTTP-specific header modification rules applied to requests routed with the service split. You cannot configure request headers if the listener protocol is set to `tcp`. Refer to [Set HTTP Headers](#set-http-headers) for an example configuration.
#### Values
- Default: None
- Values: Object containing one or more fields that define header modification rules
- `Add`: Map of one or more key-value pairs
- `Set`: Map of one or more key-value pairs
- `Remove`: Map of one or more key-value pairs
The following table describes how to configure values for request headers:
| Rule | Description | Type |
| --- | --- | --- |
| `Add` | Defines a set of key-value pairs to add to the header. Use header names as the keys. Header names are not case-sensitive. If header values with the same name already exist, the value is appended and Consul applies both headers. You can [use variable placeholders](#use-variable-placeholders). | map of strings |
| `Set` | Defines a set of key-value pairs to add to the request header or to replace existing header values with. Use header names as the keys. Header names are not case-sensitive. If header values with the same names already exist, Consul replaces the header values. You can [use variable placeholders](#use-variable-placeholders). | map of strings |
| `Remove` | Defines an list of headers to remove. Consul removes only headers containing exact matches. Header names are not case-sensitive. | list of strings |
#### Use variable placeholders
For `Add` and `Set`, if the service is configured to use Envoy as the proxy, the value may contain variables to interpolate dynamic metadata into the value. For example, using the variable `%DOWNSTREAM_REMOTE_ADDRESS%` in your configuration entry allows you to pass a value that is generated when the split occurs.
### `Splits[].ResponseHeaders`
Specifies a set of HTTP-specific header modification rules applied to responses routed with the service split. You cannot configure request headers if the listener protocol is set to `tcp`. Refer to [Set HTTP Headers](#set-http-headers) for an example configuration.
#### Values
- Default: None
- Values: Object containing one or more fields that define header modification rules
- `Add`: Map of one or more string key-value pairs
- `Set`: Map of one or more string key-value pairs
- `Remove`: Map of one or more string key-value pairs
The following table describes how to configure values for response headers:
| Rule | Description | Type |
| --- | --- | --- |
| `Add` | Defines a set of key-value pairs to add to the header. Use header names as the keys. Header names are not case-sensitive. If header values with the same name already exist, the value is appended and Consul applies both headers. You can [use variable placeholders](#use-variable-placeholders). | map of strings |
| `Set` | Defines a set of key-value pairs to add to the request header or to replace existing header values with. Use header names as the keys. Header names are not case-sensitive. If header values with the same names already exist, Consul replaces the header values. You can [use variable placeholders](#use-variable-placeholders). | map of strings |
| `Remove` | Defines an list of headers to remove. Consul removes only headers containing exact matches. Header names are not case-sensitive. | list of strings |
#### Use variable placeholders
For `Add` and `Set`, if the service is configured to use Envoy as the proxy, the value may contain variables to interpolate dynamic metadata into the value. For example, using the variable `%DOWNSTREAM_REMOTE_ADDRESS%` in your configuration entry allows you to pass a value that is generated when the split occurs.
</Tab>
<Tab heading="YAML" group="yaml">
### `apiVersion`
Kubernetes-only parameter that specifies the version of the Consul API that the configuration entry maps to Kubernetes configurations. The value must be `consul.hashicorp.com/v1alpha1`.
### `kind`
Specifies the type of configuration entry to implement.
#### Values
- Default: none
- This field is required.
- Data type: String value that must be set to `serviceSplitter`.
### `metadata.name`
Specifies a name for the configuration entry. The name is metadata that you can use to reference the configuration entry when performing Consul operations, such as applying a configuration entry to a specific cluster.
#### Values
- Default: Inherits name from the host node
- This field is required.
- Data type: String
### `metadata.namespace` <EnterpriseAlert inline />
Specifies the Consul namespace to use for resolving the service. You can map Consul namespaces to Kubernetes Namespaces in different ways. Refer to [Custom Resource Definitions (CRDs) for Consul on Kubernetes](/consul/docs/k8s/crds#consul-enterprise) for additional information.
#### Values
- Default: None
- Data type: String
### `spec`
Kubernetes-only field that contains all of the configurations for service splitter pods.
#### Values
- Default: none
- This field is required.
- Data type: Object containing [`spec.splits`](#spec-splits) configuration
### `spec.meta`
Specifies key-value pairs to add to the KV store.
#### Values
- Default: none
- Data type: Map of one or more key-value pairs
- keys: String
- values: String, integer, or float
### `spec.splits`
Defines how much traffic to send to sets of service instances during a traffic split.
#### Values
- Default: None
- This field is required.
- Data type: list of objects that can contain the following fields:
- `weight`: The sum of weights for a set of service instances. The total defined value must add up to 100.
- `service`: This field is required.
- `serviceSubset`
- `namespace` <Enterprise inline/>
- `partition` <Enterprise inline/>
- `requestHeaders`
- `responseHeaders`
### `spec.splits[].weight`
Specifies the percentage of traffic sent to the set of service instances specified in the [`spec.splits.service`](#spec-splits-service) field. Each weight must be a floating integer between `0` and `100`. The smallest representable value is `.01`. The sum of weights across all splits must add up to `100`.
#### Values
- Default: `null`
- This field is required.
- Data type: Floating integer from `.01` to `100`
### `spec.splits[].service`
Specifies the name of the service to resolve.
#### Values
- Default: The service matching the configuration entry [`meta.name`](#metadata-name) field.
- Data type: String
### `spec.splits[].serviceSubset`
Specifies a subset of the service to resolve. This field overrides the `DefaultSubset`.
#### Values
- Default: Inherits the name of the default subset.
- Data type: String
### `spec.splits[].namespace` <EnterpriseAlert inline />
Specifies the [namespace](/consul/docs/enterprise/namespaces) to use when resolving the service.
#### Values
- Default: The namespace specified in the top-level configuration entry.
- Data type: String
### `spec.splits[].partition` <EnterpriseAlert inline />
Specifies which [admin partition](/consul/docs/enterprise/admin-partitions) to use in the FQDN when resolving the service.
#### Values
- Default: `default`
- Data type: String
### `spec.splits[].requestHeaders`
Specifies a set of HTTP-specific header modification rules applied to requests routed with the service split. You cannot configure request headers if the listener protocol is set to `tcp`. Refer to [Set HTTP Headers](#set-http-headers) for an example configuration.
#### Values
- Default: None
- Values: Object containing one or more fields that define header modification rules
- `add`: Map of one or more key-value pairs
- `set`: Map of one or more key-value pairs
- `remove`: Map of one or more key-value pairs
The following table describes how to configure values for request headers:
| Rule | Description | Type |
| --- | --- | --- |
| `add` | Defines a set of key-value pairs to add to the header. Use header names as the keys. Header names are not case-sensitive. If header values with the same name already exist, the value is appended and Consul applies both headers. You can [use variable placeholders](#use-variable-placeholders). | map of strings |
| `set` | Defines a set of key-value pairs to add to the request header or to replace existing header values with. Use header names as the keys. Header names are not case-sensitive. If header values with the same names already exist, Consul replaces the header values. You can [use variable placeholders](#use-variable-placeholders). | map of strings |
| `remove` | Defines an list of headers to remove. Consul removes only headers containing exact matches. Header names are not case-sensitive. | list of strings |
#### Use variable placeholders
For `add` and `set`, if the service is configured to use Envoy as the proxy, the value may contain variables to interpolate dynamic metadata into the value. For example, using the variable `%DOWNSTREAM_REMOTE_ADDRESS%` in your configuration entry allows you to pass a value that is generated when the split occurs.
### `spec.splits[].responseHeaders`
Specifies a set of HTTP-specific header modification rules applied to responses routed with the service split. You cannot configure request headers if the listener protocol is set to `tcp`. Refer to [Set HTTP Headers](#set-http-headers) for an example configuration.
#### Values
- Default: None
- Values: Object containing one or more fields that define header modification rules
- `add`: Map of one or more string key-value pairs
- `set`: Map of one or more string key-value pairs
- `remove`: Map of one or more string key-value pairs
The following table describes how to configure values for response headers:
| Rule | Description | Type |
| --- | --- | --- |
| `add` | Defines a set of key-value pairs to add to the header. Use header names as the keys. Header names are not case-sensitive. If header values with the same name already exist, the value is appended and Consul applies both headers. You can [use variable placeholders](#use-variable-placeholders). | map of strings |
| `set` | Defines a set of key-value pairs to add to the request header or to replace existing header values with. Use header names as the keys. Header names are not case-sensitive. If header values with the same names already exist, Consul replaces the header values. You can [use variable placeholders](#use-variable-placeholders). | map of strings |
| `remove` | Defines an list of headers to remove. Consul removes only headers containing exact matches. Header names are not case-sensitive. | list of strings |
#### Use variable placeholders
For `add` and `set`, if the service is configured to use Envoy as the proxy, the value may contain variables to interpolate dynamic metadata into the value. For example, using the variable `%DOWNSTREAM_REMOTE_ADDRESS%` in your configuration entry allows you to pass a value that is generated when the split occurs.
</Tab>
</Tabs>
## Examples
The following examples demonstrate common service splitter configuration patterns for specific use cases.
### Two subsets of same service
Split traffic between two subsets of the same service:
<Tabs>
<Tab heading="HCL" group="hcl">
```hcl
Kind = "service-splitter"
Name = "web"
Splits = [
{
Weight = 90
ServiceSubset = "v1"
},
{
Weight = 10
ServiceSubset = "v2"
},
]
```
</Tab>
<Tab heading="JSON" group="json">
```json
{
"Kind": "service-splitter",
"Name": "web",
"Splits": [
{
"Weight": 90,
"ServiceSubset": "v1"
},
{
"Weight": 10,
"ServiceSubset": "v2"
}
]
}
```
</Tab>
<Tab heading="YAML" group="yaml">
```yaml
apiVersion: consul.hashicorp.com/v1alpha1
kind: ServiceSplitter
metadata:
name: web
spec:
splits:
- weight: 90
serviceSubset: v1
- weight: 10
serviceSubset: v2
```
</Tab>
</Tabs>
### Two different services
Split traffic between two services:
<Tabs>
<Tab heading="HCL" group="hcl">
```hcl
Kind = "service-splitter"
Name = "web"
Splits = [
{
Weight = 50
# will default to service with same name as config entry ("web")
},
{
Weight = 50
Service = "web-rewrite"
},
]
```
</Tab>
<Tab heading="JSON" group="json">
```json
{
"Kind": "service-splitter",
"Name": "web",
"Splits": [
{
"Weight": 50
},
{
"Weight": 50,
"Service": "web-rewrite"
}
]
}
```
</Tab>
<Tab heading="YAML" group="yaml">
```yaml
apiVersion: consul.hashicorp.com/v1alpha1
kind: ServiceSplitter
metadata:
name: web
spec:
splits:
- weight: 50
# defaults to the service with same name as the configuration entry ("web")
- weight: 50
service: web-rewrite
```
</Tab>
</Tabs>
### Set HTTP Headers
Split traffic between two subsets with extra headers added so clients can tell
which version:
<Tabs>
<Tab heading="HCL" group="hcl">
```hcl
Kind = "service-splitter"
Name = "web"
Splits = [
{
Weight = 90
ServiceSubset = "v1"
ResponseHeaders {
Set {
"X-Web-Version": "v1"
}
}
},
{
Weight = 10
ServiceSubset = "v2"
ResponseHeaders {
Set {
"X-Web-Version": "v2"
}
}
},
]
```
</Tab>
<Tab heading="JSON" group="json">
```json
{
"Kind": "service-splitter",
"Name": "web",
"Splits": [
{
"Weight": 90,
"ServiceSubset": "v1",
"ResponseHeaders": {
"Set": {
"X-Web-Version": "v1"
}
}
},
{
"Weight": 10,
"ServiceSubset": "v2",
"ResponseHeaders": {
"Set": {
"X-Web-Version": "v2"
}
}
}
]
}
```
</Tab>
<Tab heading="YAML" group="yaml">
```yaml
apiVersion: consul.hashicorp.com/v1alpha1
kind: ServiceSplitter
metadata:
name: web
spec:
splits:
- weight: 90
serviceSubset: v1
responseHeaders:
set:
x-web-version: v1
- weight: 10
serviceSubset: v2
responseHeaders:
set:
x-web-version: v2
```
</Tab>
</Tabs>