2020-10-09 19:54:15 +00:00
|
|
|
---
|
|
|
|
layout: docs
|
2020-10-09 23:58:21 +00:00
|
|
|
page_title: Consul Custom Resource Definitions (Beta)
|
|
|
|
sidebar_title: Custom Resource Definitions <sup>(Beta)</sup>
|
2020-10-09 19:54:15 +00:00
|
|
|
description: >-
|
2020-10-09 23:58:21 +00:00
|
|
|
Consul now supports managing configuration entries via Kubernetes Custom Resources.
|
2020-10-09 19:54:15 +00:00
|
|
|
These custom resource can be used to manage the configuration for workloads
|
|
|
|
deployed within the cluster.
|
|
|
|
---
|
|
|
|
|
2020-10-09 23:58:21 +00:00
|
|
|
# Custom Resource Definitions <sup>(beta)</sup>
|
2020-10-09 19:54:15 +00:00
|
|
|
|
2020-10-09 23:58:21 +00:00
|
|
|
## Overview
|
|
|
|
|
|
|
|
-> **This feature is currently in Beta.** It requires consul-helm >= 0.25.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
|
|
|
|
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)
|
|
|
|
|
|
|
|
## Installation
|
|
|
|
|
|
|
|
Ensure you have version `0.25.0` of the helm chart:
|
|
|
|
|
|
|
|
```shell-session
|
|
|
|
$ helm search repo hashicorp/consul
|
|
|
|
NAME CHART VERSION APP VERSION DESCRIPTION
|
|
|
|
hashicorp/consul 0.25.0 1.8.4 Official HashiCorp Consul Chart
|
|
|
|
```
|
|
|
|
|
|
|
|
If you don't have `0.25.0`, you will need to update your helm repository cache:
|
|
|
|
|
|
|
|
```shell-session
|
|
|
|
$ helm repo update
|
|
|
|
Hang tight while we grab the latest from your chart repositories...
|
|
|
|
...Successfully got an update from the "hashicorp" chart repository
|
|
|
|
Update Complete. ⎈Happy Helming!⎈
|
|
|
|
```
|
|
|
|
|
|
|
|
Next, you must configure consul-helm via your `values.yaml` to install the custom resource definitions
|
|
|
|
and enable the controller that acts on them:
|
|
|
|
|
|
|
|
```yaml
|
|
|
|
global:
|
|
|
|
name: consul
|
|
|
|
image: 'consul:1.9.0-beta1' # consul >= 1.8.4 must be used
|
|
|
|
imageK8S: 'hashicorp/consul-k8s:0.19.0'
|
|
|
|
|
|
|
|
controller:
|
|
|
|
enabled: true
|
|
|
|
|
|
|
|
connectInject:
|
|
|
|
enabled: true
|
|
|
|
```
|
|
|
|
|
|
|
|
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-beta1`.
|
|
|
|
1. `global.imageK8S` must be `>= 0.19.0`
|
|
|
|
1. Configuration entries are used to configure Consul service mesh so it's also
|
|
|
|
expected that `connectInject` will be enabled.
|
|
|
|
|
|
|
|
See [Install with Helm Chart](/docs/k8s/installation/install) for further installation
|
|
|
|
instructions.
|
|
|
|
|
|
|
|
## Usage
|
|
|
|
|
|
|
|
Once installed, we can use `kubectl` to create and manage Consul's configuration entries.
|
|
|
|
|
|
|
|
### Create
|
|
|
|
|
|
|
|
We can create configuration entries via `kubectl apply`.
|
|
|
|
|
|
|
|
```shell-session
|
|
|
|
$ cat <<EOF | kubectl apply -f -
|
|
|
|
apiVersion: consul.hashicorp.com/v1alpha1
|
|
|
|
kind: ServiceDefaults
|
|
|
|
metadata:
|
|
|
|
name: foo
|
|
|
|
spec:
|
|
|
|
protocol: "http"
|
|
|
|
EOF
|
|
|
|
|
|
|
|
servicedefaults.consul.hashicorp.com/foo created
|
|
|
|
```
|
|
|
|
|
|
|
|
See [Specifications](#specifications) for detailed schema documentation.
|
|
|
|
|
|
|
|
### Get
|
|
|
|
|
|
|
|
We can use `kubectl get [kind] [name]` to get the status of the configuration entry:
|
|
|
|
|
|
|
|
```shell-session
|
|
|
|
$ kubectl get servicedefaults foo
|
|
|
|
NAME SYNCED
|
|
|
|
foo True
|
|
|
|
```
|
|
|
|
|
|
|
|
The `SYNCED` status shows whether the configuration entry was successfully created
|
|
|
|
in Consul.
|
|
|
|
|
|
|
|
### Describe
|
|
|
|
|
|
|
|
We can use `kubectl describe [kind] [name]` to investigate the status of the
|
|
|
|
configuration entry. If `SYNCED` is false, the status will contain the reason
|
|
|
|
why.
|
|
|
|
|
|
|
|
```shell-session
|
|
|
|
$ kubectl describe servicedefaults foo
|
|
|
|
Status:
|
|
|
|
Conditions:
|
|
|
|
Last Transition Time: 2020-10-09T21:15:50Z
|
|
|
|
Status: True
|
|
|
|
Type: Synced
|
|
|
|
```
|
|
|
|
|
|
|
|
### Edit
|
|
|
|
|
|
|
|
We can use `kubectl edit [kind] [name]` to edit the configuration entry:
|
|
|
|
|
|
|
|
```shell
|
|
|
|
$ kubectl edit servicedefaults foo
|
|
|
|
# change protocol: http => protocol: tcp
|
|
|
|
servicedefaults.consul.hashicorp.com/foo edited
|
|
|
|
```
|
|
|
|
|
|
|
|
We can then use `kubectl get` to ensure the change was synced to Consul:
|
|
|
|
|
|
|
|
```shell-session
|
|
|
|
$ kubectl get servicedefaults foo
|
|
|
|
NAME SYNCED
|
|
|
|
foo True
|
|
|
|
```
|
|
|
|
|
|
|
|
### Delete
|
|
|
|
|
|
|
|
We can use `kubectl delete [kind] [name]` to delete the configuration entry:
|
|
|
|
|
|
|
|
```shell-session
|
|
|
|
$ kubectl delete servicedefaults foo
|
|
|
|
servicedefaults.consul.hashicorp.com "foo" deleted
|
|
|
|
```
|
|
|
|
|
|
|
|
We can then use `kubectl get` to ensure the configuration entry was deleted:
|
|
|
|
|
|
|
|
```shell-session
|
|
|
|
$ kubectl get servicedefaults foo
|
|
|
|
Error from server (NotFound): servicedefaults.consul.hashicorp.com "foo" not found
|
|
|
|
```
|
|
|
|
|
|
|
|
#### Delete Hanging
|
|
|
|
|
|
|
|
If running `kubectl delete` hangs without exiting, there may be
|
|
|
|
a requirement inside Consul that prevents that configuration entry from being
|
|
|
|
deleted. For example, if you set the protocol of your service to `http` via `ServiceDefaults` and then
|
|
|
|
create a `ServiceSplitter`, you won't be able to delete the `ServiceDefaults`.
|
|
|
|
|
|
|
|
This is because by deleting the `ServiceDefaults` config, you are setting the
|
|
|
|
protocol back to the default which is `tcp`. Since `ServiceSplitter` requires
|
|
|
|
that the service has an `http` protocol, Consul will not allow the `ServiceDefaults`
|
|
|
|
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
|
|
|
|
|
|
|
|
[proxy-defaults](/docs/agent/config-entries/proxy-defaults)
|
|
|
|
configures global defaults across all proxies.
|
|
|
|
|
|
|
|
```yaml
|
|
|
|
apiVersion: consul.hashicorp.com/v1alpha1
|
|
|
|
kind: ProxyDefaults
|
|
|
|
metadata:
|
|
|
|
name: global
|
|
|
|
spec:
|
|
|
|
config:
|
|
|
|
envoy_tracing_json: '{"http":{"name":"envoy.zipkin","config":{"collector_cluster":"zipkin","collector_endpoint":"/api/v1/spans","shared_span_context":false}}}'
|
|
|
|
expose:
|
|
|
|
checks: true
|
|
|
|
paths:
|
|
|
|
- listenerPort: 80
|
|
|
|
localPathPort: 42
|
|
|
|
path: /test/path
|
|
|
|
protocol: tcp
|
|
|
|
- listenerPort: 8080
|
|
|
|
localPathPort: 4201
|
|
|
|
path: /root/test/path
|
|
|
|
protocol: https
|
|
|
|
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
|
|
|
|
|
|
|
|
[service-defaults](/docs/agent/config-entries/service-defaults)
|
|
|
|
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: tcp
|
|
|
|
- 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 <sup>(Beta)</sup>
|
|
|
|
|
|
|
|
[service-intentions](/docs/agent/config-entries/service-intentions)
|
|
|
|
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. It can be set to any value
|
|
|
|
however we recommend setting it to the name of the destination service the
|
|
|
|
intention is configuring.
|
|
|
|
|
|
|
|
Instead, the name of the service this intention
|
|
|
|
is configuring is set in `spec.destination.name`.
|
|
|
|
|
|
|
|
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
|
|
|
|
|
|
|
|
[service-resolver](/docs/agent/config-entries/service-resolver)
|
|
|
|
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
|
|
|
|
|
|
|
|
[service-router](/docs/agent/config-entries/service-router)
|
|
|
|
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
|
|
|
|
|
|
|
|
[service-splitter](/docs/agent/config-entries/service-splitter)
|
|
|
|
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: 50.1
|
|
|
|
service: foo
|
|
|
|
serviceSubset: bar
|
|
|
|
namespace: baz
|
|
|
|
- weight: 49.9
|
|
|
|
service: foo
|
|
|
|
serviceSubset: bar
|
|
|
|
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.
|