d447b54ad3
Remove outdated usage of "Consul Connect" instead of Consul service mesh. The connect subsystem in Consul provides Consul's service mesh capabilities. However, the term "Consul Connect" should not be used as an alternative to the name "Consul service mesh".
579 lines
16 KiB
Plaintext
579 lines
16 KiB
Plaintext
---
|
|
layout: api
|
|
page_title: Discovery Chain - HTTP API
|
|
description: The /discovery-chain endpoints are for interacting with the discovery chain.
|
|
---
|
|
|
|
# Discovery Chain HTTP Endpoint
|
|
|
|
-> **1.6.0+:** The discovery chain API is available in Consul versions 1.6.0 and newer.
|
|
|
|
~> This is a low-level API primarily targeted at developers building external
|
|
[service mesh proxy integrations](/consul/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](/consul/docs/connect/l7-traffic/discovery-chain) for a service.
|
|
|
|
This will fetch all related [configuration
|
|
entries](/consul/docs/agent/config-entries) and render them into a form suitable
|
|
for use by a [service mesh proxy](/consul/docs/connect/proxies) implementation. This
|
|
is a key component of [L7 Traffic
|
|
Management](/consul/docs/connect/l7-traffic).
|
|
|
|
## 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_name` | `application/json` |
|
|
| `POST`<sup>1</sup> | `/discovery-chain/:service_name` | `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](/consul/api-docs/features/blocking),
|
|
[consistency modes](/consul/api-docs/features/consistency),
|
|
[agent caching](/consul/api-docs/features/caching), and
|
|
[required ACLs](/consul/api-docs/api-structure#authentication).
|
|
|
|
| Blocking Queries | Consistency Modes | Agent Caching | ACL Required |
|
|
| ---------------- | ----------------- | -------------------- | -------------- |
|
|
| `YES` | `all` | `background refresh` | `service:read` |
|
|
|
|
### Path Parameters
|
|
|
|
- `service_name` `(string: <required>)` - Specifies the service to query when
|
|
compiling the discovery chain.
|
|
|
|
### Query Parameters
|
|
|
|
- `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 value comes from an [upstream
|
|
configuration](/consul/docs/connect/registration/service-registration#upstream-configuration-reference)
|
|
[`datacenter`](/consul/docs/connect/registration/service-registration#datacenter)
|
|
parameter.
|
|
|
|
- `ns` `(string: "")` <EnterpriseAlert inline /> - Specifies the source namespace you use as the basis of compilation.
|
|
You can also [specify the namespace through other methods](#methods-to-specify-namespace).
|
|
|
|
### JSON Request Body Schema
|
|
|
|
- `OverrideConnectTimeout` `(duration: 0s)` - Overrides the final [connect
|
|
timeout](/consul/docs/connect/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](/consul/docs/connect/registration/service-registration#upstream-configuration-reference)
|
|
opaque
|
|
[`config`](/consul/docs/connect/registration/service-registration#config-1)
|
|
parameter.
|
|
|
|
- `OverrideProtocol` `(string: "")` - Overrides the final
|
|
[protocol](/consul/docs/connect/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](/consul/docs/connect/registration/service-registration#upstream-configuration-reference)
|
|
opaque
|
|
[`config`](/consul/docs/connect/registration/service-registration#config-1)
|
|
parameter.
|
|
|
|
- `OverrideMeshGateway` `(MeshGatewayConfig: <optional>)` - Overrides the final
|
|
[mesh gateway configuration](/consul/docs/connect/gateways/mesh-gateway#connect-proxy-configuration)
|
|
for this any service resolved in the compiled chain.
|
|
|
|
This value comes from either the [proxy
|
|
configuration](/consul/docs/connect/registration/service-registration#complete-configuration-example)
|
|
[`mesh_gateway`](/consul/docs/connect/registration/service-registration#mesh_gateway)
|
|
parameter or an [upstream
|
|
configuration](/consul/docs/connect/registration/service-registration#upstream-configuration-reference)
|
|
[`mesh_gateway`](/consul/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](/consul/docs/connect/l7-traffic/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 --request POST \
|
|
--data '
|
|
{
|
|
"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"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
## Methods to Specify Namespace <EnterpriseAlert inline />
|
|
|
|
The discovery chain endpoint
|
|
supports several methods for specifying the namespace to use as the basis of discovery chain compilation
|
|
with the following order of precedence:
|
|
1. `ns` query parameter
|
|
1. `X-Consul-Namespace` request header
|
|
1. Namespace is inherited from the namespace of the request's ACL token (if any)
|
|
1. The `default` namespace
|