Document Kube CRDs alongside config entry docs

* Adds a new react component `ConfigEntryReference` that allows us to
document config entries for both HCL and Kubernetes CRDs.
* Rewrites config entry docs to use new component
* Add CRD examples alongside HCL examples
* Removes examples from Kube CRD doc because the examples are now in the
main CRD docs
This commit is contained in:
Luke Kysow 2020-12-16 08:57:43 -08:00
parent d32e7f0857
commit 517cfa7918
No known key found for this signature in database
GPG Key ID: FA168D4DC3F04307
12 changed files with 2662 additions and 989 deletions

View File

@ -0,0 +1,265 @@
import TabsBase from '@hashicorp/react-tabs'
import s from '@hashicorp/nextjs-scripts/lib/providers/docs/style.module.css'
import EnterpriseAlertBase from '@hashicorp/react-enterprise-alert'
/**
* ConfigEntryReference renders the reference docs for a config entry.
* It creates two tabs, one for HCL docs and one for Kubernetes docs.
*
* @param {array<object>} keys Array of objects, that describe all
* keys that can be set for this config entry.
* @param {boolean} topLevel Indicates this is a reference block that contains
* the top level keys vs a reference block that documents
* nested keys and that is separated out for clarity.
*
* The objects in the keys array support the following keys:
* - name <required>: the name of the HCL key, e.g. Name, Listener. This case sensitive.
* - description <required>: the description of the key. If this key has different descriptions
* for HCL vs. Kube YAML then description can be an object:
* description: {
* hcl: 'HCL description',
* yaml: 'YAML description'
* }
* - hcl <optional>: a boolean to indicate if this key should be shown in the HCL
* documentation. Defaults to true.
* - yaml <optional>: a boolean to indicate if this key should be shown in the YAML
* documentation. Defaults to true.
* - enterprise <optional>: a boolean to indicate if this key is Consul Enterprise
* only. Defaults to false.
* - children <optional>: accepts an array of keys that must be set under this key.
* The schema for these keys is the same as the top level keys.
* - type <optional>: the type and default of this key, e.g. string: "default".
*/
export default function ConfigEntryReference({ keys, topLevel = true }) {
let kubeKeys = keys
if (topLevel) {
// Kube needs to have its non-top-level keys nested under a "spec" key.
kubeKeys = toKubeKeys(keys)
}
return (
<Tabs>
<Tab heading="HCL">{renderKeys(keys, true)}</Tab>
<Tab heading="Kubernetes YAML">{renderKeys(kubeKeys, false)}</Tab>
</Tabs>
)
}
/**
* Renders keys as HTML. It works recursively through all keys.
* @param {array} keys
* @param {boolean} isHCLTab
* @returns {JSX.Element|null}
*/
function renderKeys(keys, isHCLTab) {
if (!keys) {
return null
}
return (
<ul>
{keys.map((key) => {
return renderKey(key, isHCLTab)
})}
</ul>
)
}
/**
* Renders a single key as its HTML element.
*
* @param {object} key
* @param {boolea} isHCLTab
* @returns {JSX.Element|null}
*/
function renderKey(key, isHCLTab) {
let keyName = key.name
if (!keyName) {
return null
}
if (!isHCLTab) {
keyName = toYAMLKeyName(keyName)
}
if (isHCLTab && key.hcl === false) {
return null
}
if (!isHCLTab && key.yaml === false) {
return null
}
let description = ''
if (key.description) {
if (typeof key.description === 'string') {
description = key.description
} else if (!isHCLTab && key.description.yaml) {
description = key.description.yaml
} else if (key.description.hcl) {
description = key.description.hcl
}
}
let htmlDescription = ''
if (description !== '') {
htmlDescription = markdownToHtml(' - ' + description)
}
let type = ''
if (key.type) {
type = <code>{'(' + key.type + ')'}</code>
}
let enterpriseAlert = ''
if (key.enterprise) {
enterpriseAlert = <EnterpriseAlert inline />
}
const keyLower = keyName.toLowerCase()
return (
<li key={keyLower} className="g-type-long-body">
<a id={keyLower} className="__target-lic" aria-hidden="" />
<p>
<a
href={'#' + keyLower}
aria-label={keyLower + ' permalink'}
className="__permalink-lic"
>
<code>{keyName}</code>
</a>{' '}
{type}
{enterpriseAlert}
<span dangerouslySetInnerHTML={{ __html: htmlDescription }} />
</p>
{renderKeys(key.children, isHCLTab)}
</li>
)
}
/**
* Constructs a keys object for Kubernetes out of HCL keys.
* Really all this entails is nesting the correct keys under the Kubernetes
* 'spec' key since in HCL there is no 'spec' key.
*
* @param {array} keys
* @returns {array}
*/
function toKubeKeys(keys) {
const topLevelKeys = keys.filter((key) => {
return isTopLevelKubeKey(key.name)
})
const keysUnderSpec = keys.filter((key) => {
return !isTopLevelKubeKey(key.name)
})
return topLevelKeys.concat([{ name: 'spec', children: keysUnderSpec }])
}
/**
* Converts an HCL key name to a kube yaml key name.
*
* Examples:
* - Protocol => protocol
* - MeshGateway => meshGateway
* - ACLToken => aclToken
* - HTTP => http
*
* @param {string} hclKey
* @returns {string}
*/
function toYAMLKeyName(hclKey) {
// Handle something like HTTP.
if (hclKey.toUpperCase() === hclKey) {
return hclKey.toLowerCase()
}
let indexFirstLowercaseChar = 0
for (let i = 0; i < hclKey.length; i++) {
if (hclKey[i].toLowerCase() === hclKey[i]) {
indexFirstLowercaseChar = i
break
}
}
// Special case to handle something like ACLToken => aclToken.
if (indexFirstLowercaseChar > 1) {
indexFirstLowercaseChar--
}
let yamlKey = ''
for (let i = 0; i < indexFirstLowercaseChar; i++) {
yamlKey += hclKey[i].toLowerCase()
}
yamlKey += hclKey.split('').slice(indexFirstLowercaseChar).join('')
return yamlKey
}
/**
* Converts a markdown string to its HTML representation.
* Currently it only supports inline code blocks (e.g. `code here`) and
* links (e.g. [link text](http://link-url) because these were the most
* commonly used markdown features in the key descriptions.
*
* @param {string} markdown the input markdown
* @returns {string}
*/
function markdownToHtml(markdown) {
let html = markdown
// Replace inline code blocks defined by backticks with <code></code>.
while (html.indexOf('`') > 0) {
html = html.replace('`', '<code>')
if (html.indexOf('`') <= 0) {
throw new Error(`'${markdown} does not have matching '\`' characters`)
}
html = html.replace('`', '</code>')
}
// Replace links, e.g. [link text](http://link-url),
// with <a href="http://link-url">link text</a>.
return html.replace(/\[(.*?)]\((.*?)\)/g, '<a href="$2">$1</a>')
}
/**
* Returns true if key is a key used at the top level of a CRD. By top level we
* mean not nested under any other key.
*
* @param {string} name name of the key
*
* @return {boolean}
*/
function isTopLevelKubeKey(name) {
return (
name.toLowerCase() === 'metadata' ||
name.toLowerCase() === 'kind' ||
name.toLowerCase() === 'apiversion'
)
}
// Copied from https://github.com/hashicorp/nextjs-scripts/blob/04917da2191910d490182250d2828372aa1221c0/lib/providers/docs/index.jsx
// because there's no way to import it right now.
function Tabs({ children }) {
if (!Array.isArray(children))
throw new Error('Multiple <Tab> elements required')
return (
<span className={s.tabsRoot}>
<TabsBase
items={children.map((Block) => ({
heading: Block.props.heading,
// eslint-disable-next-line react/display-name
tabChildren: () => Block,
}))}
/>
</span>
)
}
// Copied from https://github.com/hashicorp/nextjs-scripts/blob/04917da2191910d490182250d2828372aa1221c0/lib/providers/docs/index.jsx
// because there's no way to import it right now.
function Tab({ children }) {
return <>{children}</>
}
function EnterpriseAlert(props) {
return <EnterpriseAlertBase product={'consul'} {...props} />
}

View File

@ -10,11 +10,16 @@ description: >-
# Configuration Entries
Configuration entries can be created to provide cluster-wide defaults for
various aspects of Consul. Every configuration entry has at least two fields:
various aspects of Consul.
Outside of Kubernetes, configuration entries can be specified in HCL or JSON using either
`snake_case` or `CamelCase` for key names. On Kubernetes, configuration
entries can be managed by custom resources in YAML.
Outside of Kubernetes, every configuration entry specified in HCL or JSON has at least two fields:
`Kind` and `Name`. Those two fields are used to uniquely identify a
configuration entry. When put into configuration files, configuration entries
can be specified as HCL or JSON objects using either `snake_case` or `CamelCase`
for key names.
configuration entry. Configuration entries specified as HCL or JSON objects
use either `snake_case` or `CamelCase` for key names.
Example:
@ -23,35 +28,64 @@ Kind = "<supported kind>"
Name = "<name of entry>"
```
The supported `Kind` names for configuration entries are:
On Kubernetes, `Kind` is set as the custom resource `kind` and `Name` is set
as `metadata.name`:
```yaml
apiVersion: consul.hashicorp.com/v1alpha1
kind: <supported kind>
metadata:
name: <name of entry>
```
The supported `Kind`/`kind` names for configuration entries are:
- [`ingress-gateway`](/docs/agent/config-entries/ingress-gateway) - defines the
configuration for an ingress gateway
- Kubernetes kind: [`IngressGateway`](/docs/agent/config-entries/ingress-gateway)
- [`proxy-defaults`](/docs/agent/config-entries/proxy-defaults) - controls
proxy configuration
- Kubernetes kind: [`ProxyDefaults`](/docs/agent/config-entries/proxy-defaults)
- [`service-defaults`](/docs/agent/config-entries/service-defaults) - configures
defaults for all the instances of a given service
- Kubernetes kind: [`ServiceDefaults`](/docs/agent/config-entries/service-defaults)
- [`service-intentions`](/docs/agent/config-entries/service-intentions) - defines
the [intentions](/docs/connect/intentions) for a destination service
- Kubernetes kind: [`ServiceIntentions`](/docs/agent/config-entries/service-intentions)
- [`service-resolver`](/docs/agent/config-entries/service-resolver) - matches
service instances with a specific Connect upstream discovery requests
- Kubernetes kind: [`ServiceResolver`](/docs/agent/config-entries/service-resolver)
- [`service-router`](/docs/agent/config-entries/service-router) - defines
where to send layer 7 traffic based on the HTTP route
- Kubernetes kind: [`ServiceRouter`](/docs/agent/config-entries/service-router)
- [`service-splitter`](/docs/agent/config-entries/service-splitter) - defines
how to divide requests for a single HTTP route based on percentages
- Kubernetes kind: [`ServiceSplitter`](/docs/agent/config-entries/service-splitter)
- [`terminating-gateway`](/docs/agent/config-entries/terminating-gateway) - defines the
services associated with terminating gateway
- Kubernetes kind: [`TerminatingGateway`](/docs/agent/config-entries/terminating-gateway)
## Managing Configuration Entries
## Managing Configuration Entries In Kubernetes
Configuration entries should be managed with the Consul
See [Kubernetes Custom Resource Definitions](/docs/k8s/crds).
## Managing Configuration Entries Outside Of Kubernetes
Configuration entries outside of Kubernetes should be managed with the Consul
[CLI](/commands/config) or [API](/api/config). Additionally, as a
convenience for initial cluster bootstrapping, configuration entries can be
specified in all of the Consul servers's
@ -163,7 +197,7 @@ matches both `kind` and `name`, then the server will do nothing.
## Using Configuration Entries For Service Defaults
When the agent is
Outside of Kubernetes, when the agent is
[configured](/docs/agent/options#enable_central_service_config) to enable
central service configurations, it will look for service configuration defaults
that match a registering service instance. If it finds any, the agent will merge

View File

@ -9,16 +9,18 @@ description: >-
# Ingress Gateway
-> **1.8.0+:** This config entry is available in Consul versions 1.8.0 and newer.
-> **v1.8.4+:** On Kubernetes, the `IngressGateway` custom resource is supported in Consul versions 1.8.4+.<br />
**v1.8.0+:** On other platforms, this config entry is supported in Consul versions 1.8.0+.
The `ingress-gateway` config entry kind allows you to configure ingress gateways
The `ingress-gateway` config entry kind (`IngressGateway` on Kubernetes) allows you to configure ingress gateways
with listeners that expose a set of services outside the Consul service mesh.
See [Ingress Gateway](/docs/connect/ingress-gateway) for more information.
~> [Configuration entries](/docs/agent/config-entries) are global in scope. A configuration entry for a gateway name applies
For Kubernetes, see [Kubernetes Ingress Gateway](/docs/k8s/connect/ingress-gateways) for more information.
For other platforms, see [Ingress Gateway](/docs/connect/ingress-gateway).
~> **Note:** [Configuration entries](/docs/agent/config-entries) are global in scope. A configuration entry for a gateway name applies
across all federated Consul datacenters. If ingress gateways in different Consul datacenters need to route to different
sets of services within their datacenter then the ingress gateways **must** be registered with different names.
sets of services within their datacenter then the ingress gateways **must** be registered with different names.<br />
See [Ingress Gateway](/docs/connect/ingress-gateway) for more information.
## Wildcard service specification
@ -93,6 +95,45 @@ Listeners = [
]
```
</Tab>
<Tab heading="Kubernetes YAML">
Set up a TCP listener on an ingress gateway named "us-east-ingress" to proxy traffic to the "db" service:
```yaml
apiVersion: consul.hashicorp.com/v1alpha1
kind: IngressGateway
metadata:
name: us-east-ingress
spec:
listeners:
- port: 3456
protocol: tcp
services:
- name: db
```
</Tab>
<Tab heading="Kubernetes YAML (Consul Enterprise)">
Set up a TCP listener on an ingress gateway named "us-east-ingress" in the default namespace
to proxy traffic to the "db" service in the ops namespace:
```yaml
apiVersion: consul.hashicorp.com/v1alpha1
kind: IngressGateway
metadata:
name: us-east-ingress
namespace: default
spec:
listeners:
- port: 3456
protocol: tcp
services:
- name: db
namespace: ops
```
</Tab>
<Tab heading="JSON">
@ -233,6 +274,66 @@ Listeners = [
]
```
</Tab>
<Tab heading="Kubernetes YAML">
Set up a wildcard HTTP listener on an ingress gateway named "us-east-ingress" to proxy traffic to all services in the datacenter.
Also make two services available over a custom port with user-provided hosts, and enable TLS on every listener:
```yaml
apiVersion: consul.hashicorp.com/v1alpha1
kind: IngressGateway
metadata:
name: us-east-ingress
spec:
tls:
enabled: true
listeners:
- port: 8080
protocol: http
services:
- name: '*'
- port: 4567
protocol: http
services:
- name: api
hosts: ['foo.example.com', 'foo.example.com:4567']
- name: web
hosts: ['website.example.com', 'website.example.com:4567']
```
</Tab>
<Tab heading="Kubernetes YAML (Consul Enterprise)">
Set up a wildcard HTTP listener on an ingress gateway named "us-east-ingress" to proxy traffic to all services in the frontend namespace.
Also make two services in the frontend namespace available over a custom port with user-provided hosts, and enable TLS on every listener:
```yaml
apiVersion: consul.hashicorp.com/v1alpha1
kind: IngressGateway
metadata:
name: us-east-ingress
namespace: default
spec:
tls:
enabled: true
listeners:
- port: 8080
protocol: http
services:
- name: '*'
namespace: frontend
- port: 4567
protocol: http
services:
- name: api
namespace: frontend
hosts: ['foo.example.com', 'foo.example.com:4567']
- name: web
namespace: frontend
hosts: ['website.example.com', 'website.example.com:4567']
```
</Tab>
<Tab heading="JSON">
@ -372,6 +473,46 @@ Listeners = [
]
```
</Tab>
<Tab heading="Kubernetes YAML">
Set up a HTTP listener on an ingress gateway named "us-east-ingress" to proxy
traffic to a virtual service named "api".
```yaml
apiVersion: consul.hashicorp.com/v1alpha1
kind: IngressGateway
metadata:
name: us-east-ingress
spec:
listeners:
- port: 80
protocol: http
services:
- name: api
```
</Tab>
<Tab heading="Kubernetes YAML (Consul Enterprise)">
Set up a HTTP listener on an ingress gateway named "us-east-ingress" in the
default namespace to proxy traffic to a virtual service named "api".
```yaml
apiVersion: consul.hashicorp.com/v1alpha1
kind: IngressGateway
metadata:
name: us-east-ingress
namespace: default
spec:
listeners:
- port: 80
protocol: http
services:
- name: api
namespace: frontend
```
</Tab>
<Tab heading="JSON">
@ -426,9 +567,9 @@ default namespace to proxy traffic to a virtual service named "api".
</Tabs>
The `api` service is not an actual registered service. It exist as a "virtual"
service for L7 configuration only. A `service-router` is defined for this
service for L7 configuration only. A `service-router` (`ServiceRouter` on Kubernetes) is defined for this
virtual service which uses path-based routing to route requests to different
backend services.
backend services:
<Tabs>
<Tab heading="HCL">
@ -497,6 +638,53 @@ Routes = [
]
```
</Tab>
<Tab heading="Kubernetes YAML">
```yaml
apiVersion: consul.hashicorp.com/v1alpha1
kind: ServiceRouter
metadata:
name: api
spec:
routes:
- match:
http:
pathPrefix: '/billing'
destination:
service: billing-api
- match:
http:
pathPrefix: '/payments'
destination:
service: payments-api
```
</Tab>
<Tab heading="Kubernetes YAML (Consul Enterprise)">
```yaml
apiVersion: consul.hashicorp.com/v1alpha1
kind: ServiceRouter
metadata:
name: api
namespace: default
spec:
routes:
- match:
http:
pathPrefix: '/billing'
destination:
service: billing-api
namespace: frontend
- match:
http:
pathPrefix: '/payments'
destination:
service: payments-api
namespace: frontend
```
</Tab>
<Tab heading="JSON">
@ -569,71 +757,139 @@ Routes = [
## Available Fields
- `Kind` - Must be set to `ingress-gateway`
- `Name` `(string: <required>)` - Set to the name of the gateway being configured.
- `Namespace` `(string: "default")` - <EnterpriseAlert inline /> Specifies
the namespace the config entry will apply to. This must be the namespace
the gateway is registered in. If omitted, the namespace will be inherited
from [the request](/api/config#ns) or will default to the `default` namespace.
- `Meta` `(map<string|string>: nil)` - Specifies arbitrary KV metadata pairs. Added in Consul 1.8.4.
- `TLS` `(TLSConfig: <optional>)` - TLS configuration for this gateway.
- `Enabled` `(bool: false)` - Set this configuration to enable TLS for
every listener on the gateway.
If TLS is enabled, then each host defined in the `Host` field will be added
as a DNSSAN to the gateway's x509 certificate.
- `Listeners` `(array<IngressListener>: <optional>)` - A list of listeners that
the ingress gateway should setup, uniquely identified by their port number.
- `Port` `(int: 0)` - The port that the listener should receive traffic on.
- `Protocol` `(string: "tcp")` - The protocol associated with the listener.
One of `tcp`, `http`, `http2`, or `grpc`.
- `Services` `(array<IngressService>: <optional>)` - A list of services to be
exposed via this listener. For "tcp" listeners, only a single service is
allowed.
- `Name` `(string: "")` - The name of the service that should be exposed
through this listener. This can be either a service registered in the
catalog, or a service defined only by [other config
entries](/docs/connect/l7-traffic-management). If the wildcard specifier,
`*`, is provided, then ALL services will be exposed through the listener.
This is not supported for listener's with protocol "tcp".
- `Namespace` `(string: "")` - <EnterpriseAlert inline /> The namespace to resolve the service from
instead of the current namespace. If empty the current namespace is
assumed.
- `Hosts` `(array<string>: <optional>)` - A list of hosts that specify what
requests will match this service. This cannot be used with a `tcp`
listener, and cannot be specified alongside a `*` service name. If not
specified, the default domain `<service-name>.ingress.*` will be used to
match services. Requests **must** send the correct host to be routed to
the defined service.
The wildcard specifier, `*`, can be used by itself to match all traffic
coming to the ingress gateway, if TLS is not enabled. This allows a user
to route all traffic to a single service without specifying a host,
allowing simpler tests and demos. Otherwise, the wildcard specifier can
be used as part of the host to match multiple hosts, but only in the
leftmost DNS label. This ensures that all defined hosts are valid DNS
records. For example, `*.example.com` is valid, while `example.*` and
`*-suffix.example.com` are not.
~> **Note:** If a well-known port is not used, i.e. a port other than 80
(http) or 443 (https), then the port must be appended to the host to
correctly match traffic. This is defined in the [HTTP/1.1
RFC](https://tools.ietf.org/html/rfc2616#section-14.23). If TLS is
enabled, then the host **without** the port must be added to the `Hosts`
field as well. TLS verification only matches against the hostname of the
incoming connection, and thus does not take into account the port.
<ConfigEntryReference
keys={[
{
name: 'apiVersion',
description: 'Must be set to `consul.hashicorp.com/v1alpha1`',
hcl: false,
},
{
name: 'Kind',
description: {
hcl: 'Must be set to `ingress-gateway`',
yaml: 'Must be set to `IngressGateway`',
},
},
{
name: 'Name',
description: 'Set to the name of the gateway being configured.',
type: 'string: <required>',
yaml: false,
},
{
name: 'Namespace',
type: `string: "default"`,
enterprise: true,
description:
'Specifies the namespace the config entry will apply to. This must be the namespace the gateway is registered in.' +
' If omitted, the namespace will be inherited from [the request](/api/config#ns)' +
' or will default to the `default` namespace.',
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.',
},
],
hcl: false,
},
{
name: 'TLS',
type: 'TLSConfig: <optional>',
description: 'TLS configuration for this gateway.',
children: [
{
name: 'Enabled',
type: 'bool: false',
description: {
hcl:
"Set this configuration to enable TLS for every listener on the gateway.<br><br>If TLS is enabled, then each host defined in the `Host` field will be added as a DNSSAN to the gateway's x509 certificate.",
yaml:
"Set this configuration to enable TLS for every listener on the gateway.<br><br>If TLS is enabled, then each host defined in the `host` field will be added as a DNSSAN to the gateway's x509 certificate.",
},
},
],
},
{
name: 'Listeners',
type: 'array<IngressListener>: <optional>)',
description:
'A list of listeners that the ingress gateway should setup, uniquely identified by their port number.',
children: [
{
name: 'Port',
type: 'int: 0',
description: 'The port that the listener should receive traffic on.',
},
{
name: 'Protocol',
type: 'string: "tcp"',
description:
'The protocol associated with the listener. One of `tcp`, `http`, `http2`, or `grpc`.',
},
{
name: 'Services',
type: 'array<IngressService>: <optional>',
description:
'A list of services to be exposed via this listener. For "tcp" listeners, only a single service is allowed.',
children: [
{
name: 'Name',
type: 'string: ""',
description: `The name of the service that should be exposed
through this listener. This can be either a service registered in the
catalog, or a service defined only by [other config entries](/docs/connect/l7-traffic-management). If the wildcard specifier,
\`*\`, is provided, then ALL services will be exposed through the listener.
This is not supported for listener's with protocol "tcp".`,
},
{
name: 'Namespace',
type: 'string: ""',
enterprise: true,
description:
'The namespace to resolve the service from instead of the current namespace. If empty the current namespace is assumed.',
},
{
name: 'Hosts',
type: 'array<string>: <optional>',
description: `A list of hosts that specify what
requests will match this service. This cannot be used with a \`tcp\`
listener, and cannot be specified alongside a \`*\` service name. If not
specified, the default domain \`\<service-name>.ingress.*\` will be used to
match services. Requests <b>must</b> send the correct host to be routed to
the defined service.<br><br>
The wildcard specifier, \`*\`, can be used by itself to match all traffic
coming to the ingress gateway, if TLS is not enabled. This allows a user
to route all traffic to a single service without specifying a host,
allowing simpler tests and demos. Otherwise, the wildcard specifier can
be used as part of the host to match multiple hosts, but only in the
leftmost DNS label. This ensures that all defined hosts are valid DNS
records. For example, \`*.example.com\` is valid, while \`example.*\` and
\`*-suffix.example.com\` are not.<br><br>
<b>Note:</b> If a well-known port is not used, i.e. a port other than 80
(http) or 443 (https), then the port must be appended to the host to
correctly match traffic. This is defined in the [HTTP/1.1 RFC](https://tools.ietf.org/html/rfc2616#section-14.23). If TLS is
enabled, then the host <b>without</b> the port must be added to the \`Hosts\`
field as well. TLS verification only matches against the hostname of the
incoming connection, and thus does not take into account the port.`,
},
],
},
],
},
]}
/>
## ACLs

View File

@ -10,79 +10,234 @@ description: >-
# Proxy Defaults
The `proxy-defaults` config entry kind allows for configuring global config
-> **v1.8.4+:** On Kubernetes, the `ProxyDefaults` custom resource is supported in Consul versions 1.8.4+.<br />
**v1.5.0+:** On other platforms, this config entry is supported in Consul versions 1.5.0+.
The `proxy-defaults` config entry kind (`ProxyDefaults` on Kubernetes) allows for configuring global config
defaults across all services for Connect proxy configuration. Currently, only
one global entry is supported.
## Sample Config Entries
Set the default protocol for all sidecar proxies in the default namespace:
### Default protocol
<Tabs>
<Tab heading="HCL">
Set the default protocol for all sidecar proxies:
```hcl
Kind = "proxy-defaults"
Name = "global"
Namespace = "default"
Config {
protocol = "http"
}
```
Set proxy-specific defaults :
</Tab>
<Tab heading="HCL (Consul Enterprise)">
Set the default protocol for all sidecar proxies.
**NOTE:** The `proxy-defaults` config entry can only be created in the `default`
namespace and it will configure proxies in **all** namespaces.
```hcl
Kind = "proxy-defaults"
Name = "global"
Kind = "proxy-defaults"
Name = "global"
Namespace = "default" # Can only be set to "default".
Config {
protocol = "http"
}
```
</Tab>
<Tab heading="Kubernetes YAML">
Set the default protocol for all sidecar proxies:
```yaml
apiVersion: consul.hashicorp.com/v1alpha1
kind: ProxyDefaults
metadata:
name: global
spec:
config:
protocol: http
```
</Tab>
<Tab heading="Kubernetes YAML (Consul Enterprise)">
Set the default protocol for all sidecar proxies:
```yaml
apiVersion: consul.hashicorp.com/v1alpha1
kind: ProxyDefaults
metadata:
name: global
spec:
config:
protocol: http
```
</Tab>
</Tabs>
### Proxy-specific defaults
<Tabs>
<Tab heading="HCL">
Set proxy-specific defaults:
```hcl
Kind = "proxy-defaults"
Name = "global"
Config {
local_connect_timeout_ms = 1000
handshake_timeout_ms = 10000
}
```
</Tab>
<Tab heading="Kubernetes YAML">
Set proxy-specific defaults:
```yaml
apiVersion: consul.hashicorp.com/v1alpha1
kind: ProxyDefaults
metadata:
name: global
spec:
config:
local_connect_timeout_ms: 1000
handshake_timeout_ms: 10000
```
</Tab>
</Tabs>
## Available Fields
- `Kind` - Must be set to `proxy-defaults`
- `Name` - Must be set to `global`
- `Namespace` `(string: "default")` <EnterpriseAlert inline /> - Specifies the namespace the config entry will apply to.
- `Meta` `(map<string|string>: nil)` - Specifies arbitrary KV metadata pairs. Added in Consul 1.8.4.
- `Config` `(map[string]arbitrary)` - An arbitrary map of configuration values used by Connect proxies.
The available configurations depend on the Connect proxy you use. Any values
that your proxy allows can be configured globally here. To
explore these options please see the documentation for your chosen proxy.
- [Envoy](/docs/connect/proxies/envoy#bootstrap-configuration)
- [Consul's built-in proxy](/docs/connect/proxies/built-in)
- `MeshGateway` `(MeshGatewayConfig: <optional>)` - Controls the default
[mesh gateway configuration](/docs/connect/mesh-gateway#connect-proxy-configuration)
for all proxies. Added in v1.6.0.
- `Mode` `(string: "")` - One of `none`, `local`, or `remote`.
- `Expose` `(ExposeConfig: <optional>)` - Controls the default
[expose path configuration](/docs/connect/registration/service-registration#expose-paths-configuration-reference)
for Envoy. Added in v1.6.2.
Exposing paths through Envoy enables a service to protect itself by only listening on localhost, while still allowing
non-Connect-enabled applications to contact an HTTP endpoint.
Some examples include: exposing a `/metrics` path for Prometheus or `/healthz` for kubelet liveness checks.
- `Checks` `(bool: false)` - If enabled, all HTTP and gRPC checks registered with the agent are exposed through Envoy.
Envoy will expose listeners for these checks and will only accept connections originating from localhost or Consul's
[advertise address](/docs/agent/options#advertise). The port for these listeners are dynamically allocated from
[expose_min_port](/docs/agent/options#expose_min_port) to [expose_max_port](/docs/agent/options#expose_max_port).
This flag is useful when a Consul client cannot reach registered services over localhost. One example is when running
Consul on Kubernetes, and Consul agents run in their own pods.
- `Paths` `array<Path>: []` - A list of paths to expose through Envoy.
- `Path` `(string: "")` - The HTTP path to expose. The path must be prefixed by a slash. ie: `/metrics`.
- `LocalPathPort` `(int: 0)` - The port where the local service is listening for connections to the path.
- `ListenerPort` `(int: 0)` - The port where the proxy will listen for connections. This port must be available
for the listener to be set up. If the port is not free then Envoy will not expose a listener for the path,
but the proxy registration will not fail.
- `Protocol` `(string: "http")` - Sets the protocol of the listener. One of `http` or `http2`. For gRPC use `http2`.
<ConfigEntryReference
keys={[
{
name: 'apiVersion',
description: 'Must be set to `consul.hashicorp.com/v1alpha1`',
hcl: false,
},
{
name: 'Kind',
description: {
hcl: 'Must be set to `proxy-defaults`',
yaml: 'Must be set to `ProxyDefaults`',
},
},
{
name: 'Name',
description: 'Must be set to `global`',
yaml: false,
},
{
name: 'Namespace',
type: `string: "default"`,
enterprise: true,
description: 'Specifies the namespace the config entry will apply to.',
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: 'Must be set to `global`' }],
hcl: false,
},
{
name: 'Config',
type: 'map[string]arbitrary',
description: `An arbitrary map of configuration values used by Connect proxies.
The available configurations depend on the Connect proxy you use.
Any values that your proxy allows can be configured globally here. To explore these options please see the documentation for your chosen proxy.
<ul><li>[Envoy](/docs/connect/proxies/envoy#bootstrap-configuration)</li>
<li>[Consul's built-in proxy](/docs/connect/proxies/built-in)</li></ul>`,
},
{
name: 'MeshGateway',
type: 'MeshGatewayConfig: <optional>',
description: `Controls the default
[mesh gateway configuration](/docs/connect/mesh-gateway#connect-proxy-configuration)
for all proxies. Added in v1.6.0.`,
children: [
{
name: 'Mode',
type: 'string: ""',
description: 'One of `none`, `local`, or `remote`.',
},
],
},
{
name: 'Expose',
type: 'ExposeConfig: <optional>',
description: `Controls the default
[expose path configuration](/docs/connect/registration/service-registration#expose-paths-configuration-reference)
for Envoy. Added in v1.6.2.<br><br>
Exposing paths through Envoy enables a service to protect itself by only listening on localhost, while still allowing
non-Connect-enabled applications to contact an HTTP endpoint.
Some examples include: exposing a \`/metrics\` path for Prometheus or \`/healthz\` for kubelet liveness checks.`,
children: [
{
name: 'Checks',
type: 'bool: false',
description: `If enabled, all HTTP and gRPC checks registered with the agent are exposed through Envoy.
Envoy will expose listeners for these checks and will only accept connections originating from localhost or Consul's
[advertise address](/docs/agent/options#advertise). The port for these listeners are dynamically allocated from
[expose_min_port](/docs/agent/options#expose_min_port) to [expose_max_port](/docs/agent/options#expose_max_port).
This flag is useful when a Consul client cannot reach registered services over localhost. One example is when running
Consul on Kubernetes, and Consul agents run in their own pods.`,
},
{
name: 'Paths',
type: 'array<Path>: []',
description: 'A list of paths to expose through Envoy.',
children: [
{
name: 'Path',
type: 'string: ""',
description:
'The HTTP path to expose. The path must be prefixed by a slash. ie: `/metrics`.',
},
{
name: 'LocalPathPort',
type: 'int: 0',
description:
'The port where the local service is listening for connections to the path.',
},
{
name: 'ListenerPort',
type: 'int: 0',
description: `The port where the proxy will listen for connections. This port must be available
for the listener to be set up. If the port is not free then Envoy will not expose a listener for the path,
but the proxy registration will not fail.`,
},
{
name: 'Protocol',
type: 'string: "http"',
description:
'Sets the protocol of the listener. One of `http` or `http2`. For gRPC use `http2`.',
},
],
},
],
},
]}
/>
## ACLs

View File

@ -9,11 +9,19 @@ description: >-
# Service Defaults
The `service-defaults` config entry kind controls default global values for a
-> **v1.8.4+:** On Kubernetes, the `ServiceDefaults` custom resource is supported in Consul versions 1.8.4+.<br />
**v1.5.0+:** On other platforms, this config entry is supported in Consul versions 1.5.0+.
The `service-defaults` config entry kind (`ServiceDefaults` on Kubernetes) controls default global values for a
service, such as its protocol.
## Sample Config Entries
### Default protocol
<Tabs>
<Tab heading="HCL">
Set the default protocol for a service in the default namespace to HTTP:
```hcl
@ -23,56 +31,158 @@ Namespace = "default"
Protocol = "http"
```
</Tab>
<Tab heading="Kubernetes YAML">
Set the default protocol for a service in the default namespace to HTTP:
```yaml
apiVersion: consul.hashicorp.com/v1alpha1
kind: ServiceDefaults
metadata:
name: web
spec:
protocol: http
```
</Tab>
</Tabs>
## Available Fields
- `Kind` - Must be set to `service-defaults`
- `Name` `(string: <required>)` - Set to the name of the service being configured.
- `Namespace` `(string: "default")` <EnterpriseAlert inline /> - Specifies the namespace the config entry will apply to.
- `Meta` `(map<string|string>: nil)` - Specifies arbitrary KV metadata pairs. Added in Consul 1.8.4.
- `Protocol` `(string: "tcp")` - Sets the protocol of the service. This is used
by Connect proxies for things like observability features and to unlock usage
of the [`service-splitter`](/docs/agent/config-entries/service-splitter) and
[`service-router`](/docs/agent/config-entries/service-router) config entries
for a service. It also unlocks the ability to define L7 intentions via
[`service-intentions`](/docs/agent/config-entries/service-intentions).
Supported values are one of `tcp`, `http`, `http2`, or `grpc`.
- `MeshGateway` `(MeshGatewayConfig: <optional>)` - Controls the default
[mesh gateway configuration](/docs/connect/mesh-gateway#connect-proxy-configuration)
for this service. Added in v1.6.0.
- `Mode` `(string: "")` - One of `none`, `local`, or `remote`.
- `ExternalSNI` `(string: "")` - This is an optional setting that allows for
the TLS [SNI](https://en.wikipedia.org/wiki/Server_Name_Indication) value to
be changed to a non-connect value when federating with an external system.
Added in v1.6.0.
- `Expose` `(ExposeConfig: <optional>)` - Controls the default
[expose path configuration](/docs/connect/registration/service-registration#expose-paths-configuration-reference)
for Envoy. Added in v1.6.2.
Exposing paths through Envoy enables a service to protect itself by only listening on localhost, while still allowing
non-Connect-enabled applications to contact an HTTP endpoint.
Some examples include: exposing a `/metrics` path for Prometheus or `/healthz` for kubelet liveness checks.
- `Checks` `(bool: false)` - If enabled, all HTTP and gRPC checks registered with the agent are exposed through Envoy.
Envoy will expose listeners for these checks and will only accept connections originating from localhost or Consul's
[advertise address](/docs/agent/options#advertise). The port for these listeners are dynamically allocated from
[expose_min_port](/docs/agent/options#expose_min_port) to [expose_max_port](/docs/agent/options#expose_max_port).
This flag is useful when a Consul client cannot reach registered services over localhost. One example is when running
Consul on Kubernetes, and Consul agents run in their own pods.
- `Paths` `array<Path>: []` - A list of paths to expose through Envoy.
- `Path` `(string: "")` - The HTTP path to expose. The path must be prefixed by a slash. ie: `/metrics`.
- `LocalPathPort` `(int: 0)` - The port where the local service is listening for connections to the path.
- `ListenerPort` `(int: 0)` - The port where the proxy will listen for connections. This port must be available for
the listener to be set up. If the port is not free then Envoy will not expose a listener for the path,
but the proxy registration will not fail.
- `Protocol` `(string: "http")` - Sets the protocol of the listener. One of `http` or `http2`. For gRPC use `http2`.
<ConfigEntryReference
keys={[
{
name: 'apiVersion',
description: 'Must be set to `consul.hashicorp.com/v1alpha1`',
hcl: false,
},
{
name: 'Kind',
description: {
hcl: 'Must be set to `service-defaults`',
yaml: 'Must be set to `ServiceDefaults`',
},
},
{
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 the config entry will apply to.',
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.',
},
],
hcl: false,
},
{
name: 'Protocol',
type: `string: "tcp"`,
description: `Sets the protocol of the service. This is used
by Connect proxies for things like observability features and to unlock usage
of the [\`service-splitter\`](/docs/agent/config-entries/service-splitter) and
[\`service-router\`](/docs/agent/config-entries/service-router) config entries
for a service. It also unlocks the ability to define L7 intentions via
[\`service-intentions\`](/docs/agent/config-entries/service-intentions).
Supported values are one of \`tcp\`, \`http\`, \`http2\`, or \`grpc\`.`,
},
{
name: 'MeshGateway',
type: 'MeshGatewayConfig: <optional>',
description: `Controls the default
[mesh gateway configuration](/docs/connect/mesh-gateway#connect-proxy-configuration)
for this service. Added in v1.6.0.`,
children: [
{
name: 'Mode',
type: 'string: ""',
description: 'One of `none`, `local`, or `remote`.',
},
],
},
{
name: 'ExternalSNI',
type: 'string: ""',
description: `This is an optional setting that allows for
the TLS [SNI](https://en.wikipedia.org/wiki/Server_Name_Indication) value to
be changed to a non-connect value when federating with an external system.
Added in v1.6.0.`,
},
{
name: 'Expose',
type: 'ExposeConfig: <optional>',
description: `Controls the default
[expose path configuration](/docs/connect/registration/service-registration#expose-paths-configuration-reference)
for Envoy. Added in v1.6.2.<br><br>
Exposing paths through Envoy enables a service to protect itself by only listening on localhost, while still allowing
non-Connect-enabled applications to contact an HTTP endpoint.
Some examples include: exposing a \`/metrics\` path for Prometheus or \`/healthz\` for kubelet liveness checks.`,
children: [
{
name: 'Checks',
type: 'bool: false',
description: `If enabled, all HTTP and gRPC checks registered with the agent are exposed through Envoy.
Envoy will expose listeners for these checks and will only accept connections originating from localhost or Consul's
[advertise address](/docs/agent/options#advertise). The port for these listeners are dynamically allocated from
[expose_min_port](/docs/agent/options#expose_min_port) to [expose_max_port](/docs/agent/options#expose_max_port).
This flag is useful when a Consul client cannot reach registered services over localhost. One example is when running
Consul on Kubernetes, and Consul agents run in their own pods.`,
},
{
name: 'Paths',
type: 'array<Path>: []',
description: 'A list of paths to expose through Envoy.',
children: [
{
name: 'Path',
type: 'string: ""',
description:
'The HTTP path to expose. The path must be prefixed by a slash. ie: `/metrics`.',
},
{
name: 'LocalPathPort',
type: 'int: 0',
description:
'The port where the local service is listening for connections to the path.',
},
{
name: 'ListenerPort',
type: 'int: 0',
description: `The port where the proxy will listen for connections. This port must be available
for the listener to be set up. If the port is not free then Envoy will not expose a listener for the path,
but the proxy registration will not fail.`,
},
{
name: 'Protocol',
type: 'string: "http"',
description:
'Sets the protocol of the listener. One of `http` or `http2`. For gRPC use `http2`.',
},
],
},
],
},
]}
/>
## ACLs

View File

@ -12,7 +12,7 @@ description: >-
-> **1.9.0+:** This config entry is available in Consul versions 1.9.0 and newer.
The `service-intentions` config entry kind controls Connect traffic
The `service-intentions` config entry kind (`ServiceIntentions` on Kubernetes) controls Connect traffic
authorization for both networking layer 4 (e.g. TCP) and networking layer 7
(e.g. HTTP).
@ -35,6 +35,11 @@ or globally via [`proxy-defaults`](/docs/agent/config-entries/proxy-defaults) .
## Sample Config Entries
### REST Access
<Tabs>
<Tab heading="HCL">
Grant some clients more REST access than others:
```hcl
@ -70,6 +75,44 @@ Sources = [
]
```
</Tab>
<Tab heading="Kubernetes YAML">
Grant some clients more REST access than others:
```yaml
apiVersion: consul.hashicorp.com/v1alpha1
kind: ServiceIntentions
metadata:
name: api
spec:
destination:
name: api
sources:
- name: admin-dashboard
permissions:
- action: allow
http:
pathPrefix: /v2
methods: ['GET', 'PUT', 'POST', 'DELETE', 'HEAD']
- name: report-generator
permissions:
- action: allow
http:
pathPrefix: /v2/widgets
methods: ['GET']
# NOTE: a default catch-all based on the default ACL policy will apply to
# unmatched connections and requests. Typically this will be DENY.
```
</Tab>
</Tabs>
## gRPC
<Tabs>
<Tab heading="HCL">
Selectively deny some gRPC service methods. Since gRPC method calls [are
HTTP/2](https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-HTTP2.md), we can
use an HTTP path match rule to control traffic:
@ -114,6 +157,50 @@ Sources = [
]
```
</Tab>
<Tab heading="Kubernetes YAML">
Selectively deny some gRPC service methods. Since gRPC method calls [are
HTTP/2](https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-HTTP2.md), we can
use an HTTP path match rule to control traffic:
```yaml
apiVersion: consul.hashicorp.com/v1alpha1
kind: ServiceIntentions
metadata:
name: billing
spec:
destination:
name: billing
sources:
# The frontend website can execute all billing service methods except
# issuing refunds.
- name: frontend-web
permissions:
- action: deny
http:
pathExact: /mycompany.BillingService/IssueRefund
- action: allow
http:
pathPrefix: '/mycompany.BillingService/'
- name: support-protocol
# But the support team portal page can execute all methods.
permissions:
- action: allow
http:
pathPrefix: '/mycompany.BillingService/'
# NOTE: a default catch-all based on the default ACL policy will apply to
# unmatched connections and requests. Typically this will be DENY.
```
</Tab>
</Tabs>
## L4 and L7
<Tabs>
<Tab heading="HCL">
You can mix and match L4 and L7 intentions per source:
```hcl
@ -145,167 +232,379 @@ Sources = [
]
```
</Tab>
<Tab heading="Kubernetes YAML">
You can mix and match L4 and L7 intentions per source:
```yaml
apiVersion: consul.hashicorp.com/v1alpha1
kind: ServiceIntentions
metadata:
name: api
spec:
destination:
name: api
sources:
- name: hackathon-project
action: deny
- name: web
action: allow
- name: nightly-reconciler
permissions:
- action: allow
http:
pathExact: /v1/reconcile-data
methods: ['POST']
# NOTE: a default catch-all based on the default ACL policy will apply to
# unmatched connections and requests. Typically this will be DENY.
```
</Tab>
</Tabs>
## Available Fields
- `Kind` - Must be set to `service-intentions`.
- `Name` `(string: <required>)` - The destination of all intentions defined in
this config entry. This may be set to the wildcard character (`*`) to match
all services that don't otherwise have intentions defined.
- `Namespace` `(string: "default")` <EnterpriseAlert inline /> - Specifies the namespace the config entry will apply to.
This may be set to the wildcard character (`*`) to match
all services in all namespaces that don't otherwise have intentions defined.
- `Meta` `(map<string|string>: nil)` - Specifies arbitrary KV metadata pairs.
- `Sources` `(array<SourceIntention>)` - The list of all [intention sources and
the authorization granted to those sources](#sourceintention). The order of
this list does not matter, but out of convenience Consul will always store
this reverse sorted by intention precedence, as that is the order that they
will be evaluated at enforcement time.
<ConfigEntryReference
keys={[
{
name: 'apiVersion',
description: 'Must be set to `consul.hashicorp.com/v1alpha1`',
hcl: false,
},
{
name: 'Kind',
description: {
hcl: 'Must be set to `service-intentions`',
yaml: 'Must be set to `ServiceIntentions`',
},
},
{
name: 'Name',
description:
"The name of the destination service for all intentions defined in this config entry. This may be set to the wildcard character (`*`) to match all services that don't otherwise have intentions defined.",
type: 'string: <required>',
yaml: false,
},
{
name: 'Namespace',
type: `string: "default"`,
enterprise: true,
description:
"Specifies the namespaces the config entry will apply to. This may be set to the wildcard character (`*`) to match all services in all namespaces that don't otherwise have intentions defined.",
yaml: false,
},
{
name: 'Meta',
type: 'map<string|string>: nil',
description: 'Specifies arbitrary KV metadata pairs.',
yaml: false,
},
{
name: 'metadata',
children: [
{
name: 'name',
description:
'Unlike other config entries, the `metadata.name` field is not used to set the name of the service being configured. Instead, that is set in `spec.destination.name`. Thus this name can be set to anything.',
},
],
hcl: false,
},
{
name: 'destination',
hcl: false,
children: [
{
name: 'name',
hcl: false,
type: 'string: <required>',
description:
"The name of the destination service for all intentions defined in this config entry. This may be set to the wildcard character (`*`) to match all services that don't otherwise have intentions defined.",
},
{
name: 'namespace',
hcl: false,
enterprise: true,
type: 'string: <required>',
description:
"Specifies the namespaces the config entry will apply to. This may be set to the wildcard character (`*`) to match all services in all namespaces that don't otherwise have intentions defined.",
},
],
},
{
name: 'Sources',
type: 'array<SourceIntention>',
description: `The list of all [intention sources and the authorization granted to those sources](#sourceintention). The order of
this list does not matter, but out of convenience Consul will always store
this reverse sorted by intention precedence, as that is the order that they
will be evaluated at enforcement time.`,
},
]}
/>
### `SourceIntention`
- `Name` `(string: <required>)` - The source of the intention.
For a `Type` of `consul` this is the name of a Consul service. The service
doesn't need to be registered.
- `Namespace` `(string: "default")` <EnterpriseAlert inline /> - The namespace
for the `Name` parameter.
- `Action` `(string: "")` - For an L4 intention this is required, and should be
set to one of `"allow"` or `"deny"` for the action that should be taken if
this intention matches a request.
This should be omitted for an L7 intention as it is mutually exclusive with
the `Permissions` field.
- `Permissions` `(array<IntentionPermission>)` - The list of all [additional L7
attributes](#intentionpermission) that extend the intention match criteria.
Permission precedence is applied top to bottom. For any given request the
first permission to match in the list is terminal and stops further
evaluation. As with L4 intentions, traffic that fails to match any of the
provided permissions in this intention will be subject to the default
intention behavior is defined by the default [ACL
policy](/docs/agent/options#acl_default_policy).
This should be omitted for an L4 intention as it is mutually exclusive with
the `Action` field.
- `Precedence` `(int: <read-only>)` - An [integer precedence
value](/docs/connect/intentions#precedence-and-match-order) computed from the
source and destination naming components.
- `Type` `(string: "")` - The type for the `Name` value. This can be
only "consul" today to represent a Consul service. If not provided, this
will be defaulted to "consul".
- `Description` `(string: "")` - Description for the intention. This is not
used by Consul, but is presented in API responses to assist tooling.
- `LegacyID` `(string: <read-only>)` - This is the UUID to uniquely identify
this intention in the system. Cannot be set directly and is exposed here as
an artifact of the config entry migration and is primarily used to allow
legacy intention [API](/api-docs/connect/intentions#update-intention-by-id)
[endpoints](/api-docs/connect/intentions#read-specific-intention-by-id) to
continue to function for a period of time after [upgrading to
1.9.0](/docs/upgrading/upgrade-specific#consul-1-9-0).
- `LegacyMeta` `(map<string|string>: <read-only>)` - Specified arbitrary KV
metadata pairs attached to the intention, rather than to the enclosing config
entry. Cannot be set directly and is exposed here as an artifact of the
config entry migration and is primarily used to allow legacy intention
[API](/api-docs/connect/intentions#update-intention-by-id)
[endpoints](/api-docs/connect/intentions#read-specific-intention-by-id) to
continue to function for a period of time after [upgrading to
1.9.0](/docs/upgrading/upgrade-specific#consul-1-9-0).
- `LegacyCreateTime` `(time: optional)` - The timestamp that this intention was
created. Cannot be set directly and is exposed here as an artifact of the
config entry migration and is primarily used to allow legacy intention
[API](/api-docs/connect/intentions#update-intention-by-id)
[endpoints](/api-docs/connect/intentions#read-specific-intention-by-id) to
continue to function for a period of time after [upgrading to
1.9.0](/docs/upgrading/upgrade-specific#consul-1-9-0).
- `LegacyUpdateTime` `(time: optional)` - The timestamp that this intention was
last updated. Cannot be set directly and is exposed here as an artifact of
the config entry migration and is primarily used to allow legacy intention
[API](/api-docs/connect/intentions#update-intention-by-id)
[endpoints](/api-docs/connect/intentions#read-specific-intention-by-id) to
continue to function for a period of time after [upgrading to
1.9.0](/docs/upgrading/upgrade-specific#consul-1-9-0).
<ConfigEntryReference
topLevel={false}
keys={[
{
name: 'Name',
type: 'string: <required>',
description: {
hcl:
"The source of the intention. For a `Type` of `consul` this is the name of a Consul service. The service doesn't need to be registered.",
yaml:
"The source of the intention. For a `type` of `consul` this is the name of a Consul service. The service doesn't need to be registered.",
},
},
{
name: 'Namespace',
type: 'string',
description: {
hcl:
"The namespace of the source service. Defaults to the namespace of the destination service (i.e. the config entry's namespace)",
yaml:
'The namespace of the source service. Defaults to the namespace of the destination service (i.e. `spec.destination.namespace`)',
},
enterprise: true,
},
{
name: 'Action',
type: 'string: ""',
description: {
hcl:
'For an L4 intention this is required, and should be set to one of `"allow"` or `"deny"` for the action that should be taken if this intention matches a request.' +
'<br><br>This should be omitted for an L7 intention as it is mutually exclusive with the `Permissions` field.',
yaml:
'For an L4 intention this is required, and should be set to one of `"allow"` or `"deny"` for the action that should be taken if this intention matches a request.' +
'<br><br>This should be omitted for an L7 intention as it is mutually exclusive with the `permissions` field.',
},
},
{
name: 'Permissions',
type: 'array<IntentionPermission>',
description: {
hcl: `The list of all [additional L7 attributes](#intentionpermission) that extend the intention match criteria.<br><br>
Permission precedence is applied top to bottom. For any given request the
first permission to match in the list is terminal and stops further
evaluation. As with L4 intentions, traffic that fails to match any of the
provided permissions in this intention will be subject to the default
intention behavior is defined by the default [ACL policy](/docs/agent/options#acl_default_policy).<br><br>
This should be omitted for an L4 intention as it is mutually exclusive with
the \`Action\` field.`,
yaml: `The list of all [additional L7 attributes](#intentionpermission) that extend the intention match criteria.<br><br>
Permission precedence is applied top to bottom. For any given request the
first permission to match in the list is terminal and stops further
evaluation. As with L4 intentions, traffic that fails to match any of the
provided permissions in this intention will be subject to the default
intention behavior is defined by the default [ACL policy](/docs/agent/options#acl_default_policy).<br><br>
This should be omitted for an L4 intention as it is mutually exclusive with
the \`action\` field.`,
},
},
{
name: 'Precedence',
type: 'int: <read-only>',
description:
'An [integer precedence value](/docs/connect/intentions#precedence-and-match-order) computed from the source and destination naming components.',
yaml: false,
},
{
name: 'Type',
type: 'string: "consul"',
description: {
hcl:
'The type for the `Name` value. This can be only "consul" today to represent a Consul service. If not provided, this will be defaulted to "consul".',
yaml:
'The type for the `name` value. This can be only "consul" today to represent a Consul service. If not provided, this will be defaulted to "consul".',
},
},
{
name: 'Description',
type: 'string: ""',
description:
'Description for the intention. This is not used by Consul, but is presented in API responses to assist tooling.',
},
{
name: 'LegacyID',
type: 'string: <read-only>',
description: `This is the UUID to uniquely identify
this intention in the system. Cannot be set directly and is exposed here as
an artifact of the config entry migration and is primarily used to allow
legacy intention [API](/api-docs/connect/intentions#update-intention-by-id)
[endpoints](/api-docs/connect/intentions#read-specific-intention-by-id) to
continue to function for a period of time after [upgrading to 1.9.0](/docs/upgrading/upgrade-specific#consul-1-9-0).`,
yaml: false,
},
{
name: 'LegacyMeta',
type: 'map<string|string>: <read-only>',
description: `Specified arbitrary KV
metadata pairs attached to the intention, rather than to the enclosing config
entry. Cannot be set directly and is exposed here as an artifact of the
config entry migration and is primarily used to allow legacy intention
[API](/api-docs/connect/intentions#update-intention-by-id)
[endpoints](/api-docs/connect/intentions#read-specific-intention-by-id) to
continue to function for a period of time after [upgrading to 1.9.0](/docs/upgrading/upgrade-specific#consul-1-9-0).`,
yaml: false,
},
{
name: 'LegacyCreateTime',
type: 'time: optional',
description: `The timestamp that this intention was
created. Cannot be set directly and is exposed here as an artifact of the
config entry migration and is primarily used to allow legacy intention
[API](/api-docs/connect/intentions#update-intention-by-id)
[endpoints](/api-docs/connect/intentions#read-specific-intention-by-id) to
continue to function for a period of time after [upgrading to 1.9.0](/docs/upgrading/upgrade-specific#consul-1-9-0).`,
yaml: false,
},
{
name: 'LegacyUpdateTime',
type: 'time: optional',
description: `The timestamp that this intention was
last updated. Cannot be set directly and is exposed here as an artifact of the
config entry migration and is primarily used to allow legacy intention
[API](/api-docs/connect/intentions#update-intention-by-id)
[endpoints](/api-docs/connect/intentions#read-specific-intention-by-id) to
continue to function for a period of time after [upgrading to 1.9.0](/docs/upgrading/upgrade-specific#consul-1-9-0).`,
yaml: false,
},
]}
/>
### `IntentionPermission`
- `Action` `(string: <required>)` - This is one of "allow" or "deny" for
the action that should be taken if this permission matches a request.
- `HTTP` `(IntentionHTTPPermission: <required>)` - A set of
[HTTP-specific authorization criteria](#intentionhttppermission).
<ConfigEntryReference
topLevel={false}
keys={[
{
name: 'Action',
type: 'string: <required>',
description:
'This is one of "allow" or "deny" for the action that should be taken if this permission matches a request.',
},
{
name: 'HTTP',
type: 'IntentionHTTPPermission: <required>',
description:
'A set of [HTTP-specific authorization criteria](#intentionhttppermission)',
},
]}
/>
### `IntentionHTTPPermission`
- `PathExact` `(string: "")` - Exact path to match on the HTTP request path.
At most only one of `PathExact`, `PathPrefix`, or `PathRegex` may be configured.
- `PathPrefix` `(string: "")` - Path prefix to match on the HTTP request path.
At most only one of `PathExact`, `PathPrefix`, or `PathRegex` may be configured.
- `PathRegex` `(string: "")` - Regular expression to match on the HTTP
request path.
The syntax is [described below](#regular-expression-syntax).
At most only one of `PathExact`, `PathPrefix`, or `PathRegex` may be configured.
- `Methods` `(array<string>)` - A list of HTTP methods for which this match
applies. If unspecified all HTTP methods are matched.
If provided the names must be a valid [method](https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods).
- `Header` `(array<IntentionHTTPHeaderPermission>)` - A set of criteria that can
match on HTTP request headers. If more than one is configured all must match
for the overall match to apply.
- `Name` `(string: <required>)` - Name of the header to match.
- `Present` `(bool: false)` - Match if the header with the given name is
present with any value.
At most only one of `Exact`, `Prefix`, `Suffix`, `Regex`, or `Present`
may be configured.
- `Exact` `(string: "")` - Match if the header with the given name is this
value.
At most only one of `Exact`, `Prefix`, `Suffix`, `Regex`, or `Present`
may be configured.
- `Prefix` `(string: "")` - Match if the header with the given name has
this prefix.
At most only one of `Exact`, `Prefix`, `Suffix`, `Regex`, or `Present`
may be configured.
- `Suffix` `(string: "")` - Match if the header with the given name has
this suffix.
At most only one of `Exact`, `Prefix`, `Suffix`, `Regex`, or `Present`
may be configured.
- `Regex` `(string: "")` - Match if the header with the given name matches
this pattern.
The syntax is [described below](#regular-expression-syntax).
At most only one of `Exact`, `Prefix`, `Suffix`, `Regex`, or `Present`
may be configured.
- `Invert` `(bool: false)` - Inverts the logic of the match.
<ConfigEntryReference
topLevel={false}
keys={[
{
name: 'PathExact',
type: 'string: ""',
description: {
hcl:
'Exact path to match on the HTTP request path.<br><br>At most only one of `PathExact`, `PathPrefix`, or `PathRegex` may be configured.',
yaml:
'Exact path to match on the HTTP request path.<br><br>At most only one of `pathExact`, `pathPrefix`, or `pathRegex` may be configured.',
},
},
{
name: 'PathPrefix',
type: 'string: ""',
description: {
hcl:
'Path prefix to match on the HTTP request path.<br><br>At most only one of `PathExact`, `PathPrefix`, or `PathRegex` may be configured.',
yaml:
'Path prefix to match on the HTTP request path.<br><br>At most only one of `pathExact`, `pathPrefix`, or `pathRegex` may be configured.',
},
},
{
name: 'PathRegex',
type: 'string: ""',
description: {
hcl:
'Regular expression to match on the HTTP request path.<br><br>The syntax is [described below](#regular-expression-syntax).<br><br>At most only one of `PathExact`, `PathPrefix`, or `PathRegex` may be configured.',
yaml:
'Regular expression to match on the HTTP request path.<br><br>The syntax is [described below](#regular-expression-syntax).<br><br>At most only one of `pathExact`, `pathPrefix`, or `pathRegex` may be configured.',
},
},
{
name: 'Methods',
type: 'array<string>',
description:
'A list of HTTP methods for which this match applies. If unspecified all HTTP methods are matched. If provided the names must be a valid [method](https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods).',
},
{
name: 'Header',
type: 'array<IntentionHTTPHeaderPermission>',
description:
'A set of criteria that can match on HTTP request headers. If more than one is configured all must match for the overall match to apply.',
children: [
{
name: 'Name',
type: 'string: <required>',
description: 'Name of the header to match',
},
{
name: 'Present',
type: 'bool: false',
description: {
hcl:
'Match if the header with the given name is present with any value.<br><br> At most only one of `Exact`, `Prefix`, `Suffix`, `Regex`, or `Present` may be configured.',
yaml:
'Match if the header with the given name is present with any value.<br><br> At most only one of `exact`, `prefix`, `suffix`, `regex`, or `present` may be configured.',
},
},
{
name: 'Exact',
type: 'string: ""',
description: {
hcl:
'Match if the header with the given name is this value.<br><br> At most only one of `Exact`, `Prefix`, `Suffix`, `Regex`, or `Present` may be configured.',
yaml:
'Match if the header with the given name is this value.<br><br> At most only one of `exact`, `prefix`, `suffix`, `regex`, or `present` may be configured.',
},
},
{
name: 'Prefix',
type: 'string: ""',
description: {
hcl:
'Match if the header with the given name has this prefix.<br><br> At most only one of `Exact`, `Prefix`, `Suffix`, `Regex`, or `Present` may be configured.',
yaml:
'Match if the header with the given name has this prefix.<br><br> At most only one of `exact`, `prefix`, `suffix`, `regex`, or `present` may be configured.',
},
},
{
name: 'Suffix',
type: 'string: ""',
description: {
hcl:
'Match if the header with the given name has this suffix.<br><br> At most only one of `Exact`, `Prefix`, `Suffix`, `Regex`, or `Present` may be configured.',
yaml:
'Match if the header with the given name has this suffix.<br><br> At most only one of `exact`, `prefix`, `suffix`, `regex`, or `present` may be configured.',
},
},
{
name: 'Regex',
type: 'string: ""',
description: {
hcl:
'Match if the header with the given name matches this pattern.<br><br>The syntax is [described below](#regular-expression-syntax).<br><br> At most only one of `Exact`, `Prefix`, `Suffix`, `Regex`, or `Present` may be configured.',
yaml:
'Match if the header with the given name matches this pattern.<br><br>The syntax is [described below](#regular-expression-syntax).<br><br> At most only one of `exact`, `prefix`, `suffix`, `regex`, or `present` may be configured.',
},
},
{
name: 'Invert',
type: 'bool: false',
description: 'Inverts the logic of the match',
},
],
},
]}
/>
## ACLs

View File

@ -9,9 +9,10 @@ description: >-
# Service Resolver
-> **1.6.0+:** This config entry is available in Consul versions 1.6.0 and newer.
-> **v1.8.4+:** On Kubernetes, the `ServiceResolver` 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-resolver` config entry kind controls which service instances
The `service-resolver` config entry kind (`ServiceResolver` on Kubernetes) controls which service instances
should satisfy Connect upstream discovery requests for a given service name.
If no resolver config is defined the chain assumes 100% of traffic goes to the
@ -25,6 +26,11 @@ and discovery terminates.
## Sample Config Entries
### Filter on service version
<Tabs>
<Tab heading="HCL">
Create service subsets based on a version metadata and override the defaults:
```hcl
@ -41,6 +47,33 @@ Subsets = {
}
```
</Tab>
<Tab heading="Kubernetes YAML">
Create service subsets based on a version metadata and override the defaults:
```yaml
apiVersion: consul.hashicorp.com/v1alpha1
kind: ServiceResolver
metadata:
name: web
spec:
defaultSubset: 'v1'
subsets:
'v1':
filter: 'Service.Meta.version == v1'
'v2':
filter: 'Service.Meta.version == v2'
```
</Tab>
</Tabs>
### Other datacenters
<Tabs>
<Tab heading="HCL">
Expose a set of services in another datacenter as a virtual service:
```hcl
@ -52,6 +85,30 @@ Redirect {
}
```
</Tab>
<Tab heading="Kubernetes YAML">
Expose a set of services in another datacenter as a virtual service:
```yaml
apiVersion: consul.hashicorp.com/v1alpha1
kind: ServiceResolver
metadata:
name: web-dc2
spec:
redirect:
service: web
datacenter: dc2
```
</Tab>
</Tabs>
### Datacenter failover
<Tabs>
<Tab heading="HCL">
Enable failover for all subsets:
```hcl
@ -65,13 +122,31 @@ Failover = {
}
```
Representation of the defaults when a resolver is not configured:
</Tab>
<Tab heading="Kubernetes YAML">
```hcl
Kind = "service-resolver"
Name = "web"
Enable failover for all subsets:
```yaml
apiVersion: consul.hashicorp.com/v1alpha1
kind: ServiceResolver
metadata:
name: web
spec:
connectTimeout: 15s
failover:
'*':
datacenters: ['dc3', 'dc4']
```
</Tab>
</Tabs>
### Consistent load balancing
<Tabs>
<Tab heading="HCL">
Apply consistent load balancing for requests based on `x-user-id` header:
```hcl
@ -89,137 +164,335 @@ LoadBalancer = {
}
```
</Tab>
<Tab heading="Kubernetes YAML">
Apply consistent load balancing for requests based on `x-user-id` header:
```yaml
apiVersion: consul.hashicorp.com/v1alpha1
kind: ServiceResolver
metadata:
name: web
spec:
loadBalancer:
policy: maglev
hashPolicies:
- field: header
fieldValue: x-user-id
```
</Tab>
</Tabs>
## Available Fields
- `Kind` - Must be set to `service-resolver`
- `Name` `(string: <required>)` - Set to the name of the service being configured.
- `Namespace` `(string: "default")` <EnterpriseAlert inline /> - Specifies the namespace the config entry will apply to.
- `Meta` `(map<string|string>: nil)` - Specifies arbitrary KV metadata pairs. Added in Consul 1.8.4.
- `ConnectTimeout` `(duration: 0s)` - The timeout for establishing new network
connections to this service.
- `DefaultSubset` `(string: "")` - The subset to use when no explicit subset is
requested. If empty the unnamed subset is used.
- `Subsets` `(map[string]ServiceResolverSubset)` - A map of subset name to
subset definition for all usable named subsets of this service. The map key
is the name of the subset and all names must be valid DNS subdomain elements.
This may be empty, in which case only the unnamed default subset will be
usable.
- `Filter` `(string: "")` - The
[filter expression](/api/features/filtering) to be used for selecting
instances of the requested service. If empty all healthy instances are
returned. This expression can filter on the same selectors as the
[Health API endpoint](/api/health#filtering-2).
- `OnlyPassing` `(bool: false)` - Specifies the behavior of the resolver's
health check interpretation. If this is set to false, instances with checks
in the passing as well as the warning states will be considered healthy. If
this is set to true, only instances with checks in the passing state will
be considered healthy.
- `Redirect` `(ServiceResolverRedirect: <optional>)` - When configured, all
attempts to resolve the service this resolver defines will be substituted for
the supplied redirect EXCEPT when the redirect has already been applied.
When substituting the supplied redirect into the all other fields besides
`Kind`, `Name`, and `Redirect` will be ignored.
- `Service` `(string: "")` - A service to resolve instead of the current
service.
- `ServiceSubset` `(string: "")` - 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.
If this is specified at least one of Service, Datacenter, or Namespace
should be configured.
- `Namespace` `(string: "")` - The namespace to resolve the service from
instead of the current one.
- `Datacenter` `(string: "")` - The datacenter to resolve the service from
instead of the current one.
- `Failover` `(map[string]ServiceResolverFailover`) - Controls when and how to
reroute traffic to an alternate pool of service instances.
The map is keyed by the service subset it applies to and the special
string `"*"` is a wildcard that applies to any subset not otherwise
specified here.
`Service`, `ServiceSubset`, `Namespace`, and `Datacenters` cannot all be
empty at once.
- `Service` `(string: "")` - The service to resolve instead of the default as
the failover group of instances during failover.
- `ServiceSubset` `(string: "")` - The named subset of the requested service
to resolve as the failover group of instances. If empty the default subset
for the requested service is used.
- `Namespace` `(string: "")` - The namespace to resolve the requested service
from to form the failover group of instances. If empty the current
namespace is used.
- `Datacenters` `(array<string>)` - A fixed list of datacenters to try during
failover.
- `LoadBalancer` `(LoadBalancer`) - Determines the load balancing policy and
configuration for services issuing requests to this upstream.
This option is available in Consul versions 1.9.0 and newer.
- `Policy` `(string: "")` - The load balancing policy used to select a host.
One of: `random`, `round_robin`, `least_request`, `ring_hash`, `maglev`.
- `RingHashConfig` `(RingHashConfig)` - Configuration for the `ring_hash`
policy type.
- `MinimumRingRize` `(int: 1024)` - Determines the minimum number of entries
in the hash ring.
- `MaximumRingRize` `(int: 8192)` - Determines the maximum number of entries
in the hash ring.
- `LeastRequestConfig` `(LeastRequestConfig)` - Configuration for the `least_request`
policy type.
- `ChoiceCount` `(int: 2)` - Determines the number of random healthy hosts
from which to select the one with the least requests.
- `HashPolicies` `(array<HashPolicies>)` - a list of hash policies to use for
hashing load balancing algorithms. Hash policies are evaluated individually
and combined such that identical lists result in the same hash.
If no hash policies are present, or none are successfully evaluated,
then a random backend host will be selected.
- `Field` `(string: "")` - The attribute type to hash on.
Must be one of `header`,`cookie`, or `query_parameter`.
Cannot be specified along with `SourceAddress`.
- `FieldValue` `(string: "")` - The value to hash.
ie. header name, cookie name, URL query parameter name.
Cannot be specified along with `SourceAddress`.
- `CookieConfig` `(CookieConfig)` - Additional configuration for the "cookie" hash policy type.
This is specified to have Envoy generate a cookie for a client on its first request.
- `Session` `(bool: false)` - Generates a session cookie with no expiration.
- `TTL` `(duration: 0s)` - TTL for generated cookies. Cannot be specified for session cookies.
- `Path` `(string: "")` - The path to set for the cookie.
- `SourceIP` `(bool: false)` - Determines whether the hash should be of the source IP
address rather than of a field and field value.
Cannot be specified along with `Field` or `FieldValue`.
- `Terminal` `(bool: false)` - Will short circuit the computation of the hash
when multiple hash policies are present. If a hash is computed when a
Terminal policy is evaluated, then that hash will be used and subsequent
hash policies will be ignored.
<ConfigEntryReference
keys={[
{
name: 'apiVersion',
description: 'Must be set to `consul.hashicorp.com/v1alpha1`',
hcl: false,
},
{
name: 'Kind',
description: {
hcl: 'Must be set to `service-resolver`',
yaml: 'Must be set to `ServiceResolver`',
},
},
{
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 the config entry will apply to.',
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.',
},
],
hcl: false,
},
{
name: 'ConnectTimeout',
type: 'duration: 0s',
description:
'The timeout for establishing new network connections to this service.',
},
{
name: 'DefaultSubset',
type: 'string: ""',
description:
'The subset to use when no explicit subset is requested. If empty the unnamed subset is used.',
},
{
name: 'Subsets',
type: 'map[string]ServiceResolverSubset',
description:
'A map of subset name to subset definition for all usable named subsets of this service. The map key is the name of the subset and all names must be valid DNS subdomain elements.<br><br>This may be empty, in which case only the unnamed default subset will be usable.',
children: [
{
name: 'Filter',
type: 'string: ""',
description: `The [filter expression](/api/features/filtering) to be used for selecting
instances of the requested service. If empty all healthy instances are
returned. This expression can filter on the same selectors as the
[Health API endpoint](/api/health#filtering-2).`,
},
{
name: 'OnlyPassing',
type: 'bool: false',
description: `Specifies the behavior of the resolver's
health check interpretation. If this is set to false, instances with checks
in the passing as well as the warning states will be considered healthy. If
this is set to true, only instances with checks in the passing state will
be considered healthy.`,
},
],
},
{
name: 'Redirect',
type: 'ServiceResolverRedirect: <optional>',
description: {
hcl: `When configured, all
attempts to resolve the service this resolver defines will be substituted for
the supplied redirect EXCEPT when the redirect has already been applied.
<br><br>
When substituting the supplied redirect into the all other fields besides
\`Kind\`, \`Name\`, and \`Redirect\` will be ignored.`,
yaml: `When configured, all
attempts to resolve the service this resolver defines will be substituted for
the supplied redirect EXCEPT when the redirect has already been applied.
<br><br>
When substituting the supplied redirect into the all other fields besides
\`redirect\` will be ignored.`,
},
children: [
{
name: 'Service',
type: 'string: ""',
description: 'A service to resolve instead of the current service.',
},
{
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.
<br><br>
If this is specified at least one of \`Service\`, \`Datacenter\`, or \`Namespace\`
should be configured.`,
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.
<br><br>
If this is specified at least one of \`service\`, \`datacenter\`, or \`namespace\`
should be configured.`,
},
},
{
name: 'Namespace',
enterprise: true,
type: 'string: ""',
description:
'The namespace to resolve the service from instead of the current one.',
},
{
name: 'Datacenter',
type: 'string: ""',
description:
'The datacenter to resolve the service from instead of the current one.',
},
],
},
{
name: 'Failover',
type: 'map[string]ServiceResolverFailover',
description: {
hcl: `Controls when and how to
reroute traffic to an alternate pool of service instances.
<br><br>
The map is keyed by the service subset it applies to and the special
string \`"*"\` is a wildcard that applies to any subset not otherwise
specified here.
<br><br>
\`Service\`, \`ServiceSubset\`, \`Namespace\`, and \`Datacenters\` cannot all be
empty at once.`,
yaml: `Controls when and how to
reroute traffic to an alternate pool of service instances.
<br><br>
The map is keyed by the service subset it applies to and the special
string \`"*"\` is a wildcard that applies to any subset not otherwise
specified here.
<br><br>
\`service\`, \`serviceSubset\`, \`namespace\`, and \`datacenters\` cannot all be
empty at once.`,
},
children: [
{
name: 'Service',
type: 'string: ""',
description:
'The service to resolve instead of the default as the failover group of instances during failover.',
},
{
name: 'ServiceSubset',
type: 'string: ""',
description:
'The named subset of the requested service to resolve as the failover group of instances. If empty the default subset for the requested service is used.',
},
{
name: 'Namespace',
enterprise: true,
type: 'string: ""',
description:
'The namespace to resolve the requested service from to form the failover group of instances. If empty the current namespace is used.',
},
{
name: 'Datacenters',
type: 'array<string>',
description: 'A fixed list of datacenters to try during failover.',
},
],
},
{
name: 'LoadBalancer',
type: 'LoadBalancer',
description:
'Determines the load balancing policy and configuration for services issuing requests to this upstream. This option is available in Consul versions 1.9.0 and newer.',
children: [
{
name: 'Policy',
type: 'string: ""',
description:
'The load balancing policy used to select a host. One of: `random`, `round_robin`, `least_request`, `ring_hash`, `maglev`.',
},
{
name: 'RingHashConfig',
type: 'RingHashConfig',
description: 'Configuration for the `ring_hash` policy type.',
children: [
{
name: 'MinimumRingRize',
type: 'int: 1024',
description:
'Determines the minimum number of entries in the hash ring.',
},
{
name: 'MaximumRingRize',
type: 'int: 8192',
description:
'Determines the maximum number of entries in the hash ring.',
},
],
},
{
name: 'LeastRequestConfig',
type: 'LeastRequestConfig',
description: 'Configuration for the `least_request` policy type.',
children: [
{
name: 'ChoiceCount',
type: 'int: 2',
description:
'Determines the number of random healthy hosts from which to select the one with the least requests.',
},
],
},
{
name: 'HashPolicies',
type: 'array<HashPolicies>',
description: `List of hash policies to use for
hashing load balancing algorithms. Hash policies are evaluated individually
and combined such that identical lists result in the same hash.
If no hash policies are present, or none are successfully evaluated,
then a random backend host will be selected.`,
children: [
{
name: 'Field',
type: 'string: ""',
description: {
hcl:
'The attribute type to hash on. Must be one of `header`, `cookie`, or `query_parameter`. Cannot be specified along with `SourceAddress`.',
yaml:
'The attribute type to hash on. Must be one of `header`, `cookie`, or `query_parameter`. Cannot be specified along with `sourceAddress`.',
},
},
{
name: 'FieldValue',
type: 'string: ""',
description: {
hcl:
'The value to hash. ie. header name, cookie name, URL query parameter name. Cannot be specified along with `SourceAddress`.',
yaml:
'The value to hash. ie. header name, cookie name, URL query parameter name. Cannot be specified along with `sourceAddress`.',
},
},
{
name: 'CookieConfig',
type: 'CookieConfig',
description:
'Additional configuration for the "cookie" hash policy type. This is specified to have Envoy generate a cookie for a client on its first request.',
children: [
{
name: 'Session',
type: 'bool: false',
description: 'Generates a session cookie with no expiration.',
},
{
name: 'TTL',
type: 'duration: 0s',
description:
'TTL for generated cookies. Cannot be specified for session cookies.',
},
{
name: 'Path',
type: 'string: ""',
description: 'The path to set for the cookie.',
},
],
},
{
name: 'SourceIP',
type: 'bool: false',
description: {
hcl:
'Determines whether the hash should be of the source IP address rather than of a field and field value. Cannot be specified along with `Field` or `FieldValue`.',
yaml:
'Determines whether the hash should be of the source IP address rather than of a field and field value. Cannot be specified along with `field` or `fieldValue`.',
},
},
{
name: 'Terminal',
type: 'bool: false',
description:
'Will short circuit the computation of the hash when multiple hash policies are present. If a hash is computed when a Terminal policy is evaluated, then that hash will be used and subsequent hash policies will be ignored.',
},
],
},
],
},
]}
/>
## Service Subsets

View File

@ -9,9 +9,10 @@ description: >-
# Service Router
-> **1.6.0+:** This config entry is available in Consul versions 1.6.0 and newer.
-> **v1.8.4+:** On Kubernetes, the `ServiceRouter` 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-router` config entry kind controls Connect traffic routing and
The `service-router` config entry kind (`ServiceRouter` on Kubernetes) controls Connect traffic routing and
manipulation at networking layer 7 (e.g. HTTP).
If a router is not explicitly configured or is configured with no routes then
@ -38,6 +39,11 @@ service of the same name.
## Sample Config Entries
### Path prefix matching
<Tabs>
<Tab heading="HCL">
Route HTTP requests with a path starting with `/admin` to a different service:
```hcl
@ -59,6 +65,34 @@ Routes = [
]
```
</Tab>
<Tab heading="Kubernetes YAML">
Route HTTP requests with a path starting with `/admin` to a different service:
```yaml
apiVersion: consul.hashicorp.com/v1alpha1
kind: ServiceRouter
metadata:
name: web
spec:
routes:
- match:
http:
pathPrefix: /admin
destination:
service: admin
# NOTE: a default catch-all will send unmatched traffic to "web"
```
</Tab>
</Tabs>
### Header/query parameter matching
<Tabs>
<Tab heading="HCL">
Route HTTP requests with a special url parameter or header to a canary subset:
```hcl
@ -101,6 +135,45 @@ Routes = [
]
```
</Tab>
<Tab heading="Kubernetes YAML">
Route HTTP requests with a special url parameter or header to a canary subset:
```yaml
apiVersion: consul.hashicorp.com/v1alpha1
kind: ServiceRouter
metadata:
name: web
spec:
routes:
- match:
http:
header:
- name: x-debug
exact: '1'
destination:
service: web
serviceSubset: canary
- match:
http:
queryParam:
- name: x-debug
exact: '1'
destination:
service: web
serviceSubset: canary
# NOTE: a default catch-all will send unmatched traffic to "web"
```
</Tab>
</Tabs>
### gRPC routing
<Tabs>
<Tab heading="HCL">
Re-route a gRPC method to another service. Since gRPC method calls [are
HTTP/2](https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-HTTP2.md), we can use an HTTP path match rule to re-route traffic:
@ -123,144 +196,325 @@ Routes = [
]
```
</Tab>
<Tab heading="Kubernetes YAML">
Re-route a gRPC method to another service. Since gRPC method calls [are
HTTP/2](https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-HTTP2.md), we can use an HTTP path match rule to re-route traffic:
```yaml
apiVersion: consul.hashicorp.com/v1alpha1
kind: ServiceRouter
metadata:
name: billing
spec:
routes:
- match:
http:
pathExact: /mycompany.BillingService/GenerateInvoice
destination:
service: invoice-generator
# NOTE: a default catch-all will send unmatched traffic to "billing"
```
</Tab>
</Tabs>
## Available Fields
- `Kind` - Must be set to `service-router`
- `Name` `(string: <required>)` - Set to the name of the service being configured.
- `Namespace` `(string: "default")` <EnterpriseAlert inline /> - Specifies the namespace the config entry will apply to.
- `Meta` `(map<string|string>: nil)` - Specifies arbitrary KV metadata pairs. Added in Consul 1.8.4.
- `Routes` `(array<ServiceRoute>)` - The list of routes to consider when
processing L7 requests. The first route to match in the list is terminal and
stops further evaluation. Traffic that fails to match any of the provided
routes will be routed to the default service.
- `Match` `(ServiceRouteMatch: <optional>)` - A set of criteria that can
match incoming L7 requests. If empty or omitted it acts as a catch-all.
- `HTTP` `(ServiceRouteHTTPMatch: <optional>)` - A set of
[HTTP-specific match criteria](#serviceroutehttpmatch).
- `Destination` `(ServiceRouteDestination: <optional>)` - Controls [how to
proxy](#serviceroutedestination) the matching request(s) to a
service.
<ConfigEntryReference
keys={[
{
name: 'apiVersion',
description: 'Must be set to `consul.hashicorp.com/v1alpha1`',
hcl: false,
},
{
name: 'Kind',
description: {
hcl: 'Must be set to `service-router`',
yaml: 'Must be set to `ServiceRouter`',
},
},
{
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 the config entry will apply to.',
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.',
},
],
hcl: false,
},
{
name: 'Routes',
type: 'array<ServiceRoute>',
description: `The list of routes to consider when
processing L7 requests. The first route to match in the list is terminal and
stops further evaluation. Traffic that fails to match any of the provided
routes will be routed to the default service.`,
children: [
{
name: 'Match',
type: 'ServiceRouteMatch: <optional>',
description: `A set of criteria that can
match incoming L7 requests. If empty or omitted it acts as a catch-all.`,
children: [
{
name: 'HTTP',
type: 'ServiceRouteHTTPMatch: <optional>',
description: `A set of [HTTP-specific match criteria](#serviceroutehttpmatch).`,
},
],
},
{
name: 'Destination',
type: 'ServiceRouteDestination: <optional>',
description: `Controls [how to proxy](#serviceroutedestination) the matching request(s) to a service.`,
},
],
},
]}
/>
### `ServiceRouteHTTPMatch`
- `PathExact` `(string: "")` - Exact path to match on the HTTP request path.
At most only one of `PathExact`, `PathPrefix`, or `PathRegex` may be configured.
- `PathPrefix` `(string: "")` - Path prefix to match on the HTTP request path.
At most only one of `PathExact`, `PathPrefix`, or `PathRegex` may be configured.
- `PathRegex` `(string: "")` - Regular expression to match on the HTTP
request path.
The syntax is [described below](#regular-expression-syntax).
At most only one of `PathExact`, `PathPrefix`, or `PathRegex` may be configured.
- `Methods` `(array<string>)` - A list of HTTP methods for which this match
applies. If unspecified all HTTP methods are matched.
If provided the names must be a valid [method](https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods).
- `Header` `(array<ServiceRouteHTTPMatchHeader>)` - A set of criteria that can
match on HTTP request headers. If more than one is configured all must match
for the overall match to apply.
- `Name` `(string: <required>)` - Name of the header to match.
- `Present` `(bool: false)` - Match if the header with the given name is
present with any value.
At most only one of `Exact`, `Prefix`, `Suffix`, `Regex`, or `Present`
may be configured.
- `Exact` `(string: "")` - Match if the header with the given name is this
value.
At most only one of `Exact`, `Prefix`, `Suffix`, `Regex`, or `Present`
may be configured.
- `Prefix` `(string: "")` - Match if the header with the given name has
this prefix.
At most only one of `Exact`, `Prefix`, `Suffix`, `Regex`, or `Present`
may be configured.
- `Suffix` `(string: "")` - Match if the header with the given name has
this suffix.
At most only one of `Exact`, `Prefix`, `Suffix`, `Regex`, or `Present`
may be configured.
- `Regex` `(string: "")` - Match if the header with the given name matches
this pattern.
The syntax is [described below](#regular-expression-syntax).
At most only one of `Exact`, `Prefix`, `Suffix`, `Regex`, or `Present`
may be configured.
- `Invert` `(bool: false)` - Inverts the logic of the match.
- `QueryParam` `(array<ServiceRouteHTTPMatchQueryParam>)` - A set of criteria
that can match on HTTP query parameters. If more than one is configured all
must match for the overall match to apply.
- `Name` `(string: <required>)` - The name of the query parameter to match on.
- `Present` `(bool: false)` - Match if the query parameter with the given
name is present with any value.
At most only one of `Exact`, `Regex`, or `Present` may be configured.
- `Exact` `(string: "")` - Match if the query parameter with the given name
is this value.
At most only one of `Exact`, `Regex`, or `Present` may be configured.
- `Regex` `(string: "")` - Match if the query parameter with the given name
matches this pattern.
The syntax is [described below](#regular-expression-syntax).
At most only one of `Exact`, `Regex`, or `Present` may be configured.
<ConfigEntryReference
topLevel={false}
keys={[
{
name: 'PathExact',
type: 'string: ""',
description: {
hcl:
'Exact path to match on the HTTP request path.<br><br> At most only one of `PathExact`, `PathPrefix`, or `PathRegex` may be configured.',
yaml:
'Exact path to match on the HTTP request path.<br><br> At most only one of `pathExact`, `pathPrefix`, or `pathRegex` may be configured.',
},
},
{
name: 'PathPrefix',
type: 'string: ""',
description: {
hcl:
'Path prefix to match on the HTTP request path.<br><br> At most only one of `PathExact`, `PathPrefix`, or `PathRegex` may be configured.',
yaml:
'Path prefix to match on the HTTP request path.<br><br> At most only one of `pathExact`, `pathPrefix`, or `pathRegex` may be configured.',
},
},
{
name: 'PathRegex',
type: 'string: ""',
description: {
hcl:
'Regular expression to match on the HTTP request path.<br><br>The syntax is [described below](#regular-expression-syntax).<br><br> At most only one of `PathExact`, `PathPrefix`, or `PathRegex` may be configured.',
yaml:
'Regular expression to match on the HTTP request path.<br><br>The syntax is [described below](#regular-expression-syntax).<br><br> At most only one of `pathExact`, `pathPrefix`, or `pathRegex` may be configured.',
},
},
{
name: 'Methods',
type: 'array<string>',
description:
'A list of HTTP methods for which this match applies. If unspecified all HTTP methods are matched. If provided the names must be a valid [method](https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods).',
},
{
name: 'Header',
type: 'array<ServiceRouteHTTPMatchHeader>)',
description:
'A set of criteria that can match on HTTP request headers. If more than one is configured all must match for the overall match to apply.',
children: [
{
name: 'Name',
type: 'string: <required>',
description: 'Name of the header to match.',
},
{
name: 'Present',
type: 'bool: false',
description: {
hcl:
'Match if the header with the given name is present with any value.<br><br> At most only one of `Exact`, `Prefix`, `Suffix`, `Regex`, or `Present` may be configured.',
yaml:
'Match if the header with the given name is present with any value.<br><br> At most only one of `exact`, `prefix`, `suffix`, `regex`, or `present` may be configured.',
},
},
{
name: 'Exact',
type: 'string: ""',
description: {
hcl:
'Match if the header with the given name is this value.<br><br> At most only one of `Exact`, `Prefix`, `Suffix`, `Regex`, or `Present` may be configured.',
yaml:
'Match if the header with the given name is this value.<br><br> At most only one of `exact`, `prefix`, `suffix`, `regex`, or `present` may be configured.',
},
},
{
name: 'Prefix',
type: 'string: ""',
description: {
hcl:
'Match if the header with the given name has this prefix.<br><br> At most only one of `Exact`, `Prefix`, `Suffix`, `Regex`, or `Present` may be configured.',
yaml:
'Match if the header with the given name has this prefix.<br><br> At most only one of `exact`, `prefix`, `suffix`, `regex`, or `present` may be configured.',
},
},
{
name: 'Suffix',
type: 'string: ""',
description: {
hcl:
'Match if the header with the given name has this suffix.<br><br> At most only one of `Exact`, `Prefix`, `Suffix`, `Regex`, or `Present` may be configured.',
yaml:
'Match if the header with the given name has this suffix.<br><br> At most only one of `exact`, `prefix`, `suffix`, `regex`, or `present` may be configured.',
},
},
{
name: 'Regex',
type: 'string: ""',
description: {
hcl:
'Match if the header with the given name matches this pattern.<br><br>The syntax is [described below](#regular-expression-syntax).<br><br> At most only one of `Exact`, `Prefix`, `Suffix`, `Regex`, or `Present` may be configured.',
yaml:
'Match if the header with the given name matches this pattern.<br><br>The syntax is [described below](#regular-expression-syntax).<br><br> At most only one of `exact`, `prefix`, `suffix`, `regex`, or `present` may be configured.',
},
},
{
name: 'Invert',
type: 'bool: false',
description: 'Inverts the logic of the match',
},
],
},
{
name: 'QueryParam',
type: 'array<ServiceRouteHTTPMatchQueryParam>)',
description:
'A set of criteria that can match on HTTP query parameters. If more than one is configured all must match for the overall match to apply.',
children: [
{
name: 'Name',
type: 'string: <required>',
description: 'The name of the query parameter to match on.',
},
{
name: 'Present',
type: 'bool: false',
description: {
hcl:
'Match if the query parameter with the given name is present with any value.<br><br>At most only one of `Exact`, `Regex`, or `Present` may be configured.',
yaml:
'Match if the query parameter with the given name is present with any value.<br><br>At most only one of `exact`, `regex`, or `present` may be configured.',
},
},
{
name: 'Exact',
type: 'string: ""',
description: {
hcl:
'Match if the query parameter with the given name is this value.<br><br>At most only one of `Exact`, `Regex`, or `Present` may be configured.',
yaml:
'Match if the query parameter with the given name is this value.<br><br>At most only one of `exact`, `regex`, or `present` may be configured.',
},
},
{
name: 'Regex',
type: 'string: ""',
description: {
hcl:
'Match if the query parameter with the given name matches this pattern.<br><br>The syntax is [described below](#regular-expression-syntax).<br><br>At most only one of `Exact`, `Regex`, or `Present` may be configured.',
yaml:
'Match if the query parameter with the given name matches this pattern.<br><br>The syntax is [described below](#regular-expression-syntax).<br><br>At most only one of `exact`, `regex`, or `present` may be configured.',
},
},
],
},
]}
/>
### `ServiceRouteDestination`
- `Service` `(string: "")` - The service to resolve instead of the default
service. If empty then the default service name is used.
- `ServiceSubset` `(string: "")` - A named subset of the given service to
resolve instead of the one defined as that service's `DefaultSubset`. If empty,
the default subset is used.
- `Namespace` `(string: "")` - The namespace to resolve the service from
instead of the current namespace. If empty the current namespace is assumed.
- `PrefixRewrite` `(string: "")` - Defines how to rewrite the HTTP request path
before proxying it to its final destination.
This requires that either `Match.HTTP.PathPrefix` or
`Match.HTTP.PathExact` be configured on this route.
- `RequestTimeout` `(duration: 0s)` - The total amount of time permitted for
the entire downstream request (and retries) to be processed.
- `NumRetries` `(int: 0)` - The number of times to retry the request when a
retryable result occurs.
- `RetryOnConnectFailure` `(bool: false)` - Allows for connection failure
errors to trigger a retry.
- `RetryOnStatusCodes` `(array<int>)` - A list of HTTP response status codes
that are eligible for retry.
<ConfigEntryReference
topLevel={false}
keys={[
{
name: 'Service',
type: 'string: ""',
description:
'The service to resolve instead of the default service. If empty then the default service name is used.',
},
{
name: 'ServiceSubset',
type: 'string: ""',
description: {
hcl:
"A named subset of the given service to resolve instead of the 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 the one defined as that service's `defaultSubset`. If empty, the default subset is used.",
},
},
{
name: 'Namespace',
type: 'string: ""',
description:
'The Consul namespace to resolve the service from instead of the current namespace. If empty the current namespace is assumed.',
enterprise: true,
},
{
name: 'PrefixRewrite',
type: 'string: ""',
description: {
hcl:
'Defines how to rewrite the HTTP request path before proxying it to its final destination.<br><br> This requires that either `Match.HTTP.PathPrefix` or `Match.HTTP.PathExact` be configured on this route.',
yaml:
'Defines how to rewrite the HTTP request path before proxying it to its final destination.<br><br> This requires that either `match.http.pathPrefix` or `match.http.pathExact` be configured on this route.',
},
},
{
name: 'RequestTimeout',
type: 'duration: 0',
description:
'The total amount of time permitted for the entire downstream request (and retries) to be processed.',
},
{
name: 'NumRetries',
type: 'int: 0',
description:
'The number of times to retry the request when a retryable result occurs.',
},
{
name: 'RetryOnConnectFailure',
type: 'bool: false',
description: 'Allows for connection failure errors to trigger a retry.',
},
{
name: 'RetryOnStatusCodes',
type: 'array<int>',
description:
'A list of HTTP response status codes that are eligible for retry.',
},
]}
/>
## ACLs
@ -279,8 +533,8 @@ name in these fields:
The actual syntax of the regular expression fields described here is entirely
proxy-specific.
When using [Envoy](/docs/connect/proxies/envoy) as a proxy, the syntax for
these fields is version specific:
When using [Envoy](/docs/connect/proxies/envoy) as a proxy (the only supported proxy in Kubernetes),
the syntax for these fields is version specific:
| Envoy Version | Syntax |
| --------------- | ------------------------------------------------------------------- |

View File

@ -11,9 +11,10 @@ description: >-
# Service Splitter
-> **1.6.0+:** This config entry is available in Consul versions 1.6.0 and newer.
-> **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 controls how to split incoming Connect
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).
@ -41,6 +42,11 @@ resolution stage.
## Sample Config Entries
### Two subsets of same service
<Tabs>
<Tab heading="HCL">
Split traffic between two subsets of the same service:
```hcl
@ -58,6 +64,32 @@ Splits = [
]
```
</Tab>
<Tab heading="Kubernetes YAML">
Split traffic between two subsets of the same service:
```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
<Tabs>
<Tab heading="HCL">
Split traffic between two services:
```hcl
@ -75,33 +107,111 @@ Splits = [
]
```
</Tab>
<Tab heading="Kubernetes YAML">
Split traffic between two services:
```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: 10
service: web-rewrite
```
</Tab>
</Tabs>
## Available Fields
- `Kind` - Must be set to `service-splitter`
- `Name` `(string: <required>)` - Set to the name of the service being configured.
- `Namespace` `(string: "default")` <EnterpriseAlert inline /> - Specifies the namespace the config entry will apply to.
- `Meta` `(map<string|string>: nil)` - Specifies arbitrary KV metadata pairs. Added in Consul 1.8.4.
- `Splits` `(array<ServiceSplit>)` - 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.
- `Weight` `(float32: 0)` - 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%
- `Service` `(string: "")` - The service to resolve instead of the default.
- `ServiceSubset` `(string: "")` - 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.
- `Namespace` `(string: "")` - The namespace to resolve the service from
instead of the current namespace. If empty the current namespace is
assumed.
<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 the config entry will apply to.',
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.',
},
],
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 assumed.',
},
],
},
]}
/>
## ACLs

View File

@ -9,9 +9,10 @@ description: >-
# Terminating Gateway
-> **1.8.0+:** This config entry is available in Consul versions 1.8.0 and newer.
-> **v1.8.4+:** On Kubernetes, the `ServiceSplitter` custom resource is supported in Consul versions 1.8.4+.<br />
**v1.8.0+:** On other platforms, this config entry is supported in Consul versions 1.8.0+.
The `terminating-gateway` config entry kind you to configure terminating gateways
The `terminating-gateway` config entry kind (`TerminatingGateway` on Kubernetes) allows you to configure terminating gateways
to proxy traffic from services in the Consul service mesh to services registered with Consul that do not have a
[Connect service sidecar proxy](/docs/connect/proxies). The configuration is associated with the name of a gateway service
and will apply to all instances of the gateway with that name.
@ -78,6 +79,37 @@ Services = [
]
```
</Tab>
<Tab heading="Kubernetes YAML">
Link gateway named "us-west-gateway" with the billing service:
```yaml
apiVersion: consul.hashicorp.com/v1alpha1
kind: TerminatingGateway
metadata:
name: us-west-gateway
spec:
services:
- name: billing
```
</Tab>
<Tab heading="Kubernetes YAML (Consul Enterprise)">
Link gateway named "us-west-gateway" in the default namespace with the billing service in the finance namespace:
```yaml
apiVersion: consul.hashicorp.com/v1alpha1
kind: TerminatingGateway
metadata:
name: us-west-gateway
spec:
services:
- name: billing
namespace: finance
```
</Tab>
<Tab heading="JSON">
@ -154,6 +186,40 @@ Services = [
]
```
</Tab>
<Tab heading="Kubernetes YAML">
Link gateway named "us-west-gateway" with the billing service and specify a CA file for one-way TLS authentication:
```yaml
apiVersion: consul.hashicorp.com/v1alpha1
kind: TerminatingGateway
metadata:
name: us-west-gateway
spec:
services:
- name: billing
caFile: /etc/certs/ca-chain.cert.pem
```
</Tab>
<Tab heading="Kubernetes YAML (Consul Enterprise)">
Link gateway named "us-west-gateway" in the default namespace with the billing service in the finance namespace,
and specify a CA file for one-way TLS authentication:
```yaml
apiVersion: consul.hashicorp.com/v1alpha1
kind: TerminatingGateway
metadata:
name: us-west-gateway
spec:
services:
- name: billing
namespace: finance
caFile: /etc/certs/ca-chain.cert.pem
```
</Tab>
<Tab heading="JSON">
@ -237,6 +303,44 @@ Services = [
]
```
</Tab>
<Tab heading="Kubernetes YAML">
Link gateway named "us-west-gateway" with the payments service and specify a CA file, key file, and cert file for mutual TLS authentication:
```yaml
apiVersion: consul.hashicorp.com/v1alpha1
kind: TerminatingGateway
metadata:
name: us-west-gateway
spec:
services:
- name: billing
caFile: /etc/certs/ca-chain.cert.pem
keyFile: /etc/certs/gateway.key.pem
certFile: /etc/certs/gateway.cert.pem
```
</Tab>
<Tab heading="Kubernetes YAML (Consul Enterprise)">
Link gateway named "us-west-gateway" in the default namespace with the payments service in the finance namespace.
Also specify a CA file, key file, and cert file for mutual TLS authentication:
```yaml
apiVersion: consul.hashicorp.com/v1alpha1
kind: TerminatingGateway
metadata:
name: us-west-gateway
spec:
services:
- name: billing
namespace: finance
caFile: /etc/certs/ca-chain.cert.pem
keyFile: /etc/certs/gateway.key.pem
certFile: /etc/certs/gateway.cert.pem
```
</Tab>
<Tab heading="JSON">
@ -336,6 +440,52 @@ Services = [
]
```
</Tab>
<Tab heading="Kubernetes YAML">
Link gateway named "us-west-gateway" with all services in the datacenter, and configure default certificates for mutual TLS.
Also override the SNI and CA file used for connections to the billing service:
```yaml
apiVersion: consul.hashicorp.com/v1alpha1
kind: TerminatingGateway
metadata:
name: us-west-gateway
spec:
services:
- name: '*'
caFile: /etc/common-certs/ca-chain.cert.pem
keyFile: /etc/common-certs/gateway.key.pem
certFile: /etc/common-certs/gateway.cert.pem
- name: billing
caFile: /etc/billing-ca/ca-chain.cert.pem
sni: billing.service.com
```
</Tab>
<Tab heading="Kubernetes YAML (Consul Enterprise)">
Link gateway named "us-west-gateway" in the default namespace with all services in the finance namespace,
and configure default certificates for mutual TLS. Also override the SNI and CA file used for connections to the billing service:
```yaml
apiVersion: consul.hashicorp.com/v1alpha1
kind: TerminatingGateway
metadata:
name: us-west-gateway
spec:
services:
- name: '*'
namespace: finance
caFile: /etc/common-certs/ca-chain.cert.pem
keyFile: /etc/common-certs/gateway.key.pem
certFile: /etc/common-certs/gateway.cert.pem
- name: billing
namespace: finance
caFile: /etc/billing-ca/ca-chain.cert.pem
sni: billing.service.com
```
</Tab>
<Tab heading="JSON">
@ -398,44 +548,117 @@ and configure default certificates for mutual TLS. Also override the SNI and CA
## Available Fields
- `Kind` - Must be set to `terminating-gateway`
- `Name` `(string: <required>)` - Set to the name of the gateway being configured.
- `Namespace` `(string: "default")` - <EnterpriseAlert inline /> Specifies the namespace
the config entry will apply to. This must be the namespace the gateway is registered in.
If omitted, the namespace will be inherited from [the request](/api/config#ns)
or will default to the `default` namespace.
- `Meta` `(map<string|string>: nil)` - Specifies arbitrary KV metadata pairs. Added in Consul 1.8.4.
- `Services` `(array<LinkedService>: <optional>)` - A list of services to link
with the gateway. The gateway will proxy traffic to these services. These linked services
must be registered with Consul for the gateway to discover their addresses. They must also
be registered in the same Consul datacenter as the terminating gateway.
- `Name` `(string: "")` - The name of the service to link with the gateway.
If the wildcard specifier, `*`, is provided, then ALL services within the namespace
will be linked with the gateway.
- `Namespace` `(string: "")` - <EnterpriseAlert inline /> The namespace of the service.
If omitted, the namespace will be inherited from the config entry.
- `CAFile` `(string: "")` - A file path to a PEM-encoded certificate authority.
The file must be present on the proxy's filesystem.
The certificate authority is used to verify the authenticity of the service linked with the gateway.
It can be provided along with a CertFile and KeyFile for mutual TLS authentication, or on its own
for one-way TLS authentication. If none is provided the gateway **will not** encrypt the traffic to the destination.
- `CertFile` `(string: "")` - A file path to a PEM-encoded certificate.
The file must be present on the proxy's filesystem.
The certificate is provided servers to verify the gateway's authenticity. It must be provided if a KeyFile was specified.
- `KeyFile` `(string: "")` - A file path to a PEM-encoded private key.
The file must be present on the proxy's filesystem.
The key is used with the certificate to verify the gateway's authenticity. It must be provided along if a CertFile was specified.
- `SNI` `(string: "")` - An optional hostname or domain name to specify during the TLS handshake.
<ConfigEntryReference
keys={[
{
name: 'apiVersion',
description: 'Must be set to `consul.hashicorp.com/v1alpha1`',
hcl: false,
},
{
name: 'Kind',
description: {
hcl: 'Must be set to `terminating-gateway`',
yaml: 'Must be set to `TerminatingGateway`',
},
},
{
name: 'Name',
description: 'Set to the name of the gateway being configured.',
type: 'string: <required>',
yaml: false,
},
{
name: 'Namespace',
type: `string: "default"`,
enterprise: true,
description:
'Specifies the namespace the config entry will apply to. This must be the namespace the gateway is registered in.' +
' If omitted, the namespace will be inherited from [the request](/api/config#ns)' +
' or will default to the `default` namespace.',
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 gateway being configured.',
},
],
hcl: false,
},
{
name: 'Services',
type: 'array<LinkedService>: <optional>',
description: `A list of services to link
with the gateway. The gateway will proxy traffic to these services. These linked services
must be registered with Consul for the gateway to discover their addresses. They must also
be registered in the same Consul datacenter as the terminating gateway.`,
children: [
{
name: 'Name',
type: 'string: ""',
description:
'The name of the service to link with the gateway. If the wildcard specifier, `*`, is provided, then ALL services within the namespace will be linked with the gateway.',
},
{
name: 'Namespace',
enterprise: true,
type: 'string: ""',
description:
'The namespace of the service. If omitted, the namespace will be inherited from the config entry.',
},
{
name: 'CAFile',
type: 'string: ""',
description: `A file path to a PEM-encoded certificate authority.
The file must be present on the proxy's filesystem.
The certificate authority is used to verify the authenticity of the service linked with the gateway.
It can be provided along with a CertFile and KeyFile for mutual TLS authentication, or on its own
for one-way TLS authentication. If none is provided the gateway <b>will not</b> encrypt the traffic to the destination.`,
},
{
name: 'CertFile',
type: 'string: ""',
description: {
hcl: `A file path to a PEM-encoded certificate.
The file must be present on the proxy's filesystem.
The certificate is provided servers to verify the gateway's authenticity. It must be provided if a \`KeyFile\` was specified.`,
yaml: `A file path to a PEM-encoded certificate.
The file must be present on the proxy's filesystem.
The certificate is provided servers to verify the gateway's authenticity. It must be provided if a \`keyFile\` was specified.`,
},
},
{
name: 'KeyFile',
type: 'string: ""',
description: {
hcl: `A file path to a PEM-encoded private key.
The file must be present on the proxy's filesystem.
The key is used with the certificate to verify the gateway's authenticity. It must be provided along if a \`CertFile\` was specified.`,
yaml: `A file path to a PEM-encoded private key.
The file must be present on the proxy's filesystem.
The key is used with the certificate to verify the gateway's authenticity. It must be provided along if a \`certFile\` was specified.`,
},
},
{
name: 'SNI',
type: 'string: ""',
description:
'An optional hostname or domain name to specify during the TLS handshake.',
},
],
},
]}
/>
## ACLs

View File

@ -10,7 +10,7 @@ description: >-
# Custom Resource Definitions
-> This feature requires consul-helm >= 0.26.0, consul-k8s >= 0.20.0 and consul >= 1.8.4.
-> This feature requires consul-helm >= 0.28.0, consul-k8s >= 0.22.0 and consul >= 1.8.4.
We support managing Consul [configuration entries](/docs/agent/config-entries)
via Kubernetes Custom Resources. Configuration entries are used to provide
@ -18,29 +18,26 @@ cluster-wide defaults for the service mesh.
We currently support the follow configuration entry kinds:
- [`proxy-defaults`](/docs/agent/config-entries/proxy-defaults)
- [`service-defaults`](/docs/agent/config-entries/service-defaults)
- [`service-splitter`](/docs/agent/config-entries/service-splitter)
- [`service-router`](/docs/agent/config-entries/service-router)
- [`service-resolver`](/docs/agent/config-entries/service-resolver)
- [`service-intentions`](/docs/agent/config-entries/service-intentions) (requires Consul >= 1.9.0)
The following kinds are **not** currently supported:
- [`ingress-gateway`](/docs/agent/config-entries/ingress-gateway)
- [`terminating-gateway`](/docs/agent/config-entries/terminating-gateway)
- [`ProxyDefaults`](/docs/agent/config-entries/proxy-defaults)
- [`ServiceDefaults`](/docs/agent/config-entries/service-defaults)
- [`ServiceSplitter`](/docs/agent/config-entries/service-splitter)
- [`ServiceRouter`](/docs/agent/config-entries/service-router)
- [`ServiceResolver`](/docs/agent/config-entries/service-resolver)
- [`ServiceIntentions`](/docs/agent/config-entries/service-intentions) (requires Consul >= 1.9.0)
- [`IngressGateway`](/docs/agent/config-entries/ingress-gateway)
- [`TerminatingGateway`](/docs/agent/config-entries/terminating-gateway)
## Installation
Ensure you have version `0.26.0` of the helm chart:
Ensure you have at least version `0.28.0` of the helm chart:
```shell-session
$ helm search repo hashicorp/consul
NAME CHART VERSION APP VERSION DESCRIPTION
hashicorp/consul 0.26.0 1.8.5 Official HashiCorp Consul Chart
hashicorp/consul 0.28.0 1.9.1 Official HashiCorp Consul Chart
```
If you don't have `0.26.0`, you will need to update your helm repository cache:
If you don't have `0.28.0`, you will need to update your helm repository cache:
```shell-session
$ helm repo update
@ -55,8 +52,6 @@ and enable the controller that acts on them:
```yaml
global:
name: consul
image: 'consul:1.9.0' # consul >= 1.8.4 must be used
imageK8S: 'hashicorp/consul-k8s:0.20.0'
controller:
enabled: true
@ -68,8 +63,6 @@ connectInject:
Note that:
1. `controller.enabled: true` installs the CRDs and enables the controller.
1. `global.image` must be a Consul version `>= 1.8.4`, e.g. `consul:1.8.4` or `consul:1.9.0`.
1. `global.imageK8S` must be `>= 0.20.0`
1. Configuration entries are used to configure Consul service mesh so it's also
expected that `connectInject` will be enabled.
@ -102,7 +95,7 @@ EOF
servicedefaults.consul.hashicorp.com/foo created
```
See [Specifications](#specifications) for detailed schema documentation.
See [Configuration Entries](/docs/agent/config-entries) for detailed schema documentation.
### Get
@ -180,306 +173,3 @@ to be deleted since that would put Consul into a broken state.
In order to delete the `ServiceDefaults` config, you would need to first delete
the `ServiceSplitter`.
## Specifications
### ProxyDefaults
A [proxy-defaults](/docs/agent/config-entries/proxy-defaults)
entry configures global defaults across all proxies.
```yaml
apiVersion: consul.hashicorp.com/v1alpha1
kind: ProxyDefaults
metadata:
name: global
spec:
config:
envoy_tracing_json: '{"http":{"config":{"collector_cluster":"jaeger_9411","collector_endpoint":"/api/v2/spans"},"name":"envoy.zipkin"}}'
expose:
checks: true
paths:
- listenerPort: 80
localPathPort: 42
path: /test/path
protocol: http
- listenerPort: 8080
localPathPort: 4201
path: /root/test/path
protocol: http2
meshGateway:
mode: local
```
Notes:
1. There can only be one `ProxyDefaults` resource and its name **must** be `global`.
1. Keys under `spec.config` will need to use `snake_case`, not `camelCase`, because
this config is passed directly to Envoy which uses `snake_case`, e.g.
```yaml
spec:
config:
envoy_statsd_url: 'udp://127.0.0.1:8125'
```
1. See [proxy-defaults](/docs/agent/config-entries/proxy-defaults) for full
documentation on this config entry.
### ServiceDefaults
A [service-defaults](/docs/agent/config-entries/service-defaults)
entry configures a specific service.
```yaml
apiVersion: consul.hashicorp.com/v1alpha1
kind: ServiceDefaults
metadata:
name: your-service-name
spec:
protocol: https
meshGateway:
mode: local
expose:
checks: true
paths:
- listenerPort: 80
path: /path
localPathPort: 9000
protocol: http
- listenerPort: 8080
path: /another-path
localPathPort: 9091
protocol: http2
externalSNI: external-sni
```
Notes:
1. The name of the service that this `ServiceDefaults` configures is set by
`metadata.name`.
1. See [service-defaults](/docs/agent/config-entries/service-defaults) for full
documentation on this config entry.
### ServiceIntentions
A [service-intentions](/docs/agent/config-entries/service-intentions)
entry configures traffic authorization for a destination service.
```yaml
apiVersion: consul.hashicorp.com/v1alpha1
kind: ServiceIntentions
metadata:
name: my-intention
spec:
destination:
name: your-service-name
sources:
- name: svc1
namespace: test
action: allow
permissions: []
description: allow access from svc1
- name: '*'
namespace: not-test
action: deny
permissions: []
description: disallow access from namespace not-test
- name: svc-2
namespace: bar
action: ''
permissions:
- action: allow
http:
pathExact: /foo
pathPrefix: /bar
pathRegex: /baz
header:
- name: header
present: true
exact: exact
prefix: prefix
suffix: suffix
regex: regex
invert: true
methods:
- GET
- PUT
description: an L7 config
```
Notes:
1. This resource is only supported in Consul 1.9.0.
1. **Unlike the other configuration entries**, the value of `metadata.name` does not
define which service the intention applies to.
Instead, the name of the service this intention
is configuring is set in `spec.destination.name`.
The `metadata.name` field can be set to any value,
however, we recommend setting it to the name of the destination service the
intention is configuring.
1. Wildcard intentions can be created by setting `spec.destination.name` to `*` and/or
`spec.sources[].name` to `*`. For example to create a `deny` intention that applies
to all services:
```yaml
apiVersion: consul.hashicorp.com/v1alpha1
kind: ServiceIntentions
metadata:
name: deny-all
spec:
destination:
name: *
sources:
- name: *
action: deny
```
1. See [service-intentions](/docs/agent/config-entries/service-intentions) for full
documentation on this config entry.
### ServiceResolver
A [service-resolver](/docs/agent/config-entries/service-resolver)
entry configures which service instances should satisfy Connect upstream discovery requests for a given service name.
```yaml
apiVersion: consul.hashicorp.com/v1alpha1
kind: ServiceResolver
metadata:
name: your-service-name
spec:
defaultSubset: default_subset
subsets:
subset1:
filter: filter1
onlyPassing: true
subset2:
filter: filter2
redirect:
service: redirect
serviceSubset: redirect_subset
namespace: redirect_namespace
datacenter: redirect_datacenter
failover:
failover1:
service: failover1
serviceSubset: failover_subset1
namespaces: failover_namespace1
datacenters:
- failover1_dc1
- failover1_dc2
failover2:
service: failover2
serviceSubset: failover_subset2
namespaces: failover_namespace2
datacenters:
- failover2_dc1
- failover2_dc2
connectTimeout: 1000000000
loadBalancer:
policy: policy
ringHashConfig:
minimumRingSize: 1
maximumRingSize: 2
leastRequestConfig:
choiceCount: 1
hashPolicies:
- field: field
fieldValue: value
cookieConfig:
session: true
ttl: 1
path: path
sourceIP: true
terminal: true
```
Notes:
1. The name of the service that this `ServiceResolver` configures is set by
`metadata.name`.
1. See [service-resolver](/docs/agent/config-entries/service-resolver) for full
documentation on this config entry.
### ServiceRouter
A [service-router](/docs/agent/config-entries/service-router)
entry configures traffic routing and manipulation at networking layer 7 (e.g. HTTP).
```yaml
apiVersion: consul.hashicorp.com/v1alpha1
kind: ServiceRouter
metadata:
name: your-service-name
spec:
routes:
- match:
http:
pathExact: pathExact
pathPrefix: pathPrefix
pathRegex: pathRegex
header:
- name: name
present: true
exact: exact
prefix: prefix
suffix: suffix
regex: regex
invert: true
queryParam:
- name: name
present: true
exact: exact
regex: regex
methods:
- method1
- method2
destination:
service: service
serviceSubset: serviceSubset
namespace: namespace
prefixRewrite: prefixRewrite
requestTimeout: 1000000000
numRetries: 1
retryOnConnectFailure: true
retryOnStatusCodes:
- 500
- 400
```
Notes:
1. The name of the service that this `ServiceRouter` configures is set by
`metadata.name`.
1. See [service-router](/docs/agent/config-entries/service-router) for full
documentation on this config entry.
### ServiceSplitter
A [service-splitter](/docs/agent/config-entries/service-splitter)
entry configures splitting incoming requests across different subsets of a single service.
```yaml
apiVersion: consul.hashicorp.com/v1alpha1
kind: ServiceSplitter
metadata:
name: your-service-name
spec:
splits:
- weight: 25.5
service: foo
serviceSubset: v1
namespace: baz
- weight: 74.5
service: foo
serviceSubset: v2
namespace: baz
```
Notes:
1. The name of the service that this `ServiceSplitter` configures is set by
`metadata.name`.
1. See [service-splitter](/docs/agent/config-entries/service-splitter) for full
documentation on this config entry.

View File

@ -5,8 +5,10 @@ import {
generateStaticPaths,
generateStaticProps,
} from '@hashicorp/react-docs-page/server'
import ConfigEntryReference from 'components/config-entry-reference'
const subpath = 'docs'
const additionalComponents = {ConfigEntryReference}
export default function DocsLayout(props) {
return (
@ -15,6 +17,7 @@ export default function DocsLayout(props) {
subpath={subpath}
order={order}
staticProps={props}
additionalComponents={additionalComponents}
/>
)
}
@ -28,5 +31,6 @@ export async function getStaticProps({ params }) {
subpath,
productName,
params,
additionalComponents
})
}