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.
consul/website/content/api-docs/discovery-chain.mdx

579 lines
16 KiB

5 years ago
---
layout: api
page_title: Discovery Chain - HTTP API
description: The /discovery-chain endpoints are for interacting with the discovery chain.
5 years ago
---
# Discovery Chain HTTP Endpoint
-> **1.6.0+:** The discovery chain API is available in Consul versions 1.6.0 and newer.
5 years ago
~> This is a low-level API primarily targeted at developers building external
[service mesh proxy integrations](/consul/docs/connect/proxies/integrate). Future
5 years ago
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.
5 years ago
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
5 years ago
is a key component of [L7 Traffic
Management](/consul/docs/connect/l7-traffic).
5 years ago
## 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` |
5 years ago
<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>
5 years ago
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).
5 years ago
| Blocking Queries | Consistency Modes | Agent Caching | ACL Required |
| ---------------- | ----------------- | -------------------- | -------------- |
| `YES` | `all` | `background refresh` | `service:read` |
### Path Parameters
5 years ago
- `service_name` `(string: <required>)` - Specifies the service to query when
compiling the discovery chain.
### Query Parameters
5 years ago
- `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)
5 years ago
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
5 years ago
- `OverrideConnectTimeout` `(duration: 0s)` - Overrides the final [connect
timeout](/consul/docs/connect/config-entries/service-resolver#connecttimeout) for
5 years ago
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)
5 years ago
opaque
[`config`](/consul/docs/connect/registration/service-registration#config-1)
5 years ago
parameter.
- `OverrideProtocol` `(string: "")` - Overrides the final
[protocol](/consul/docs/connect/config-entries/service-defaults#protocol) used in
5 years ago
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)
5 years ago
opaque
[`config`](/consul/docs/connect/registration/service-registration#config-1)
5 years ago
parameter.
- `OverrideMeshGateway` `(MeshGatewayConfig: <optional>)` - Overrides the final
[mesh gateway configuration](/consul/docs/connect/gateways/mesh-gateway#connect-proxy-configuration)
5 years ago
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)
5 years ago
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)
5 years ago
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)
5 years ago
page.
#### Multi-Datacenter Failover
Config entries defined:
```hcl
kind = "service-resolver"
name = "web"
connect_timeout = "15s"
failover = {
"*" = {
datacenters = ["dc3", "dc4"]
}
}
```
Request:
```shell-session
5 years ago
$ 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 '
5 years ago
{
"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
5 years ago
$ 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
5 years ago
$ 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