mirror of
https://github.com/status-im/consul.git
synced 2025-01-10 13:55:55 +00:00
59394e4aa2
Avoid HTTP redirects for internal site links by updating old URLs to point to the new location for the target content.
348 lines
8.9 KiB
Plaintext
348 lines
8.9 KiB
Plaintext
---
|
|
layout: docs
|
|
page_title: 'Configuration Entry Kind: Service Splitter'
|
|
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).
|
|
---
|
|
|
|
# Service Splitter
|
|
|
|
-> **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+.
|
|
|
|
The `service-splitter` config entry kind (`ServiceSplitter` on Kubernetes) 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).
|
|
|
|
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
|
|
Management](/docs/connect/l7-traffic).
|
|
|
|
- Service splitter config entries are restricted to only services that define
|
|
their protocol as http-based via a corresponding
|
|
[`service-defaults`](/docs/connect/config-entries/service-defaults) config
|
|
entry or globally via
|
|
[`proxy-defaults`](/docs/connect/config-entries/proxy-defaults) .
|
|
|
|
- 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
|
|
[`service-resolver`](/docs/connect/config-entries/service-resolver).
|
|
|
|
## UI
|
|
|
|
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.
|
|
|
|
![screenshot of service splitter in the UI](/img/l7-routing/Splitter.png)
|
|
|
|
## Sample Config Entries
|
|
|
|
### Two subsets of same service
|
|
|
|
Split traffic between two subsets of the same service:
|
|
|
|
<CodeTabs tabs={[ "HCL", "Kubernetes YAML", "JSON" ]}>
|
|
|
|
```hcl
|
|
Kind = "service-splitter"
|
|
Name = "web"
|
|
Splits = [
|
|
{
|
|
Weight = 90
|
|
ServiceSubset = "v1"
|
|
},
|
|
{
|
|
Weight = 10
|
|
ServiceSubset = "v2"
|
|
},
|
|
]
|
|
```
|
|
|
|
```yaml
|
|
apiVersion: consul.hashicorp.com/v1alpha1
|
|
kind: ServiceSplitter
|
|
metadata:
|
|
name: web
|
|
spec:
|
|
splits:
|
|
- weight: 90
|
|
serviceSubset: v1
|
|
- weight: 10
|
|
serviceSubset: v2
|
|
```
|
|
|
|
```json
|
|
{
|
|
"Kind": "service-splitter",
|
|
"Name": "web",
|
|
"Splits": [
|
|
{
|
|
"Weight": 90,
|
|
"ServiceSubset": "v1"
|
|
},
|
|
{
|
|
"Weight": 10,
|
|
"ServiceSubset": "v2"
|
|
}
|
|
]
|
|
}
|
|
```
|
|
|
|
</CodeTabs>
|
|
|
|
### Two different services
|
|
|
|
Split traffic between two services:
|
|
|
|
<CodeTabs tabs={[ "HCL", "Kubernetes YAML", "JSON" ]}>
|
|
|
|
```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"
|
|
},
|
|
]
|
|
```
|
|
|
|
```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")
|
|
- weight: 50
|
|
service: web-rewrite
|
|
```
|
|
|
|
```json
|
|
{
|
|
"Kind": "service-splitter",
|
|
"Name": "web",
|
|
"Splits": [
|
|
{
|
|
"Weight": 50
|
|
},
|
|
{
|
|
"Weight": 50,
|
|
"Service": "web-rewrite"
|
|
}
|
|
]
|
|
}
|
|
```
|
|
|
|
</CodeTabs>
|
|
|
|
|
|
### Set HTTP Headers
|
|
|
|
Split traffic between two subsets with extra headers added so clients can tell
|
|
which version (not yet supported in Kubernetes CRD):
|
|
|
|
<CodeTabs tabs={[ "HCL", "JSON" ]}>
|
|
|
|
```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"
|
|
}
|
|
}
|
|
},
|
|
]
|
|
```
|
|
|
|
```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>
|
|
|
|
## Available Fields
|
|
|
|
<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,
|
|
description: 'Specifies the namespace to which the configuration entry will apply.',
|
|
yaml: false,
|
|
},
|
|
{
|
|
name: 'Partition',
|
|
type: `string: "default"`,
|
|
enterprise: true,
|
|
description: 'Specifies the admin partition to which the configuration entry will apply.',
|
|
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.',
|
|
},
|
|
{
|
|
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.',
|
|
},
|
|
],
|
|
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:
|
|
'A value between 0 and 100 reflecting what portion of traffic should be directed to this split. The smallest representable eight is 1/10000 or .01%',
|
|
},
|
|
{
|
|
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:
|
|
'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.',
|
|
},
|
|
{
|
|
yaml: false,
|
|
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.`,
|
|
},
|
|
{
|
|
yaml: false,
|
|
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.`,
|
|
},
|
|
],
|
|
},
|
|
]}
|
|
/>
|
|
|
|
## ACLs
|
|
|
|
Configuration entries may be protected by [ACLs](/docs/security/acl).
|
|
|
|
Reading a `service-splitter` config entry requires `service:read` on the resource.
|
|
|
|
Creating, updating, or deleting a `service-splitter` config entry requires
|
|
`service:write` on the resource and `service:read` on any other service referenced by
|
|
name in these fields:
|
|
|
|
- [`Splits[].Service`](#service)
|