mirror of https://github.com/hashicorp/consul
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
565 lines
15 KiB
565 lines
15 KiB
--- |
|
layout: api |
|
page_title: Discovery Chain - HTTP API |
|
sidebar_title: Discovery Chain |
|
description: The /discovery-chain endpoints are for interacting with the discovery chain. |
|
--- |
|
|
|
-> **1.6.0+:** The discovery chain API is available in Consul versions 1.6.0 and newer. |
|
|
|
# Discovery Chain HTTP Endpoint |
|
|
|
~> This is a low-level API primarily targeted at developers building external |
|
[Connect proxy integrations](/docs/connect/proxies/integrate). Future |
|
high-level proxy integration APIs may obviate the need for this API over time. |
|
|
|
The `/discovery-chain` endpoint returns the compiled [discovery |
|
chain](/docs/internals/discovery-chain) for a service. |
|
|
|
This will fetch all related [configuration |
|
entries](/docs/agent/config-entries) and render them into a form suitable |
|
for use by a [connect proxy](/docs/connect/proxies) implementation. This |
|
is a key component of [L7 Traffic |
|
Management](/docs/connect/l7-traffic-management). |
|
|
|
## Read Compiled Discovery Chain |
|
|
|
If overrides are needed they are passed as the JSON-encoded request body and |
|
the `POST` method must be used, otherwise `GET` is sufficient. |
|
|
|
| Method | Path | Produces | |
|
| ------------------ | --------------------------- | ------------------ | |
|
| `GET` | `/discovery-chain/:service` | `application/json` | |
|
| `POST`<sup>1</sup> | `/discovery-chain/:service` | `application/json` | |
|
|
|
<p> |
|
<sup>1</sup> Both GET and POST are for <strong>read</strong> operations. GET |
|
requests do not permit request bodies so a POST is required if override |
|
parameters are needed. |
|
</p> |
|
|
|
The table below shows this endpoint's support for |
|
[blocking queries](/api/features/blocking), |
|
[consistency modes](/api/features/consistency), |
|
[agent caching](/api/features/caching), and |
|
[required ACLs](/api#authentication). |
|
|
|
| Blocking Queries | Consistency Modes | Agent Caching | ACL Required | |
|
| ---------------- | ----------------- | -------------------- | -------------- | |
|
| `YES` | `all` | `background refresh` | `service:read` | |
|
|
|
### URL Parameters |
|
|
|
- `service` `(string: <required>)` - Specifies the service to query when |
|
compiling the discovery chain. This is provided as part of the URL. |
|
|
|
- `compile-dc` `(string: "")` - Specifies the datacenter to use as the basis of |
|
compilation. This will default to the datacenter of the agent being queried. |
|
This is specified as part of the URL as a query parameter. |
|
|
|
This value comes from an [upstream |
|
configuration](/docs/connect/registration/service-registration#upstream-configuration-reference) |
|
[`datacenter`](/docs/connect/registration/service-registration#datacenter) |
|
parameter. |
|
|
|
### POST Body Parameters |
|
|
|
- `OverrideConnectTimeout` `(duration: 0s)` - Overrides the final [connect |
|
timeout](/docs/agent/config-entries/service-resolver#connecttimeout) for |
|
any service resolved in the compiled chain. |
|
|
|
This value comes from the `connect_timeout_ms` key in an [upstream |
|
configuration](/docs/connect/registration/service-registration#upstream-configuration-reference) |
|
opaque |
|
[`config`](/docs/connect/registration/service-registration#config-1) |
|
parameter. |
|
|
|
- `OverrideProtocol` `(string: "")` - Overrides the final |
|
[protocol](/docs/agent/config-entries/service-defaults#protocol) used in |
|
the compiled discovery chain. |
|
|
|
If the chain ordinarily would be TCP and an L7 protocol is passed here the |
|
chain will still not include Routers or Splitters. If the chain ordinarily |
|
would be L7 and TCP is passed here the chain will not include Routers or |
|
Splitters. |
|
|
|
This value comes from the `protocol` key in an [upstream |
|
configuration](/docs/connect/registration/service-registration#upstream-configuration-reference) |
|
opaque |
|
[`config`](/docs/connect/registration/service-registration#config-1) |
|
parameter. |
|
|
|
- `OverrideMeshGateway` `(MeshGatewayConfig: <optional>)` - Overrides the final |
|
[mesh gateway configuration](/docs/connect/mesh-gateway#connect-proxy-configuration) |
|
for this any service resolved in the compiled chain. |
|
|
|
This value comes from either the [proxy |
|
configuration](/docs/connect/registration/service-registration#complete-configuration-example) |
|
[`mesh_gateway`](/docs/connect/registration/service-registration#mesh_gateway) |
|
parameter or an [upstream |
|
configuration](/docs/connect/registration/service-registration#upstream-configuration-reference) |
|
[`mesh_gateway`](/docs/connect/registration/service-registration#mesh_gateway-1) |
|
parameter. If both are present the value defined on the upstream is used. |
|
|
|
- `Mode` `(string: "")` - One of `none`, `local`, or `remote`. |
|
|
|
### Sample Compilations |
|
|
|
Full documentation for the output fields is found on the [discovery chain |
|
internals](/docs/internals/discovery-chain#compileddiscoverychain) |
|
page. |
|
|
|
#### Multi-Datacenter Failover |
|
|
|
Config entries defined: |
|
|
|
```hcl |
|
kind = "service-resolver" |
|
name = "web" |
|
connect_timeout = "15s" |
|
failover = { |
|
"*" = { |
|
datacenters = ["dc3", "dc4"] |
|
} |
|
} |
|
``` |
|
|
|
Request: |
|
|
|
```shell-session |
|
$ curl http://127.0.0.1:8500/v1/discovery-chain/web |
|
``` |
|
|
|
Response: |
|
|
|
```json |
|
{ |
|
"Chain": { |
|
"ServiceName": "web", |
|
"Namespace": "default", |
|
"Datacenter": "dc1", |
|
"Protocol": "tcp", |
|
"StartNode": "resolver:web.default.dc1", |
|
"Nodes": { |
|
"resolver:web.default.dc1": { |
|
"Type": "resolver", |
|
"Name": "web.default.dc1", |
|
"Resolver": { |
|
"ConnectTimeout": "15s", |
|
"Target": "web.default.dc1", |
|
"Failover": { |
|
"Targets": ["web.default.dc3", "web.default.dc4"] |
|
} |
|
} |
|
} |
|
}, |
|
"Targets": { |
|
"web.default.dc1": { |
|
"ID": "web.default.dc1", |
|
"Service": "web", |
|
"Namespace": "default", |
|
"Datacenter": "dc1", |
|
"MeshGateway": {}, |
|
"Subset": {}, |
|
"SNI": "web.default.dc1.internal.47e25151-6212-ba25-8b7e-81adbbbab461.consul", |
|
"Name": "web.default.dc1.internal.47e25151-6212-ba25-8b7e-81adbbbab461.consul" |
|
}, |
|
"web.default.dc3": { |
|
"ID": "web.default.dc3", |
|
"Service": "web", |
|
"Namespace": "default", |
|
"Datacenter": "dc3", |
|
"MeshGateway": {}, |
|
"Subset": {}, |
|
"SNI": "web.default.dc3.internal.47e25151-6212-ba25-8b7e-81adbbbab461.consul", |
|
"Name": "web.default.dc3.internal.47e25151-6212-ba25-8b7e-81adbbbab461.consul" |
|
}, |
|
"web.default.dc4": { |
|
"ID": "web.default.dc4", |
|
"Service": "web", |
|
"Namespace": "default", |
|
"Datacenter": "dc4", |
|
"MeshGateway": {}, |
|
"Subset": {}, |
|
"SNI": "web.default.dc4.internal.47e25151-6212-ba25-8b7e-81adbbbab461.consul", |
|
"Name": "web.default.dc4.internal.47e25151-6212-ba25-8b7e-81adbbbab461.consul" |
|
} |
|
} |
|
} |
|
} |
|
``` |
|
|
|
#### Datacenter Redirect with Overrides |
|
|
|
Config entries defined: |
|
|
|
```hcl |
|
kind = "service-resolver" |
|
name = "web" |
|
redirect { |
|
datacenter = "dc2" |
|
} |
|
``` |
|
|
|
Request: |
|
|
|
```shell-session |
|
$ curl -X POST \ |
|
-d' |
|
{ |
|
"OverrideConnectTimeout": "7s", |
|
"OverrideProtocol": "grpc", |
|
"OverrideMeshGateway": { |
|
"Mode": "remote" |
|
} |
|
} |
|
' http://127.0.0.1:8500/v1/discovery-chain/web |
|
``` |
|
|
|
Response: |
|
|
|
```json |
|
{ |
|
"Chain": { |
|
"ServiceName": "web", |
|
"Namespace": "default", |
|
"Datacenter": "dc1", |
|
"CustomizationHash": "b94f529a", |
|
"Protocol": "grpc", |
|
"StartNode": "resolver:web.default.dc2", |
|
"Nodes": { |
|
"resolver:web.default.dc2": { |
|
"Type": "resolver", |
|
"Name": "web.default.dc2", |
|
"Resolver": { |
|
"ConnectTimeout": "7s", |
|
"Target": "web.default.dc2" |
|
} |
|
} |
|
}, |
|
"Targets": { |
|
"web.default.dc2": { |
|
"ID": "web.default.dc2", |
|
"Service": "web", |
|
"Namespace": "default", |
|
"Datacenter": "dc2", |
|
"MeshGateway": { |
|
"Mode": "remote" |
|
}, |
|
"Subset": {}, |
|
"SNI": "web.default.dc2.internal.59c17fd4-8dfa-f54a-ae71-855b26faf637.consul", |
|
"Name": "web.default.dc2.internal.59c17fd4-8dfa-f54a-ae71-855b26faf637.consul" |
|
} |
|
} |
|
} |
|
} |
|
``` |
|
|
|
#### Version Split For Alternate Datacenter |
|
|
|
Config entries defined: |
|
|
|
```hcl |
|
kind = "service-resolver" |
|
name = "web" |
|
default_subset = "v1" |
|
subsets = { |
|
"v1" = { |
|
filter = "Service.Meta.version == v1" |
|
} |
|
"v2" = { |
|
filter = "Service.Meta.version == v2" |
|
} |
|
} |
|
# --------------------------- |
|
kind = "service-defaults" |
|
name = "web" |
|
protocol = "http" |
|
# --------------------------- |
|
kind = "service-splitter" |
|
name = "web" |
|
splits = [ |
|
{ |
|
weight = 90 |
|
service_subset = "v1" |
|
}, |
|
{ |
|
weight = 10 |
|
service_subset = "v2" |
|
}, |
|
] |
|
``` |
|
|
|
Request: |
|
|
|
```shell-session |
|
$ curl http://127.0.0.1:8500/v1/discovery-chain/web?compile-dc=dc2 |
|
``` |
|
|
|
Response: |
|
|
|
```json |
|
{ |
|
"Chain": { |
|
"ServiceName": "web", |
|
"Namespace": "default", |
|
"Datacenter": "dc2", |
|
"Protocol": "http", |
|
"StartNode": "splitter:web", |
|
"Nodes": { |
|
"resolver:v1.web.default.dc2": { |
|
"Type": "resolver", |
|
"Name": "v1.web.default.dc2", |
|
"Resolver": { |
|
"ConnectTimeout": "5s", |
|
"Target": "v1.web.default.dc2" |
|
} |
|
}, |
|
"resolver:v2.web.default.dc2": { |
|
"Type": "resolver", |
|
"Name": "v2.web.default.dc2", |
|
"Resolver": { |
|
"ConnectTimeout": "5s", |
|
"Target": "v2.web.default.dc2" |
|
} |
|
}, |
|
"splitter:web": { |
|
"Type": "splitter", |
|
"Name": "web", |
|
"Splits": [ |
|
{ |
|
"Weight": 90, |
|
"NextNode": "resolver:v1.web.default.dc2" |
|
}, |
|
{ |
|
"Weight": 10, |
|
"NextNode": "resolver:v2.web.default.dc2" |
|
} |
|
] |
|
} |
|
}, |
|
"Targets": { |
|
"v1.web.default.dc2": { |
|
"ID": "v1.web.default.dc2", |
|
"Service": "web", |
|
"ServiceSubset": "v1", |
|
"Namespace": "default", |
|
"Datacenter": "dc2", |
|
"MeshGateway": {}, |
|
"Subset": { |
|
"Filter": "Service.Meta.version == v1" |
|
}, |
|
"SNI": "v1.web.default.dc2.internal.6c9594ec-d798-28b9-d084-aa03e81cf078.consul", |
|
"Name": "v1.web.default.dc2.internal.6c9594ec-d798-28b9-d084-aa03e81cf078.consul" |
|
}, |
|
"v2.web.default.dc2": { |
|
"ID": "v2.web.default.dc2", |
|
"Service": "web", |
|
"ServiceSubset": "v2", |
|
"Namespace": "default", |
|
"Datacenter": "dc2", |
|
"MeshGateway": {}, |
|
"Subset": { |
|
"Filter": "Service.Meta.version == v2" |
|
}, |
|
"SNI": "v2.web.default.dc2.internal.6c9594ec-d798-28b9-d084-aa03e81cf078.consul", |
|
"Name": "v2.web.default.dc2.internal.6c9594ec-d798-28b9-d084-aa03e81cf078.consul" |
|
} |
|
} |
|
} |
|
} |
|
``` |
|
|
|
#### HTTP Path Routing |
|
|
|
Config entries defined: |
|
|
|
```hcl |
|
kind = "service-resolver" |
|
name = "web" |
|
subsets = { |
|
"canary" = { |
|
filter = "Service.Meta.flavor == canary" |
|
} |
|
} |
|
# --------------------------- |
|
kind = "proxy-defaults" |
|
name = "web" |
|
config { |
|
protocol = "http" |
|
} |
|
# --------------------------- |
|
kind = "service-router" |
|
name = "web" |
|
routes = [ |
|
{ |
|
match { |
|
http { |
|
path_prefix = "/admin" |
|
} |
|
} |
|
destination { |
|
service = "admin" |
|
prefix_rewrite = "/" |
|
request_timeout = "15s" |
|
} |
|
}, |
|
{ |
|
match { |
|
http { |
|
header = [ |
|
{ |
|
name = "x-debug" |
|
exact = "1" |
|
}, |
|
] |
|
} |
|
} |
|
destination { |
|
service = "web" |
|
service_subset = "canary" |
|
num_retries = 5 |
|
retry_on_connect_failure = true |
|
retry_on_status_codes = [401, 409] |
|
} |
|
}, |
|
] |
|
``` |
|
|
|
Request: |
|
|
|
```shell-session |
|
$ curl http://127.0.0.1:8500/v1/discovery-chain/web |
|
``` |
|
|
|
Response: |
|
|
|
```json |
|
{ |
|
"Chain": { |
|
"ServiceName": "web", |
|
"Namespace": "default", |
|
"Datacenter": "dc1", |
|
"Protocol": "http", |
|
"StartNode": "router:web", |
|
"Nodes": { |
|
"resolver:admin.default.dc1": { |
|
"Type": "resolver", |
|
"Name": "admin.default.dc1", |
|
"Resolver": { |
|
"ConnectTimeout": "5s", |
|
"Default": true, |
|
"Target": "admin.default.dc1" |
|
} |
|
}, |
|
"resolver:canary.web.default.dc1": { |
|
"Type": "resolver", |
|
"Name": "canary.web.default.dc1", |
|
"Resolver": { |
|
"ConnectTimeout": "5s", |
|
"Target": "canary.web.default.dc1" |
|
} |
|
}, |
|
"resolver:web.default.dc1": { |
|
"Type": "resolver", |
|
"Name": "web.default.dc1", |
|
"Resolver": { |
|
"ConnectTimeout": "5s", |
|
"Target": "web.default.dc1" |
|
} |
|
}, |
|
"router:web": { |
|
"Type": "router", |
|
"Name": "web", |
|
"Routes": [ |
|
{ |
|
"Definition": { |
|
"Match": { |
|
"HTTP": { |
|
"PathPrefix": "/admin" |
|
} |
|
}, |
|
"Destination": { |
|
"RequestTimeout": "15s", |
|
"Service": "admin", |
|
"PrefixRewrite": "/" |
|
} |
|
}, |
|
"NextNode": "resolver:admin.default.dc1" |
|
}, |
|
{ |
|
"Definition": { |
|
"Match": { |
|
"HTTP": { |
|
"Header": [ |
|
{ |
|
"Name": "x-debug", |
|
"Exact": "1" |
|
} |
|
] |
|
} |
|
}, |
|
"Destination": { |
|
"Service": "web", |
|
"ServiceSubset": "canary", |
|
"NumRetries": 5, |
|
"RetryOnConnectFailure": true, |
|
"RetryOnStatusCodes": [401, 409] |
|
} |
|
}, |
|
"NextNode": "resolver:canary.web.default.dc1" |
|
}, |
|
{ |
|
"Definition": { |
|
"Match": { |
|
"HTTP": { |
|
"PathPrefix": "/" |
|
} |
|
}, |
|
"Destination": { |
|
"Service": "web" |
|
} |
|
}, |
|
"NextNode": "resolver:web.default.dc1" |
|
} |
|
] |
|
} |
|
}, |
|
"Targets": { |
|
"admin.default.dc1": { |
|
"ID": "admin.default.dc1", |
|
"Service": "admin", |
|
"Namespace": "default", |
|
"Datacenter": "dc1", |
|
"MeshGateway": {}, |
|
"Subset": {}, |
|
"SNI": "admin.default.dc1.internal.fce8a058-0981-2c04-d23c-b7375af64ce8.consul", |
|
"Name": "admin.default.dc1.internal.fce8a058-0981-2c04-d23c-b7375af64ce8.consul" |
|
}, |
|
"canary.web.default.dc1": { |
|
"ID": "canary.web.default.dc1", |
|
"Service": "web", |
|
"ServiceSubset": "canary", |
|
"Namespace": "default", |
|
"Datacenter": "dc1", |
|
"MeshGateway": {}, |
|
"Subset": { |
|
"Filter": "Service.Meta.flavor == canary" |
|
}, |
|
"SNI": "canary.web.default.dc1.internal.fce8a058-0981-2c04-d23c-b7375af64ce8.consul", |
|
"Name": "canary.web.default.dc1.internal.fce8a058-0981-2c04-d23c-b7375af64ce8.consul" |
|
}, |
|
"web.default.dc1": { |
|
"ID": "web.default.dc1", |
|
"Service": "web", |
|
"Namespace": "default", |
|
"Datacenter": "dc1", |
|
"MeshGateway": {}, |
|
"Subset": {}, |
|
"SNI": "web.default.dc1.internal.fce8a058-0981-2c04-d23c-b7375af64ce8.consul", |
|
"Name": "web.default.dc1.internal.fce8a058-0981-2c04-d23c-b7375af64ce8.consul" |
|
} |
|
} |
|
} |
|
} |
|
```
|
|
|