2019-07-09 02:11:19 +00:00
---
2020-04-07 18:55:19 +00:00
layout: docs
2020-04-06 20:27:35 +00:00
page_title: 'Configuration Entry Kind: Service Splitter'
2020-04-07 18:55:19 +00:00
description: >-
The service-splitter config entry kind controls how to split incoming Connect
requests across different subsets of a single service (like during staged
canary rollouts), or perhaps across different services (like during a v2
rewrite or other type of codebase migration).
2019-07-09 02:11:19 +00:00
---
2019-08-21 21:23:08 +00:00
# Service Splitter
2019-07-09 02:11:19 +00:00
2020-12-16 16:57:43 +00:00
-> **v1.8.4+:** On Kubernetes, the `ServiceSplitter` custom resource is supported in Consul versions 1.8.4+.<br />
**v1.6.0+:** On other platforms, this config entry is supported in Consul versions 1.6.0+.
2020-04-09 00:09:01 +00:00
2020-12-16 16:57:43 +00:00
The `service-splitter` config entry kind (`ServiceSplitter` on Kubernetes) controls how to split incoming Connect
2019-07-09 02:11:19 +00:00
requests across different subsets of a single service (like during staged
canary rollouts), or perhaps across different services (like during a v2
rewrite or other type of codebase migration).
If no splitter config is defined for a service it is assumed 100% of traffic
flows to a service with the same name and discovery continues on to the
resolution stage.
## Interaction with other Config Entries
- Service splitter config entries are a component of [L7 Traffic
2022-01-10 23:36:16 +00:00
Management](/docs/connect/l7-traffic).
2019-07-09 02:11:19 +00:00
- Service splitter config entries are restricted to only services that define
their protocol as http-based via a corresponding
2021-01-13 20:48:48 +00:00
[`service-defaults`](/docs/connect/config-entries/service-defaults) config
2019-07-09 02:11:19 +00:00
entry or globally via
2021-01-13 20:48:48 +00:00
[`proxy-defaults`](/docs/connect/config-entries/proxy-defaults) .
2019-07-09 02:11:19 +00:00
- Any split destination that specifies a different `Service` field and omits
the `ServiceSubset` field is eligible for further splitting should a splitter
be configured for that other service, otherwise resolution proceeds according
to any configured
2021-01-13 20:48:48 +00:00
[`service-resolver`](/docs/connect/config-entries/service-resolver).
2019-07-09 02:11:19 +00:00
2022-02-03 22:03:21 +00:00
## UI
2022-01-10 23:14:24 +00:00
2022-02-03 22:03:21 +00:00
Once a `service-splitter` is successfully entered, you can view it in the UI. Service routers, service splitters, and service resolvers can all be viewed by clicking on your service then switching to the _routing_ tab.
2022-01-10 23:14:24 +00:00
![screenshot of service splitter in the UI](/img/l7-routing/Splitter.png)
2019-07-09 02:11:19 +00:00
## Sample Config Entries
2020-12-16 16:57:43 +00:00
### Two subsets of same service
2019-07-09 02:11:19 +00:00
Split traffic between two subsets of the same service:
2021-06-13 00:53:50 +00:00
<CodeTabs tabs={[ "HCL", "Kubernetes YAML", "JSON" ]}>
2019-07-09 02:11:19 +00:00
```hcl
2020-06-15 21:14:36 +00:00
Kind = "service-splitter"
Name = "web"
Splits = [
2019-07-09 02:11:19 +00:00
{
2020-06-16 18:28:21 +00:00
Weight = 90
2020-06-15 21:14:36 +00:00
ServiceSubset = "v1"
2019-07-09 02:11:19 +00:00
},
{
2020-06-16 18:28:21 +00:00
Weight = 10
2020-06-15 21:14:36 +00:00
ServiceSubset = "v2"
2019-07-09 02:11:19 +00:00
},
]
```
2020-12-16 16:57:43 +00:00
```yaml
apiVersion: consul.hashicorp.com/v1alpha1
kind: ServiceSplitter
metadata:
name: web
spec:
splits:
- weight: 90
serviceSubset: v1
- weight: 10
serviceSubset: v2
```
2021-06-13 00:53:50 +00:00
```json
{
"Kind": "service-splitter",
"Name": "web",
"Splits": [
{
"Weight": 90,
"ServiceSubset": "v1"
},
{
"Weight": 10,
"ServiceSubset": "v2"
}
]
}
```
2020-12-16 16:57:43 +00:00
2021-06-13 00:53:50 +00:00
</CodeTabs>
2020-12-16 16:57:43 +00:00
2021-06-13 00:53:50 +00:00
### Two different services
2020-12-16 16:57:43 +00:00
2019-07-09 02:11:19 +00:00
Split traffic between two services:
2021-06-13 00:53:50 +00:00
<CodeTabs tabs={[ "HCL", "Kubernetes YAML", "JSON" ]}>
2019-07-09 02:11:19 +00:00
```hcl
2020-06-15 21:14:36 +00:00
Kind = "service-splitter"
Name = "web"
Splits = [
2019-07-09 02:11:19 +00:00
{
2020-06-16 18:28:21 +00:00
Weight = 50
2019-07-09 02:11:19 +00:00
# will default to service with same name as config entry ("web")
},
{
2021-06-29 11:01:55 +00:00
Weight = 50
2020-06-15 21:14:36 +00:00
Service = "web-rewrite"
2019-07-09 02:11:19 +00:00
},
]
```
2020-12-16 16:57:43 +00:00
```yaml
apiVersion: consul.hashicorp.com/v1alpha1
kind: ServiceSplitter
metadata:
name: web
spec:
splits:
- weight: 50
# will default to service with same name as config entry ("web")
2021-06-29 11:01:55 +00:00
- weight: 50
2020-12-16 16:57:43 +00:00
service: web-rewrite
```
2019-07-09 02:11:19 +00:00
2021-06-13 00:53:50 +00:00
```json
{
"Kind": "service-splitter",
"Name": "web",
"Splits": [
{
"Weight": 50
},
{
"Weight": 50,
"Service": "web-rewrite"
}
]
}
```
</CodeTabs>
2019-07-09 02:11:19 +00:00
2021-09-15 12:36:58 +00:00
### Set HTTP Headers
Split traffic between two subsets with extra headers added so clients can tell
2022-02-03 22:03:21 +00:00
which version:
2021-09-15 12:36:58 +00:00
2022-02-03 22:03:21 +00:00
<CodeTabs tabs={[ "HCL", "Kubernetes YAML", "JSON" ]}>
2021-09-15 12:36:58 +00:00
```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"
}
}
},
]
```
2022-02-03 22:03:21 +00:00
```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
```
2021-09-15 12:36:58 +00:00
```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"
}
}
}
]
}
```
</CodeTabs>
2020-12-16 16:57:43 +00:00
## Available Fields
2019-07-09 02:11:19 +00:00
2020-12-16 16:57:43 +00:00
<ConfigEntryReference
keys={[
{
name: 'apiVersion',
description: 'Must be set to `consul.hashicorp.com/v1alpha1`',
hcl: false,
},
{
name: 'Kind',
description: {
hcl: 'Must be set to `service-splitter`',
yaml: 'Must be set to `ServiceSplitter`',
},
},
{
name: 'Name',
description: 'Set to the name of the service being configured.',
type: 'string: <required>',
yaml: false,
},
{
name: 'Namespace',
type: `string: "default"`,
enterprise: true,
2022-02-03 22:03:21 +00:00
description:
'Specifies the namespace to which the configuration entry will apply.',
2021-12-21 00:30:39 +00:00
yaml: false,
},
{
name: 'Partition',
type: `string: "default"`,
enterprise: true,
2022-02-03 22:03:21 +00:00
description:
'Specifies the admin partition to which the configuration entry will apply.',
2020-12-16 16:57:43 +00:00
yaml: false,
},
{
name: 'Meta',
type: 'map<string|string>: nil',
description:
'Specifies arbitrary KV metadata pairs. Added in Consul 1.8.4.',
yaml: false,
},
{
name: 'metadata',
children: [
{
name: 'name',
description: 'Set to the name of the service being configured.',
},
2021-01-07 19:22:06 +00:00
{
name: 'namespace',
description:
'If running Consul Open Source, the namespace is ignored (see [Kubernetes Namespaces in Consul OSS](/docs/k8s/crds#consul-oss)). If running Consul Enterprise see [Kubernetes Namespaces in Consul Enterprise](/docs/k8s/crds#consul-enterprise) for more details.',
},
2020-12-16 16:57:43 +00:00
],
hcl: false,
},
{
name: 'Splits',
type: 'array<ServiceSplit>',
description:
'Defines how much traffic to send to which set of service instances during a traffic split. The sum of weights across all splits must add up to 100.',
children: [
{
name: 'weight',
type: 'float32: 0',
description:
2022-05-28 19:22:01 +00:00
'A value between 0 and 100 reflecting what portion of traffic should be directed to this split. The smallest representable weight is 1/10000 or .01%',
2020-12-16 16:57:43 +00:00
},
{
name: 'Service',
type: 'string: ""',
description: 'The service to resolve instead of the default.',
},
{
name: 'ServiceSubset',
type: 'string: ""',
description: {
hcl:
"A named subset of the given service to resolve instead of one defined as that service's `DefaultSubset`. If empty the default subset is used.",
yaml:
"A named subset of the given service to resolve instead of one defined as that service's `defaultSubset`. If empty the default subset is used.",
},
},
{
name: 'Namespace',
enterprise: true,
type: 'string: ""',
description:
2021-12-21 00:30:39 +00:00
'The namespace to resolve the service from instead of the current namespace. If empty, the current namespace is used.',
},
{
name: 'Partition',
enterprise: true,
type: 'string: ""',
description:
'The admin partition to resolve the service from instead of the current partition. If empty, the current partition is used.',
2020-12-16 16:57:43 +00:00
},
2021-09-15 12:36:58 +00:00
{
name: 'RequestHeaders',
type: 'HTTPHeaderModifiers: <optional>',
description: `A set of [HTTP-specific header modification rules](/docs/connect/config-entries/service-router#httpheadermodifiers)
that will be applied to requests routed to this split.
This cannot be used with a \`tcp\` listener.`,
},
{
name: 'ResponseHeaders',
type: 'HTTPHeaderModifiers: <optional>',
description: `A set of [HTTP-specific header modification rules](/docs/connect/config-entries/service-router#httpheadermodifiers)
that will be applied to responses from this split.
This cannot be used with a \`tcp\` listener.`,
},
2020-12-16 16:57:43 +00:00
],
},
]}
/>
2019-07-09 02:11:19 +00:00
## ACLs
2020-10-14 15:23:05 +00:00
Configuration entries may be protected by [ACLs](/docs/security/acl).
2019-07-09 02:11:19 +00:00
2020-10-14 15:23:05 +00:00
Reading a `service-splitter` config entry requires `service:read` on the resource.
2019-07-09 02:11:19 +00:00
Creating, updating, or deleting a `service-splitter` config entry requires
2020-10-14 15:23:05 +00:00
`service:write` on the resource and `service:read` on any other service referenced by
2019-07-09 02:11:19 +00:00
name in these fields:
- [`Splits[].Service`](#service)