1--- 2layout: "docs" 3page_title: "Discovery Chain" 4sidebar_current: "docs-internals-discovery-chain" 5description: |- 6 The service discovery process can be modeled as a "discovery chain" which passes through three distinct stages: routing, splitting, and resolution. Each of these stages is controlled by a set of configuration entries. 7--- 8 9-> **1.6.0+:** This feature is available in Consul versions 1.6.0 and newer. 10 11# Discovery Chain 12 13~> This topic is part of a [low-level API](/api/discovery-chain.html) 14primarily targeted at developers building external [Connect proxy 15integrations](/docs/connect/proxies/integrate.html). 16 17The service discovery process can be modeled as a "discovery chain" which 18passes through three distinct stages: routing, splitting, and resolution. Each 19of these stages is controlled by a set of [configuration 20entries](/docs/agent/config_entries.html). By configuring different phases of 21the discovery chain a user can control how proxy upstreams are ultimately 22resolved to specific instances for load balancing. 23 24-> **Note:** The discovery chain is currently only used to discover 25[Connect](/docs/connect/index.html) proxy upstreams. 26 27## Configuration 28 29The configuration entries used in the discovery chain are designed to be simple 30to read and modify for narrowly tailored changes, but at discovery-time the 31various configuration entries interact in more complex ways. For example: 32 33* If a [`service-resolver`](/docs/agent/config-entries/service-resolver.html) 34 is created with a [service 35 redirect](/docs/agent/config-entries/service-resolver.html#service) defined, 36 then all references made to the original service in any other configuration 37 entry is replaced with the redirect destination. 38 39* If a [`service-resolver`](/docs/agent/config-entries/service-resolver.html) 40 is created with a [default 41 subset](/docs/agent/config-entries/service-resolver.html#defaultsubset) 42 defined then all references made to the original service in any other 43 configuration entry that did not specify a subset will be replaced with the 44 default. 45 46* If a [`service-splitter`](/docs/agent/config-entries/service-splitter.html) 47 is created with a [service 48 split](/docs/agent/config-entries/service-splitter.html#splits), and the target service has its 49 own `service-splitter` then the overall effect is flattened and only a single 50 aggregate traffic split is ultimately configured in the proxy. 51 52* [`service-resolver`](/docs/agent/config-entries/service-resolver.html) 53 redirect loops must be rejected as invalid. 54 55* [`service-router`](/docs/agent/config-entries/service-router.html) and 56 [`service-splitter`](/docs/agent/config-entries/service-splitter.html) 57 configuration entries require an L7 compatible protocol be set for the 58 service via either a 59 [`service-defaults`](/docs/agent/config-entries/service-defaults.html) or 60 [`proxy-defaults`](/docs/agent/config-entries/proxy-defaults.html) config 61 entry. Violations must be rejected as invalid. 62 63* If an [upstream 64 configuration](/docs/connect/registration/service-registration.html#upstream-configuration-reference) 65 [`datacenter`](/docs/connect/registration/service-registration.html#datacenter) 66 parameter is defined then any configuration entry that does not explicitly 67 refer to a desired datacenter should use that value from the upstream. 68 69## Compilation 70 71To correctly interpret a collection of configuration entries as a valid 72discovery chain, we first compile them into a form more directly usable by the 73layers responsible for configuring Connect sidecar proxies. 74 75You can interact with the compiler directly using the [discovery-chain 76API](/api/discovery-chain.html). 77 78### Compilation Parameters 79 80* **Service Name** - The service being discovered by name. 81* **Datacenter** - The datacenter to use as the basis of compilation. 82* **Overrides** - Discovery-time tweaks to apply when compiling. These should 83 be derived from either the 84 [proxy](/docs/connect/registration/service-registration.html#complete-configuration-example) 85 or 86 [upstream](/docs/connect/registration/service-registration.html#upstream-configuration-reference) 87 configurations if either are set. 88 89### Compilation Results 90 91The response is a single wrapped `CompiledDiscoveryChain` field: 92 93```json 94{ 95 "Chain": {...<CompiledDiscoveryChain>...} 96} 97``` 98 99#### `CompiledDiscoveryChain` 100 101The chain encodes a digraph of [nodes](#discoverygraphnode) and 102[targets](#discoverytarget). Nodes are the compiled representation of various 103discovery chain stages and targets are instructions on how to use the [health 104API](/api/health.html#list-nodes-for-connect-capable-service) to retrieve 105relevant service instance lists. 106 107You should traverse the nodes starting with [`StartNode`](#startnode). The 108nodes can be resolved by name using the [`Nodes`](#nodes) field. Targets can be 109resolved by name using the [`Targets`](#targets) field. 110 111- `ServiceName` `(string)` - The requested service. 112- `Namespace` `(string)` - The requested namespace. 113- `Datacenter` `(string)` - The requested datacenter. 114 115- `CustomizationHash` `(string: <optional>)` - A unique hash of any overrides 116 that affected the compilation of the discovery chain. 117 118 If set, this value should be used to prefix/suffix any generated load 119 balancer data plane objects to avoid sharing customized and non-customized 120 versions. 121 122- `Protocol` `(string)` - The overall protocol shared by everything in the 123 chain. 124 125- `StartNode` `(string)` - The first key into the `Nodes` map that should be 126 followed when traversing the discovery chain. 127 128- `Nodes` `(map<string|DiscoveryGraphNode>)` - All nodes available for traversal in 129 the chain keyed by a unique name. You can walk this by starting with 130 `StartNode`. 131 132 -> The names should be treated as opaque values and are only guaranteed to be 133 consistent within a single compilation. 134 135- `Targets` `(map<string|DiscoveryTarget>)` - A list of all targets used in this chain. 136 137 -> The names should be treated as opaque values and are only guaranteed to be 138 consistent within a single compilation. 139 140#### `DiscoveryGraphNode` 141 142A single node in the compiled discovery chain. 143 144- `Type` `(string)` - The type of the node. Valid values are: `router`, 145 `splitter`, and `resolver`. 146 147- `Name` `(string)` - The unique name of the node. 148 149- `Routes` `(array<DiscoveryRoute>)` - Only set for `Type:router`. List of routes to 150 render. 151 152 - `Definition` `(ServiceRoute)` - Relevant portion of underlying 153 `service-router` 154 [route](/docs/agent/config-entries/service-router.html#routes). 155 156 - `NextNode` `(string)` - The name of the next node in the chain in [`Nodes`](#nodes). 157 158- `Splits` `(array<DiscoverySplit>)` - Only set for `Type:splitter`. List of traffic 159 splits. 160 161 - `Weight` `(float32)` - Copy of underlying `service-splitter` 162 [`weight`](/docs/agent/config-entries/service-splitter.html#weight) field. 163 164 - `NextNode` `(string)` - The name of the next node in the chain in [`Nodes`](#nodes). 165 166- `Resolver` `(DiscoveryResolver: <optional>)` - Only set for `Type:resolver`. How 167 to resolve the service instances. 168 169 - `Default` `(bool)` - Set to true if no `service-resolver` config entry is 170 defined for this node and the default was synthesized. 171 172 - `ConnectTimeout` `(duration)` - Copy of the underlying `service-resolver` 173 [`ConnectTimeout`](/docs/agent/config-entries/service-resolver.html#connecttimeout) 174 field. If one is not defined the default of `5s` is returned. 175 176 - `Target` `(string)` - The name of the target to use found in [`Targets`](#targets). 177 178 - `Failover` `(DiscoveryFailover: <optional>)` - Compiled form of the 179 underlying `service-resolver` 180 [`Failover`](/docs/agent/config-entries/service-resolver.html#failover) 181 definition to use for this request. 182 183 - `Targets` `(array<string>)` - List of targets found in 184 [`Targets`](#targets) to failover to in order of preference. 185 186#### `DiscoveryTarget` 187 188- `ID` `(string)` - The unique name of this target. 189 190- `Service` `(string)` - The service to query when resolving a list of service instances. 191 192- `ServiceSubset` `(string: <optional>)` - The 193 [subset](/docs/agent/config-entries/service-resolver.html#service-subsets) of 194 the service to resolve. 195 196- `Namespace` `(string)` - The namespace to use when resolving a list of service instances. 197 198- `Datacenter` `(string)` - The datacenter to use when resolving a list of service instances. 199 200- `Subset` `(ServiceResolverSubset)` - Copy of the underlying 201 `service-resolver` 202 [`Subsets`](/docs/agent/config-entries/service-resolver.html#subsets) 203 definition for this target. 204 205 - `Filter` `(string: "")` - The 206 [filter expression](/api/features/filtering.html) to be used for selecting 207 instances of the requested service. If empty all healthy instances are 208 returned. 209 210 - `OnlyPassing` `(bool: false)` - Specifies the behavior of the resolver's 211 health check interpretation. If this is set to false, instances with checks 212 in the passing as well as the warning states will be considered healthy. If 213 this is set to true, only instances with checks in the passing state will 214 be considered healthy. 215 216- `MeshGateway` `(MeshGatewayConfig)` - The [mesh gateway 217 configuration](/docs/connect/mesh_gateway.html#connect-proxy-configuration) 218 to use when connecting to this target's service instances. 219 220 - `Mode` `(string: "")` - One of `none`, `local`, or `remote`. 221 222- `External` `(bool: false)` - True if this target is outside of this consul cluster. 223 224- `SNI` `(string)` - This value should be used as the 225 [SNI](https://en.wikipedia.org/wiki/Server_Name_Indication) value when 226 connecting to this set of endpoints over TLS. 227 228- `Name` `(string)` - The unique name for this target for use when generating 229 load balancer objects. This has a structure similar to [SNI](#sni), but will 230 not be affected by SNI customizations such as 231 [`ExternalSNI`](/docs/agent/config-entries/service-defaults.html#externalsni). 232