Introduction
A Linkerd config example
admin:
port: 9990
routers:
- protocol: http
label: int-http
dtab: |
/svc => /#/io.l5d.fs;
servers:
- port: 4140
ip: 0.0.0.0
- protocol: thrift
servers:
- port: 8081
ip: 0.0.0.0
thriftFramed: true
client:
thriftFramed: true
thriftMethodInDst: false
dtab: |
/svc => /#/io.l5d.fs/thrift;
namers:
- kind: io.l5d.fs
rootDir: disco
telemetry:
- kind: io.l5d.statsd
experimental: true
prefix: linkerd
hostname: 127.0.0.1
port: 8125
gaugeIntervalMs: 10000
sampleRate: 0.01
- kind: io.l5d.tracelog
sampleRate: 0.2
level: TRACE
Welcome to the Configuration Reference for linkerd!
linkerd’s configuration is controlled via config file, which must be provided
as a command-line argument. It may be a local file path or -
to
indicate that the configuration should be read from the standard input.
For convenience, the release package includes a default linkerd.yaml
file in
the config/
directory.
File Format
The configuration may be specified as a JSON or YAML object. There are no requirements on field ordering, though it’s generally good style to start a router with the protocol. Four top level keys are supported:
Key | Required | Description |
---|---|---|
admin | no | Configures Linkerd’s administrative interface. |
routers | yes | Configures Linkerd’s RPC support for various protocols. |
namers | no | Configures Linkerd’s integration with various service discovery backends. |
telemetry | no | Configures Linkerd’s metrics instrumentation. |
usage | no | Configures Linkerd usage reporting. |
Administrative interface
admin:
ip: 127.0.0.1
port: 9990
Linkerd supports an administrative interface, both as a web ui and a collection
of json endpoints. The exposed admin port and ip to listen on are configurable
via a top-level admin
section.
Key | Default Value | Description |
---|---|---|
ip | 0.0.0.0 |
IP for the admin interface. |
port | 9990 |
Port for the admin interface. |
Administrative endpoints
Example admin requests
curl :9990/admin
curl :9990/admin/tracing?enable=true
curl -H "Accept: application/json" :9990/admin/lint
curl -H "Accept: application/json" :9990/admin/threads
curl ":9990/admin/pprof/profile?seconds=10&hz=100"
curl ":9990/delegator.json?path=/http/1.1/GET/foo&dtab=/http/*=>/$/inet/127.1/9990"
Default admin endpoints available in both Linkerd and namerd:
Endpoint | Description |
---|---|
/admin |
retrieve a list of all available admin endpoints |
/admin/announcer |
set of announcement chains that have run through the announcers |
/admin/contention |
call stacks of blocked and waiting threads |
/admin/lint |
results for all registered linters, set Accept: application/json to force json |
/admin/lint.json |
identical to admin/lint |
/admin/ping |
simple health check endpoint, returns pong |
/admin/pprof/contention |
CPU contention profile which identifies blocked threads (Thread.State.BLOCKED), in pprof format. The process will be profiled for 10 seconds at a frequency of 100 hz. These values can be controlled via HTTP request parameters seconds and hz respectively. |
/admin/pprof/heap |
heap profile computed by the heapster agent, output is in pprof format |
/admin/pprof/profile |
CPU usage profile in pprof format. The process will be profiled for 10 seconds at a frequency of 100 hz. These values can be controlled via HTTP request parameters seconds and hz respectively. |
/admin/registry.json |
displays how Linkerd is currently configured across a variety of dimensions including the client stack, server stack, flags, service loader values, system properties, environment variables, build properties and more |
/admin/server_info |
build information about this linkerd |
/admin/shutdown |
initiate a graceful shutdown |
/admin/threads |
capture the current stacktraces, set Accept: application/json to force json |
/admin/threads.json |
identical to admin/threads |
/admin/tracing |
enable (/admin/tracing?enable=true ) or disable tracing (/admin/tracing?disable=true ) |
/config.json |
current Linkerd configuration, this should match your config file |
Endpoints only available in linkerd:
Endpoint | Description |
---|---|
/bound-names.json |
list of all known bound names from configured namers. namers must support the EnumeratingNamer trait to make this available, currently only supported by the io.l5d.k8s and io.l5d.fs namers. |
/delegator.json |
given path , dtab , and an optional namespace param, return the delegation tree |
/logging.json |
currently configured loggers and log levels |
Note that in addition to a default set of admin endpoints, Linkerd plugins may dynamically add their own endpoints.
This administrative interface was originally based on TwitterServer, more information may be found at TwitterServer HTTP Admin interface.
Routers Intro
A minimal Linkerd configuration example, which forwards all requests on
localhost:8080
tolocalhost:8888
routers:
- protocol: http
dtab: /svc/* => /$/inet/127.1/8888
servers:
- port: 8080
All configurations must define a routers key, the value of which must be an array of router configurations. Each router implements RPC for a supported protocol. Linkerd doesn’t need to understand the payload in an RPC call, but it does need to know enough about the protocol to determine the logical name of the destination.
See routers.
Namers and Service Discovery
namers:
- kind: io.l5d.fs
rootDir: disco
Linkerd supports a variety of common service discovery backends, including ZooKeeper and Consul. Linkerd provides abstractions on top of service discovery lookups that allow the use of arbitrary numbers of service discovery backends, and for precedence and failover rules to be expressed between them. This logic is governed by the routing configuration.
Naming and service discovery are configured via the namers
section of the
configuration file. A namer acts on paths that start with /#
followed by the
namer’s prefix. See namers.
Telemetry Intro
telemetry:
- kind: io.l5d.statsd
experimental: true
prefix: linkerd
hostname: 127.0.0.1
port: 8125
gaugeIntervalMs: 10000
sampleRate: 0.01
- kind: io.l5d.tracelog
sampleRate: 0.2
level: TRACE
A telemeter may receive stats and trace annotations, i.e. to send to a collector
or export. Telemetry data can be collected and exported from a Linkerd process by
configuring telemeters via a top-level telemetry
section. See
telemetry.
Usage
Example usage config
usage:
orgId: my-org
In order to make improvements and prioritize features, we’d like to gain a broader picture of how users run Linkerd. Linkerd gathers anonymized usage data, and sends it to Buoyant once an hour. This behavior can be configured or disabled in the usage config.
The kind of data captured is as follows:
- How linkerds are configured (The kinds of namers, initializers, identifiers, transformers, protocols, & interpreters used)
- What environments are linkerds running in (Operating System, Container orchestration solution),
- How do linkerds perform in those contexts (JVM performance, Number of requests served)
We do not collect the labels of namers/routers, designated service addresses or directories, dtabs, request/response data, or any other possibly identifying information.
To see the exact payload that is sent query localhost:9990/admin/metrics/usage
Key | Default Value | Description |
---|---|---|
orgId | empty by default | Optional string of your choosing that identifies your organization |
enabled | true | If set to true, data is sent to Buoyant once per hour |
Routers
All configurations must define a routers key, the value of which must be an array of router configurations. Routers also include servers, which define their entry points, client, which configures how clients are built, and service, which configures service level policy.
Router Parameters
routers:
- protocol: http
servers: ...
service: ...
client: ...
announcers: ...
bindingCache: ...
label: myPackIce
dstPrefix: /walruses/http
dtab: |
/host => /#/io.l5d.fs;
/walruses/http => /host;
originator: true
bindingTimeoutMs: 5000
Key | Default Value | Description |
---|---|---|
protocol | required | Either http , h2 , thrift , or mux . |
servers | required | A list of server objects. |
announcers | an empty list | A list of service discovery announcers that servers can announce to. |
dtab | an empty dtab | Sets the base delegation table. See dtabs for more. |
bindingTimeoutMs | 10 seconds | The maximum amount of time in milliseconds to spend binding a path. |
bindingCache | see binding cache | Binding cache size configuration. |
client | an empty object | A client configuration object. |
dstPrefix | protocol dependent | A path prefix to be used on request destinations. |
originator | false |
If true , indicates that this router is the first hop for linker-to-linker requests, and reflects that in the router’s stats. Useful for deduping linker-to-linker stats. |
interpreter | default interpreter | An interpreter object determining what module will be used to process destinations. |
label | the value of protocol | The name of the router (in stats and the admin ui) |
Binding Cache
- protocol: http
servers:
- port: 9000
bindingCache:
paths: 100
trees: 100
bounds: 100
clients: 10
Key | Default Value | Description |
---|---|---|
paths | 1000 |
Max number of paths in the path cache. |
trees | 1000 |
Max number of trees in the tree cache. |
bounds | 1000 |
Max number of bounds in the bounds cache. |
clients | 1000 |
Max number of clients in the clients cache. |
Server Parameters
servers:
- port: 8080
ip: 0.0.0.0
tls:
certPath: /foo/cert.pem
keyPath: /foo/key.pem
maxConcurrentRequests: 1000
announce:
- /#/io.l5d.serversets/discovery/prod/web
Key | Default Value | Description |
---|---|---|
port | protocol dependent | The TCP port number. Protocols may provide default values. If no default is provided, the port parameter is required. |
ip | loopback address | The local IP address. A value like 0.0.0.0 configures the server to listen on all local IPv4 interfaces. |
tls | no tls | The server will serve over TLS if this parameter is provided. see TLS. |
maxConcurrentRequests | unlimited | The maximum number of concurrent requests the server will accept. |
announce | an empty list | A list of concrete names to announce using the router’s announcers. |
clearContext | false |
If true , all headers that set Linkerd contexts are removed from inbound requests. Useful for servers exposed on untrusted networks. |
Service Configuration
This section defines the policy that Linkerd will use when talking to services.
The structure of this section depends on its kind
.
Key | Default Value | Description |
---|---|---|
kind | io.l5d.global |
Either io.l5d.global or io.l5d.static |
Global Service Config
- protocol: http
service:
kind: io.l5d.global
totalTimeoutMs: 500ms
retries:
budget:
minRetriesPerSec: 5
percentCanRetry: 0.5
ttlSecs: 15
backoff:
kind: jittered
minMs: 10
maxMs: 10000
This service configuration allows you to specify service parameters which will be applied to all services.
Static Service Config
- protocol: http
service:
kind: io.l5d.static
configs:
- prefix: /svc
retries:
budget:
minRetriesPerSec: 5
percentCanRetry: 0.5
ttlSecs: 15
backoff:
kind: jittered
minMs: 10
maxMs: 10000
- prefix: /svc/foo
totalTimeoutMs: 500ms
- prefix: /svc/bar
totalTimeoutMs: 200ms
This service configuration allows you to specify service parameters
which will be applied to all services that match a specified prefix. The service
configuration must contain a property called configs
which contains a list
of config objects. Each config object must specify a prefix and the
service parameters to apply to services that match that prefix.
If a service matches more than one prefix, all parameters from the matching
configs will be applied, with parameters defined later in the configuration file
taking precedence over those defined earlier.
Service Parameters
Key | Default Value | Description |
---|---|---|
retries | see retries | A retry policy for applicaiton-level retries. |
totalTimeoutMs | no timeout | The timeout for an entire request, including all retries, in milliseconds. |
responseClassifier | io.l5d.http.nonRetryable5XX |
A (sometimes protocol-specific) response classifier that determines which responses should be considered failures and, of those, which should be considered retryable. |
Client Configuration
This section defines how the clients that Linkerd creates will be configured. The structure of this section depends on
its kind
.
Key | Default Value | Description |
---|---|---|
kind | io.l5d.global |
Either io.l5d.global or io.l5d.static |
Global Client Config
- protocol: http
client:
kind: io.l5d.global
loadBalancer:
kind: ewma
failureAccrual:
kind: io.l5d.consecutiveFailures
failures: 10
This client configuration allows you to specify client parameters which will be applied to all clients.
Static Client Config
- protocol: http
client:
kind: io.l5d.static
configs:
- prefix: /#/io.l5d.fs
loadBalancer:
kind: ewma
- prefix: /#/io.l5d.fs/{service}
tls:
commonName: "{service}.linkerd.io"
- prefix: /$/inet/*/80
failureAccrual:
kind: io.l5d.consecutiveFailures
failures: 10
This client configuration allows you to specify client parameters
which will be applied to all clients that match a specified prefix. The client
configuration must contain a property called configs
which contains a list
of config objects. Each config object must specify a prefix and the
client parameters to apply to clients that match that prefix.
A prefix may contain wildcards (*
) and capture variables ({foo}
) which can
be referenced in some client parameters.
If a client matches more than one config’s prefix, all parameters from the
matching configs will be applied, with parameters defined later in the
configuration file taking precedence over those defined earlier.
Client Parameters
client:
tls:
kind: io.l5d.noValidation
commonName: foo
caCertPath: /foo/caCert.pem
requestAttemptTimeoutMs: 100
loadBalancer:
kind: ewma
enableProbation: false
requeueBudget:
percentCanRetry: 0.25
failureAccrual:
kind: io.l5d.consecutiveFailures
failures: 10
Key | Default Value | Description |
---|---|---|
hostConnectionPool | An empty object | see hostConnectionPool. |
tls | no tls | The router will make requests using TLS if this parameter is provided. It must be a client TLS object. |
loadBalancer | p2c | A load balancer object. |
failFast | false |
If true , connection failures are punished more aggressively. Should not be used with small destination pools. |
requeueBudget | see retry budget | A requeue budget for connection-level retries. |
failureAccrual | 5 consecutive failures | a failure accrual policy for all clients created by this router. |
requestAttemptTimeoutMs | no timeout | The timeout, in milliseconds, for each attempt (original or retry) of the request made by this client. |
Host Connection Pool
client:
hostConnectionPool:
minSize: 0
maxSize: 1000
idleTimeMs: 10000
maxWaiters: 5000
Key | Default Value | Description |
---|---|---|
minSize | 0 |
The minimum number of connections to maintain to each host. |
maxSize | Int.MaxValue | The maximum number of connections to maintain to each host. |
idleTimeMs | forever | The amount of idle time for which a connection is cached in milliseconds. |
maxWaiters | Int.MaxValue | The maximum number of connection requests that are queued when the connection concurrency exceeds maxSize. |
HTTP/1.1 protocol
Below: http-specific configuration options
routers:
- protocol: http
httpAccessLog: access.log
identifier:
kind: io.l5d.methodAndHost
maxChunkKB: 8
maxHeadersKB: 8
maxInitialLineKB: 4
maxRequestKB: 5120
maxResponseKB: 5120
servers:
- port: 5000
addForwardedHeader:
by: {kind: "ip:port"}
for: {kind: ip}
protocol: http
The HTTP/1.1 protocol is used when the protocol option of the routers configuration block is set to http. This protocol has additional configuration options on the routers block.
Key | Default Value | Description |
---|---|---|
dstPrefix | /svc |
A path prefix used by Http-specific identifiers. |
httpAccessLog | none | Sets the access log path. If not specified, no access log is written. |
identifier | The io.l5d.header.token identifier |
An identifier or list of identifiers. See Http-specific identifiers. |
maxChunkKB | 8 | The maximum size of an HTTP chunk. |
maxHeadersKB | 8 | The maximum size of all headers in an HTTP message. |
maxInitialLineKB | 4 | The maximum size of an initial HTTP message line. |
maxRequestKB | 5120 | The maximum size of a non-chunked HTTP request payload. |
maxResponseKB | 5120 | The maximum size of a non-chunked HTTP response payload. |
compressionLevel | -1 , automatically compresses textual content types with compression level 6 |
The compression level to use (on 0-9). |
HTTP Servers
HTTP servers accept additional configuration parameters.
Example: default
addForwardedHeader: {}
Key | Default Value | Description |
---|---|---|
addForwardedHeader | null | If set, a Forwarded header is added to all requests. See below. |
Adding the Forwarded
header
RFC 7239 describes how a
Forwarded
header may be added to requests by proxies. This RFC
requests that this header not be added unless explicitly configured
and that proxies obfuscate IP addresses unless explicitly configured
to transmit them.
Key | Default Value | Description |
---|---|---|
by | {kind: requestRandom} |
The labeler to use with the router’s server address |
for | {kind: requestRandom} |
The labeler to use with the upstream client’s address |
Endpoint labelers
The Forwarded
header includes labels describing the endpoints of the
upstream connection. Because this is sensitive information, it is
typically randomized.
addForwardedHeader:
for: {kind: ip}
by:
kind: static
label: linkerd
Kind | Description |
---|---|
ip | A textual IP address like 192.168.1.1 or "[2001:db8:cafe::17]" . |
ip:port | A textual IP:PORT address like "192.168.1.1:80" or "[2001:db8:cafe::17]:80" . |
connectionRandom | An obfuscated random label like _6Oq8jJ generated for all requests on a connection. |
requestRandom | An obfuscated random label like _6Oq8jJ generated for each request. |
router | Uses the router’s label as an obfuscated static label. |
static | Accepts a label parameter. Produces obfuscated static labels like _linkerd . |
HTTP/1.1 Identifiers
Identifiers are responsible for creating logical names from an incoming
request; these names are then matched against the dtab. (See the linkerd
routing overview for more details on
this.) All HTTP/1.1 identifiers have a kind
. If a list of identifiers is
provided, each identifier is tried in turn until one successfully assigns a
logical name to the request.
If no identifier is specified the io.l5d.header.token
identifier is used.
Key | Default Value | Description |
---|---|---|
kind | required | Either io.l5d.methodAndHost , io.l5d.path , io.l5d.header , io.l5d.header.token , or io.l5d.static . |
Method and Host Identifier
kind: io.l5d.methodAndHost
.
With this identifier, HTTP requests are turned into logical names using a
combination of Host
header, method, and (optionally) URI. Host
header value is lower-cased as per RFC 2616
.
Identifier Configuration:
Configuration example
identifier:
kind: io.l5d.methodAndHost
httpUriInDst: true
Key | Default Value | Description |
---|---|---|
httpUriInDst | false |
If true http paths are appended to destinations. This allows a form of path-prefix routing. This option is not recommended as performance implications may be severe; Use the path identifier instead. |
Identifier Path Parameters:
Dtab Path Format for HTTP/1.1
/ dstPrefix / "1.1" / method / host [/ uri* ]
Dtab Path Format for HTTP/1.0
/ dstPrefix / "1.0" / method [/ uri* ]
Key | Default Value | Description |
---|---|---|
dstPrefix | /svc |
The dstPrefix as set in the routers block. |
method | N/A | The HTTP method of the current request, ie OPTIONS , GET , HEAD , POST , PUT , DELETE , TRACE , or CONNECT . |
host | N/A | The value of the current request’s Host header. Case sensitive!. Not used in HTTP/1.0. |
uri | Not used | Only considered a part of the logical name if the config option httpUriInDst is true . |
Path Identifier
kind: io.l5d.path
With this identifier, HTTP requests are turned into names based only on the path component of the URL, using a configurable number of “/” separated segments from the start of their HTTP path.
Identifier Configuration:
With this configuration, a request to
:5000/true/love/waits.php
will be mapped to/http/true/love
and will be routed based on this name by the corresponding dtab. Additionally, becauseconsume
is true, after routing, requests will be proxied to the destination service with/waits.php
as the path component of the URL.
routers:
- protocol: http
identifier:
kind: io.l5d.path
segments: 2
consume: true
servers:
- port: 5000
Key | Default Value | Description |
---|---|---|
segments | 1 |
Number of segments from the path that are appended to destinations. |
consume | false |
Whether to additionally strip the consumed segments from the HTTP request proxied to the final destination service. This only affects the request sent to the destination service; it does not affect identification or routing. |
Identifier Path Parameters:
Dtab Path Format
/ dstPrefix [/ *urlPath ]
Key | Default Value | Description |
---|---|---|
dstPrefix | /svc |
The dstPrefix as set in the routers block. |
urlPath | N/A | A path from the URL whose number of segments is set in the identifier block. |
Header Identifier
kind: io.l5d.header
With this identifier, HTTP requests are turned into names based only on the
value of an HTTP header. The value of the HTTP header is interpreted as a path
and therefore must start with a /
.
Identifier Configuration:
With this configuration, the value of the
my-header
HTTP header will be used as the logical name.
routers:
- protocol: http
identifier:
kind: io.l5d.header
header: my-header
servers:
- port: 5000
Key | Default Value | Description |
---|---|---|
header | l5d-name |
The name of the HTTP header to use |
Identifier Path Parameters:
Dtab Path Format
/ dstPrefix [*headerValue ]
Key | Default Value | Description |
---|---|---|
dstPrefix | /svc |
The dstPrefix as set in the routers block. |
headerValue | N/A | The value of the HTTP header as a path. |
Header Token Identifier
kind: io.l5d.header.token
With this identifier, HTTP requests are turned into names based only on the value of an HTTP header. The name is a path with one segment and the value of that segment is taken from the HTTP header.
Identifier Configuration:
With this configuration, the value of the
my-header
HTTP header will be used as the logical name.
routers:
- protocol: http
identifier:
kind: io.l5d.header.token
header: my-header
servers:
- port: 5000
Key | Default Value | Description |
---|---|---|
header | Host |
The name of the HTTP header to use |
Identifier Path Parameters:
Dtab Path Format
/ dstPrefix / [headerValue]
Key | Default Value | Description |
---|---|---|
dstPrefix | /svc |
The dstPrefix as set in the routers block. |
headerValue | N/A | The value of the HTTP header as a path segment. |
Ingress Identifier
kind: io.l5d.ingress
Using this identifier enables Linkerd to function as a Kubernetes ingress controller. The ingress identifier compares HTTP requests to ingress resource rules, and assigns a name based on those rules.
Identifier Configuration:
This example watches all ingress resources in the default namespace:
routers:
- protocol: http
identifier:
kind: io.l5d.ingress
namespace: default
servers:
- port: 4140
dtab: /svc => /#/io.l5d.k8s
namers:
- kind: io.l5d.k8s
An example ingress resource watched by the Linkerd ingress controller:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: my-first-ingress
namespace: default
annotations:
kubernetes.io/ingress.class: "linkerd"
spec:
rules:
- http:
paths:
- path: /testpath
backend:
serviceName: test
servicePort: 80
So an HTTP request like
http://localhost:4140/testpath
would have an identified name of/svc/default/80/test
Key | Default Value | Description |
---|---|---|
namespace | (all) | The Kubernetes namespace where the ingress resources are deployed. If not specified, Linkerd will watch all namespaces. |
host | localhost |
The Kubernetes master host. |
port | 8001 |
The Kubernetes master port. |
Identifier Path Parameters
Dtab Path Format
/ dstPrefix / namespace / port / service
Key | Default Value | Description |
---|---|---|
dstPrefix | /svc |
The dstPrefix as set in the routers block. |
namespace | N/A | The Kubernetes namespace. |
port | N/A | The port name. |
svc | N/A | The name of the service. |
Static Identifier
kind: io.l5d.static
This identifier always assigns the same static name to all requests.
Identifier Configuration:
routers:
- protocol: http
identifier:
kind: io.l5d.static
path: /foo/bar
Key | Default Value | Description |
---|---|---|
path | required | The name to assign to all requests |
Identifier Path Parameters
Dtab Path Format
/ dstPrefix / *path
Key | Default Value | Description |
---|---|---|
dstPrefix | /svc |
The dstPrefix as set in the routers block. |
path | N/A | The path given in the configuration. |
HTTP Engines
This configures an HTTP router that uses the new netty4 implementation on both the client and server:
- protocol: http
servers:
- port: 4141
ip: 0.0.0.0
engine:
kind: netty4
client:
engine:
kind: netty4
An engine may be configured on HTTP clients and servers, causing an alternate HTTP implementation to be used.
Key | Default Value | Description |
---|---|---|
kind | netty3 |
Either netty3 or netty4 (netty4 will become default in an upcoming release). |
HTTP Headers
Linkerd reads and sets several headers prefixed by l5d-
.
Context Headers
Context headers (l5d-ctx-*
) are generated and read by linkerd
instances. Applications should forward all context headers in order
for all Linkerd features to work.
Header | Description |
---|---|
dtab-local |
Deprecated. Use l5d-ctx-dtab and l5d-dtab . |
l5d-ctx-deadline |
Describes time bounds within which a request is expected to be satisfied. Currently deadlines are only advisory and do not factor into request cancellation. |
l5d-ctx-trace |
Encodes Zipkin-style trace IDs and flags so that trace annotations emitted by Linkerd may be correlated. |
User Headers
Append a dtab override to the dtab for this request
curl -H 'l5d-dtab: /host/web => /host/web-v2' "localhost:5000"
User headers enable user-overrides.
Header | Description |
---|---|
l5d-dtab |
A client-specified delegation override. |
l5d-sample |
A client-specified trace sample rate override. |
Informational Request Headers
The informational headers Linkerd emits on outgoing requests.
Header | Description |
---|---|
l5d-dst-service |
The logical service name of the request as identified by linkerd. |
l5d-dst-client |
The concrete client name after delegation. |
l5d-dst-residual |
An optional residual path remaining after delegation. |
l5d-reqid |
A token that may be used to correlate requests in a callgraph across services and Linkerd instances. |
Applications are not required to forward these headers on downstream requests.
Informational Response Headers
The informational headers Linkerd emits on outgoing responses.
Header | Description |
---|---|
l5d-err |
Indicates a linkerd-generated error. Error responses that do not have this header are application errors. |
l5d-retryable |
Indicates that the request for this response is known to be safe to retry (for example, because it was not delivered to its destination). |
Applications should not forward these headers on upstream responses.
HTTP/2 protocol
Below: Authority (Host) based routing for HTTP/2 over TLS
routers:
- protocol: h2
experimental: true
servers:
- port: 4143
tls:
certPath: .../public/linkerd.pem
keyPath: .../private/linkerd.pem
caCertPath: .../ca.pem
identifier:
kind: io.l5d.header.token
header: ":authority"
dtab: |
/svc => /#/io.l5d.fs ;
client:
tls:
kind: io.l5d.boundPath
caCertPath: .../ca.pem
names:
- prefix: "/#/io.l5d.fs/{service}"
commonNamePattern: "{service}"
Below: plaintext gRPC
routers:
- protocol: h2
experimental: true
label: grpc
servers:
- port: 4142
identifier:
kind: io.l5d.header.path
segments: 2
dtab: |
/svc => /#/io.l5d.fs ;
because gRPC encodes URLs as /serviceName/methodName, we can simply register service names into a discovery system and route accordingly. Note that gRPC may be configured over TLS as well.
protocol: h2
Linkerd now has experimental support for HTTP/2. There are a number of open issues that are being addressed. Please report any additional issues with this protocol!
Key | Default Value | Description |
---|---|---|
dstPrefix | /svc |
A path prefix used by H2-specific identifiers. |
experimental | false |
Set this to true to opt-in to experimental h2 support. |
identifier | The io.l5d.header.token identifier |
An identifier or list of identifiers. See HTTP/2 Identifiers. |
When TLS is configured, h2 routers negotiate to communicate over HTTP/2 via ALPN.
When TLS is not configured, h2 servers accept both prior knowledge and HTTP Upgrade requests. Plaintext clients are currently only capable of issuing prior-knowledge requests.
HTTP/2 Server Parameters
Key | Default Value | Description |
---|---|---|
windowUpdateRatio: | 0.99 |
A number between 0 and 1, exclusive, indicating the ratio at which window updates should be sent. With a value of 0.75, updates will be sent when the available window size is 75% of its capacity. |
headerTableBytes | none | Configures SETTINGS_HEADER_TABLE_SIZE on new streams. |
initialStreamWindowBytes | 64KB | Configures SETTINGS_INITIAL_WINDOW_SIZE on streams. |
maxConcurrentStreamsPerConnection | unlimited | Configures SETTINGS_MAX_CONCURRENT_STREAMS on new streams. |
maxFrameBytes | 16KB | Configures SETTINGS_MAX_FRAME_SIZE on new streams. |
maxHeaderListByts | none | Configures SETTINGS_MAX_HEADER_LIST_SIZE on new streams. |
HTTP/2 Client Parameters
Key | Default Value | Description |
---|---|---|
windowUpdateRatio: | 0.99 |
A number between 0 and 1, exclusive, indicating the ratio at which window updates should be sent. With a value of 0.75, updates will be sent when the available window size is 75% of its capacity. |
headerTableBytes | none | Configures SETTINGS_HEADER_TABLE_SIZE on new streams. |
initialStreamWindowBytes | 64KB | Configures SETTINGS_INITIAL_WINDOW_SIZE on streams. |
maxFrameBytes | 16KB | Configures SETTINGS_MAX_FRAME_SIZE on new streams. |
maxHeaderListByts | none | Configures SETTINGS_MAX_HEADER_LIST_SIZE on new streams. |
HTTP/2 Identifiers
Identifiers are responsible for creating logical names from an incoming
request; these names are then matched against the dtab. (See the linkerd
routing overview for more details on
this.) All h2 identifiers have a kind
. If a list of identifiers is
provided, each identifier is tried in turn until one successfully assigns a
logical name to the request.
Key | Default Value | Description |
---|---|---|
kind | required | Either io.l5d.header.token , io.l5d.header.path , or io.l5d.ingress . |
HTTP/2 Header Token identifier
kind: io.l5d.header.token
.
With this identifier, requests are turned into logical names using the
value of the named header. By default, the :authority
pseudo-header
is used to provide host-based routing.
Namer Configuration:
With this configuration, the value of the
my-header
header will be used as the logical name.
routers:
- protocol: h2
experimental: true
identifier:
kind: io.l5d.header.token
header: my-header
servers:
- port: 5000
Key | Default Value | Description |
---|---|---|
header | :authority |
The name of the header to extract a token from. If there are multiple headers with this name, the last one is used. |
Namer Path Parameters:
Dtab Path Format
/ dstPrefix / headerValue
Key | Default Value | Description |
---|---|---|
dstPrefix | /svc |
The dstPrefix as set in the routers block. |
headerValue | N/A | The value of the header. |
HTTP/2 Header Path Identifier
kind: io.l5d.header.path
With this identifier, requests are identified using a path read from a
header. This is useful for routing gRPC requests. By default, the :path
psuedo-header is used.
Namer Configuration:
With this configuration, a request to
:5000/true/love/waits.php?thing=1
will be mapped to/h2/true/love
and will be routed based on this name by the corresponding Dtab.
routers:
- protocol: h2
experimental: true
identifier:
kind: io.l5d.header.path
segments: 2
servers:
- port: 5000
Key | Default Value | Description |
---|---|---|
header | :path |
The name of the header to extract a Path from. If there are multiple headers with this name, the last one is used. |
segments | None | If specified, the number of path segments that are required extracted from each request. |
Namer Path Parameters:
Dtab Path Format
/ dstPrefix / *urlPath
Key | Default Value | Description |
---|---|---|
dstPrefix | /svc |
The dstPrefix as set in the routers block. |
urlPath | N/A | The first segments elements of the path from the URL |
HTTP/2 Ingress Identifier
kind: io.l5d.ingress
Using this identifier enables Linkerd to function as a Kubernetes ingress controller. The ingress identifier compares HTTP/2 requests to ingress resource rules, and assigns a name based on those rules.
Identifier Configuration:
This example watches all ingress resources in the default namespace:
routers:
- protocol: h2
experimental: true
identifier:
kind: io.l5d.ingress
namespace: default
servers:
- port: 4140
dtab: /svc => /#/io.l5d.k8s
namers:
- kind: io.l5d.k8s
An example ingress resource watched by the Linkerd ingress controller:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: my-first-ingress
namespace: default
annotations:
kubernetes.io/ingress.class: "linkerd"
spec:
rules:
- http:
paths:
- path: /testpath
backend:
serviceName: test
servicePort: 80
So an HTTP/2 request like
https://localhost:4140/testpath
would have an identified name of/svc/default/80/test
Key | Default Value | Description |
---|---|---|
namespace | (all) | The Kubernetes namespace where the ingress resources are deployed. If not specified, Linkerd will watch all namespaces. |
host | localhost |
The Kubernetes master host. |
port | 8001 |
The Kubernetes master port. |
Identifier Path Parameters
Dtab Path Format
/ dstPrefix / namespace / port / service
Key | Default Value | Description |
---|---|---|
dstPrefix | /svc |
The dstPrefix as set in the routers block. |
namespace | N/A | The Kubernetes namespace. |
port | N/A | The port name. |
svc | N/A | The name of the service. |
HTTP/2 Headers
Linkerd reads and sets several headers prefixed by l5d-
, as is done
by the http
protocol.
HTTP/2 Context Headers
Context headers (l5d-ctx-*
) are generated and read by linkerd
instances. Applications should forward all context headers in order
for all Linkerd features to work.
Header | Description |
---|---|
dtab-local |
Deprecated. Use l5d-ctx-dtab and l5d-dtab . |
l5d-ctx-deadline |
Describes time bounds within which a request is expected to be satisfied. Currently deadlines are only advisory and do not factor into request cancellation. |
l5d-ctx-trace |
Encodes Zipkin-style trace IDs and flags so that trace annotations emitted by Linkerd may be correlated. |
HTTP/2 User Headers
Append a dtab override to the dtab for this request
curl -H 'l5d-dtab: /host/web => /host/web-v2' "localhost:5000"
User headers enable user-overrides.
Header | Description |
---|---|
l5d-dtab |
A client-specified delegation override. |
l5d-sample |
A client-specified trace sample rate override. |
HTTP/2 Informational Request Headers
The informational headers Linkerd emits on outgoing requests.
Header | Description |
---|---|
l5d-dst-service |
The logical service name of the request as identified by linkerd. |
l5d-dst-client |
The concrete client name after delegation. |
l5d-dst-residual |
An optional residual path remaining after delegation. |
l5d-reqid |
A token that may be used to correlate requests in a callgraph across services and Linkerd instances. |
Applications are not required to forward these headers on downstream requests.
HTTP/2 Informational Response Headers
The informational headers Linkerd emits on outgoing responses.
Header | Description |
---|---|
l5d-err |
Indicates a linkerd-generated error. Error responses that do not have this header are application errors. |
Applications are not required to forward these headers on upstream responses.
Thrift Protocol
This config routes thrift (via buffered transport using the TCompactProtocol) from port 4004 to port 5005
routers:
- protocol: thrift
label: port-shifter
dtab: |
/svc => /$/inet/127.1/5005;
servers:
- port: 4004
ip: 0.0.0.0
thriftFramed: false
thriftProtocol: compact
client:
thriftFramed: false
thriftProtocol: compact
protocol: thrift
If the TTwitter thrift protocol is
used, the value from the dest
request header will be used for routing:
Dtab Path Format For Thrift
/ dstPrefix [/ dest] [/ thriftMethod ]
Otherwise, the Thrift protocol does not encode a destination name in the message itself and the dest part of the path will be absent.
Thrift Router Parameters
Key | Default Value | Description |
---|---|---|
dstPrefix | /svc |
A path prefix used in dtab . |
thriftMethodInDst | false |
If true , thrift method names are appended to destinations for outgoing requests. |
Thrift Server Parameters
Key | Default Value | Description |
---|---|---|
port | 4114 |
The TCP port number. |
thriftFramed | true |
If true , a framed thrift transport is used for incoming requests; otherwise, a buffered transport is used. Typically this setting matches the router’s thriftFramed param. |
thriftProtocol | binary |
Either binary (TBinaryProtocol) or compact (TCompantProtocol). Typically this setting matches the router’s client thriftProtocol param. |
Thrift Client Parameters
Key | Default Value | Description |
---|---|---|
thriftFramed | true |
If true , a framed thrift transport is used for outgoing requests; otherwise, a buffered transport is used. Typically this setting matches the router’s servers’ thriftFramed param. |
thriftProtocol | binary |
Either binary (TBinaryProtocol) or compact (TCompantProtocol). Typically this setting matches the router’s servers’ thriftProtocol param. |
attemptTTwitterUpgrade | false |
Controls whether thrift protocol upgrade should be attempted. |
ThriftMux Protocol (experimental)
This config routes thriftmux from port 4400 to port 5005.
routers:
- protocol: thriftmux
experimental: true
label: port-shifter
dtab: |
/svc => /$/inet/127.1/5005;
servers:
- port: 4400
ip: 0.0.0.0
protocol: thriftmux
Linkerd experimentally supports the thriftmux
Thriftmux protocol is capable of routing traffic to pure thrift service and will use Thrift protocol on the client.
Protocol configuration uses the same parameters as Thrift protocol.
ThriftMux Router Parameters
ThriftMux Server Parameters
ThriftMux Client Parameters
Mux Protocol (experimental)
A mux router configuration that routes requests to port 9001
routers:
- protocol: mux
label: power-level-router
dstPrefix: /overNineThousand
dtab: |
/overNineThousand => /$/inet/127.0.1/9001;
protocol: mux
Linkerd experimentally supports the mux protocol.
Mux Router Parameters
Key | Default Value | Description |
---|---|---|
dstPrefix | /svc |
A path prefix used in dtab . |
Mux Server Parameters
Key | Default Value | Description |
---|---|---|
port | 4141 |
The TCP port number. |
Interpreter
Example Interpreter Configuration
routers:
- ...
interpreter:
kind: io.l5d.namerd
dst: /$/inet/1.2.3.4/4180
An interpreter determines how names are resolved.
Key | Default Value | Description |
---|---|---|
kind | default |
Either default , io.l5d.namerd , io.l5d.namerd.http , io.l5d.mesh , or io.l5d.fs . |
transformers | No transformers | A list of transformers to apply to the resolved addresses. |
Default
kind: default
The default interpreter resolves names via the configured
namers
, with a fallback to the default Finagle
Namer.Global
that handles paths of the form /$/
.
namerd thrift
kind: io.l5d.namerd
The namerd thrift interpreter offloads the responsibilities of name resolution
to the namerd service. Any namers configured in this Linkerd are not used. The
interpreter users namerd’s long-poll thrift interface
(io.l5d.thriftNameInterpreter
). Note that the protocol that the interpreter
uses to talk to namerd is unrelated to the protocols of Linkerd’s routers.
Key | Default Value | Description |
---|---|---|
dst | required | A Finagle path locating the namerd service. |
namespace | default |
The name of the namerd dtab to use. |
retry | see namerd retry | An object configuring retry backoffs for requests to namerd. |
tls | no tls | Requests to namerd will be made using TLS if this parameter is provided. It must be a namerd client TLS object. |
namerd retry
Key | Default Value | Description |
---|---|---|
baseSeconds | 5 seconds | The base number of seconds to wait before retrying. |
maxSeconds | 10 minutes | The maximum number of seconds to wait before retrying. |
namerd client tls
Key | Default Value | Description |
---|---|---|
commonName | required | The common name to use for namerd requests. |
caCert | N/A | The path to the CA cert used for common name validation. |
namerd http
kind: io.l5d.namerd.http
The namerd http interpreter offloads the responsibilities of name resolution to
the namerd service. Any namers configured in this Linkerd are not used. The
interpreter uses namerd’s HTTP streaming interface (io.l5d.httpController
).
Note that the protocol that the interpreter uses to talk to namerd is unrelated
to the protocols of Linkerd’s routers.
Key | Default Value | Description |
---|---|---|
experimental | required | Because the http interpreter is still considered experimental, you must set this to true to use it. |
dst | required | A Finagle path locating the namerd service. |
namespace | default |
The name of the namerd dtab to use. |
retry | see namerd retry | An object configuring retry backoffs for requests to namerd. |
tls | no tls | Requests to namerd will be made using TLS if this parameter is provided. It must be a namerd client TLS object. |
namerd mesh
kind: io.l5d.mesh
The namerd mesh interpreter offloads the responsibilities of name resolution to
the namerd service. Any namers configured in this Linkerd are not used. The
interpreter uses namerd’s gRPC mesh interface (io.l5d.mesh
). Note that the
protocol that the interpreter uses to talk to namerd is unrelated to the
protocols of Linkerd’s routers.
Key | Default Value | Description |
---|---|---|
experimental | required | Because the mesh interpreter is still considered experimental, you must set this to true to use it. |
dst | required | A Finagle path locating the namerd service. |
root | /default |
A single-element Finagle path representing the namerd namespace. |
retry | see namerd retry | An object configuring retry backoffs for requests to namerd. |
tls | no tls | The namerd mesh interface does not support server TLS configuration at this time. |
File-System
kind: io.l5d.fs
The file-system interpreter resolves names via the configured
namers
, just like the default interpreter, but also uses
a dtab read from a file on the local file-system. The specified file is watched
for changes so that the dtab may be edited live.
Key | Default Value | Description |
---|---|---|
dtabFile | required | The file-system path to a file containing a dtab. |
Transformer
Example Transformer Configuration
routers:
- ...
interpreter:
...
transformers:
- kind: io.l5d.localhost
Transformers perform a transformation on the addresses resolved by the interpreter. Transformations are applied sequentially in the order they appear.
Key | Default Value | Description |
---|---|---|
kind | required | Either io.l5d.localhost , io.l5d.port , io.l5d.k8s.daemonset , io.l5d.k8s.localnode , io.l5d.replace , or io.l5d.const . |
Localhost
kind: io.l5d.localhost
The localhost transformer filters the list of addresses down to only addresses that have the same IP address as localhost. The IP of localhost is determined by doing a one-time dns lookup of the local hostname. This transformer can be used by an incoming router to only route traffic to local destinations.
Port
kind: io.l5d.port
The port transformer replaces the port number in every addresses with a configured value. This can be used if there is an incoming Linkerd router (or other reverse-proxy) running on a fixed port on each host and you with to send traffic to that port instead of directly to the destination address.
Key | Default Value | Description |
---|---|---|
port | required | The port number to use. |
DaemonSet (Kubernetes)
kind: io.l5d.k8s.daemonset
The DaemonSetTransformer maps each address in the destination NameTree to a member of a given daemonset that is on the same /24 subnet. Since each k8s node is its own /24 subnet, the result is that each destination address is mapped to the member of the daemonset that is running on the same node. This can be used to redirect traffic to a reverse-proxy that runs as a daemonset.
This transformer assumes that there is a Kubernetes service for the daemonset which can be used to find all pods in the daemonset.
Key | Default Value | Description |
---|---|---|
k8sHost | localhost |
The Kubernetes master host. |
k8sPort | 8001 |
The Kubernetes master port. |
namespace | required | The Kubernetes namespace of the daemonset. |
service | required | The Kubernetes service name for the daemonset. |
port | required | The name of the daemonset port to use. |
hostNetwork | false |
If true, use nodeName instead of /24 subnet to determine which daemonset pod is on the destination node. Set this to true if the daemonset is running with hostNetwork: true . |
Localnode (Kubernetes)
kind: io.l5d.k8s.localnode
The localnode transformer filters the list of addresses down to only addresses that are on the same /24 subnet as localhost. Since each k8s node is its own /24 subnet, the result is that only addresses on the local node are used.
This transformer does not have any configuration properties but it does require
the POD_IP
environment variable be set with the localhost IP address. This is
most easily done with the
Kubernetes downward API.
In your container spec:
env:
- name: POD_IP
valueFrom:
fieldRef:
fieldPath: status.podIP
Key | Default Value | Description |
---|---|---|
hostNetwork | false |
If true, use nodeName to determine which pods are on the local node. This adds the requirement that the NODE_NAME environment variable be set with the node name. Set this to true if the pod is running with hostNetwork: true . |
Replace
kind: io.l5d.replace
The replace transformer replaces all bound names with a configurable path.
This differs from the Const transformer in that if the original NameTree is
Neg
then the result will be Neg
as well. This is useful if you want to
use a namer to check the validity of a name but then actually route to a
different name.
Key | Default Value | Description |
---|---|---|
path | required | Bound names will be replaced with this path. |
Const
kind: io.l5d.const
The const transformer ignores the input and always returns a constant
configurable path. This differs from the Replace transformer in that it always
returns the configured path, even when the original NameTree is Neg
.
Key | Default Value | Description |
---|---|---|
path | required | Ignore the input and return this path. |
HTTP Response Classifiers
Example response classifier config
routers:
- protocol: http
service:
responseClassifier:
kind: io.l5d.http.retryableRead5XX
Response classifiers determine which HTTP responses are considered to be failures (for the purposes of success rate calculation) and which of these responses may be retried.
Key | Default Value | Description |
---|---|---|
kind | io.l5d.http.nonRetryable5XX |
Either io.l5d.http.nonRetryable5XX , io.l5d.h2.nonRetryable5XX , io.l5d.http.retryableRead5XX , io.l5d.h2.retryableRead5XX , io.l5d.http.retryableIdempotent5XX , or io.l5d.h2.retryableIdempotent5XX . |
Non-Retryable 5XX
kind: io.l5d.http.nonRetryable5XX
kind: io.l5d.h2.nonRetryable5XX
All 5XX responses are considered to be failures and none of these requests are considered to be retryable.
Retryable Read 5XX
kind: io.l5d.http.retryableRead5XX
kind: io.l5d.h2.retryableRead5XX
All 5XX responses are considered to be failures. However, GET
,
HEAD
, OPTIONS
, and TRACE
requests may be retried automatically.
Retryable Idempotent 5XX
kind: io.l5d.http.retryableIdempotent5XX
kind: io.l5d.h2.retryableIdempotent5XX
Like io.l5d.http.retryableRead5XX/io.l5d.h2.retryableRead5XX, but PUT
and
DELETE
requests may also be retried.
Failure Accrual
routers:
- ...
client:
failureAccrual:
kind: io.l5d.successRate
successRate: 0.9
requests: 1000
backoff:
kind: jittered
minMs: 5000
maxMs: 300000
Linkerd uses failure accrual to track the number of requests that have failed to a given node, and it will backoff sending requets to any nodes whose failures have exceeded a given threshold. Both the failure threshold and the backoff behavior are configurable. By default, if Linkerd observes 5 consecutive failures from a node, it will mark the node as dead and only attempt to resend it traffic in increasing intervals between 5 seconds and 5 minutes.
Key | Default Value | Description |
---|---|---|
kind | required | Either io.l5d.consecutiveFailures , io.l5d.successRate , io.l5d.successRateWindowed , or none . |
backoff | jittered backoff from 5s to 300s | A backoff policy that determines how long to wait before resending traffic. |
Consecutive Failures
kind: io.l5d.consecutiveFailures
Observes the number of consecutive failures to each node, and backs off sending requests to nodes that have exceeded the specified number of failures.
Key | Default Value | Description |
---|---|---|
failures | required | Number of consecutive failures. |
Success Rate
kind: io.l5d.successRate
Computes an exponentially-weighted moving average success rate for each node, and backs off sending requests to nodes that have fallen below the specified success rate. The window size for computing success rate is constrained to a fixed number of requests.
Key | Default Value | Description |
---|---|---|
successRate | required | Target success rate. |
requests | required | Number of requests over which success rate is computed. |
Success Rate (windowed)
kind: io.l5d.successRateWindowed
Computes an exponentially-weighted moving average success rate for each node, and backs off sending requests to nodes that have fallen below the specified success rate. The window size for computing success rate is constrained to a fixed time window.
Key | Default Value | Description |
---|---|---|
successRate | required | Target success rate. |
window | required | Number of seconds over which success rate is computed. |
None
kind: none
Disables failure accrual altogether. This policy does not accept any additional parameters.
TLS
Server TLS
routers:
- protocol: http
servers:
- port: 4140
# accept incoming TLS traffic from remote linkerd
tls:
certPath: /certificates/certificate.pem
keyPath: /certificates/key.pem
dtab: |
/http => /$/inet/127.1/8080;
In order to accept incoming tls traffic, the tls parameter must be defined on the server.
Key | Default Value | Description |
---|---|---|
certPath | required | File path to the TLS certificate file. |
keyPath | required | File path to the TLS key file. |
See Transparent TLS with linkerd for more on how to generate certificate and key files.
Client TLS
Client TLS is defined in the client section of routers:
routers:
- protocol: http
client:
tls:
commonName: linkerd.io
trustCerts:
- /certificates/cacert.pem
In order to send outgoing tls traffic, the tls parameter must be defined as a client parameter.
A client TLS object describes how Linkerd should use TLS when sending requests to destination services.
Key | Default Value | Description |
---|---|---|
disableValidation | false | Enable this to skip hostname validation (unsafe). |
commonName | required unless disableValidation is set | The common name to use for all TLS requests. |
trustCerts | empty list | A list of file paths of CA certs to use for common name validation. |
Any variables captured from the client prefix may be used in the common name.
routers:
- protocol: http
client:
kind: io.l5d.static
configs:
- prefix: /#/io.l5d.fs/{service}
tls:
commonName: "{service}.linkerd.io"
trustCerts:
- /certificates/cacert.pem
Load Balancer
Example load balancer configuration
routers:
- ...
client:
loadBalancer:
kind: ewma
maxEffort: 10
decayTimeMs: 15000
Key | Default Value | Description |
---|---|---|
kind | p2c |
Either p2c , ewma , aperture , heap , or roundRobin . |
enableProbation | false |
If true , endpoints are eagerly evicted from service discovery. See Finagle’s LoadBalancerFactory.EnableProbation. |
Power of Two Choices: Least Loaded
kind: p2c
Key | Default Value | Description |
---|---|---|
maxEffort | 5 |
The number of times a load balancer can retry if the previously picked node was marked unavailable. |
Power of Two Choices: Peak EWMA
kind: ewma
Key | Default Value | Description |
---|---|---|
maxEffort | 5 |
The number of times a load balancer can retry if the previously picked node was marked unavailable. |
decayTimeMs | 10 seconds | The window of latency observations. |
Aperture: Least Loaded
kind: aperture
Key | Default Value | Description |
---|---|---|
maxEffort | 5 |
The number of times a load balancer can retry if the previously picked node was marked unavailable. |
smoothWin | 5 seconds | The window of concurrent load observation. |
lowLoad | 0.5 |
The lower bound of the load band used to adjust an aperture. |
highLoad | 2 |
The upper bound of the load band used to adjust an aperture. |
minAperture | 1 |
The minimum size of the aperture. |
Heap: Least Loaded
kind: heap
Round Robin
kind: roundRobin
Key | Default Value | Description |
---|---|---|
maxEffort | 5 |
The number of times a load balancer can retry if the previously picked node was marked unavailable. |
Retries
routers:
- ...
service:
retries:
budget:
minRetriesPerSec: 5
percentCanRetry: 0.5
ttlSecs: 15
backoff:
kind: jittered
minMs: 10
maxMs: 10000
Linkerd can automatically retry requests on certain failures and can be configured via the retries block. Retries fall into two categories: retries and requeues.
Key | Default Value | Description |
---|---|---|
budget | See retry budget | Object that determins how many failed requests are eligible to be retried. |
backoff | See retry backoff | Object that determines which backoff algorithm should be used. |
Retries
Retries are for application-level failures (such as 5XX responses in the case of
HTTP) as determined by the response classifier. If the response classifier
determines that a request is a retryable failure, and the retry budget is not
empty, then the request will be retried. Retries are configured by the
retries
parameter on the service
object. On the retries
object you may
specify the retry budget and retry backoff schedule. Each service has its own
retry budget that is not shared with other services or clients.
Requeues
Requeues are for connection-level failures that are guaranteed to be idempotent.
If a connection-level failure is encountered and there is requeue budget
available, then the request will be retried. Requeue budgets are configured
by the requeueBudget
parameter on the client
object. Requeues happen
immediately with no backoff. Each client has its own requeue budget that is not
shared with other clients or services.
Retry Budget Parameters
For every 10 non-retry calls, allow 1 retry
service:
retries:
budget:
percentCanRetry: 0.1
For every non-retry call, allow 2 retries
service:
retries:
budget:
percentCanRetry: 2.0
Key | Default Value | Description |
---|---|---|
minRetriesPerSec | 10 |
The minimum rate of retries allowed in order to accommodate clients that have just started issuing requests, as well as clients that do not issue many requests per window. Must be non-negative. If 0 , no reserve is given. |
percentCanRetry | 0.2 |
The percentage of calls that can be retried. This is in addition to any retries allowed via minRetriesPerSec . Must be >= 0 and <= 1000 . |
ttlSecs | 10 |
The amount of time in seconds that successful calls are considered when calculating retry budgets. |
Retry Backoff Parameters
Key | Default Value | Description |
---|---|---|
kind | required | Either constant or jittered . |
Constant Backoff
kind: constant
Key | Default Value | Description |
---|---|---|
ms | 0 |
The number of milliseconds to wait before each retry. |
Jittered Backoff
kind: jittered
Uses a decorrelated jitter backoff algorithm.
Key | Default Value | Description |
---|---|---|
minMs | required | The minimum number of milliseconds to wait before each retry. |
maxMs | required | The maximum number of milliseconds to wait before each retry. |
Namers
namers:
- kind: io.l5d.fs
prefix: /disco
rootDir: disco
A namer binds a concrete name to a physical address.
Key | Default Value | Description |
---|---|---|
kind | required | Either io.l5d.fs , io.l5d.serversets , io.l5d.consul , io.l5d.k8s , io.l5d.marathon , io.l5d.zkLeader , io.l5d.curator , or io.l5d.rewrite . |
prefix | namer dependent | Resolves names with /#/<prefix> . |
experimental | false |
Set this to true to enable the namer if it is experimental. |
transformers | No transformers | A list of transformers to apply to the resolved addresses. |
File-based service discovery
kind: io.l5d.fs
File-based Configuration
Example fs configuration:
namers:
- kind: io.l5d.fs
rootDir: disco
Then reference the namer in the dtab to use it:
dtab: |
/svc => /#/io.l5d.fs
With the filesystem directory:
$ ls disco/
apps users web
The contents of the files look similar to this:
$ cat config/web
192.0.2.220 8080
192.0.2.105 8080
192.0.2.210 8080 * 2.0
Linkerd ships with a simple file-based service discovery mechanism, called the file-based namer. This system is intended to act as a structured form of basic host lists.
While simple, the file-based namer is a full-fledged service discovery system, and can be useful in production systems where host configurations are largely static. It can act as an upgrade path for the introduction of an external service discovery system, since application code will be isolated from these changes. Finally, when chained with precedence rules, the file-based namer can be a convenient way to add local service discovery overrides for debugging or experimentation.
This service discovery mechanism is tied to the directory set by the
namers/rootDir
key in config.yaml
. This directory must be on the local
filesystem and relative to Linkerd’s start path. Every file in this directory
corresponds to a service, where the name of the file is the service’s concrete
name, and the contents of the file must be a newline-delimited set of
addresses.
Linkerd watches all files in this directory, so files can be added, removed, or updated, and Linkerd will pick up the changes automatically.
Key | Default Value | Description |
---|---|---|
prefix | io.l5d.fs |
Resolves names with /#/<prefix> . |
rootDir | required | the directory containing name files as described above. |
File-based Path Parameters
Dtab Path Format:
/#/<prefix>/<fileName>
Key | Required | Description |
---|---|---|
prefix | yes | Tells Linkerd to resolve the request path using the fs namer. |
fileName | yes | The file in rootDir to use when resolving this request. |
ZooKeeper ServerSets service discovery
kind: io.l5d.serversets
ServerSets Configuration
Example ServerSets configuration:
namers:
- kind: io.l5d.serversets
zkAddrs:
- host: 127.0.0.1
port: 2181
Then reference the namer in the dtab to use it:
dtab: |
/svc => /#/io.l5d.serversets/discovery/prod;
Linkerd provides support for ZooKeeper ServerSets.
Key | Default Value | Description |
---|---|---|
prefix | io.l5d.serversets |
Resolves names with /#/<prefix> . |
zkAddrs | required | A list of ZooKeeper addresses, each of which have host and port parameters. |
ServerSets Path Parameters
Dtab Path Format:
/#/<prefix>/<zkHosts>/<zkPath>[:<endpoint>]
Key | Required | Description |
---|---|---|
prefix | yes | Tells Linkerd to resolve the request path using the serversets namer. |
zkHosts | yes | The ZooKeeper host to use for this request. |
zkPath | yes | The ZooKeeper path to use for this request. |
endpoint | no | The ZooKeeper endpoint to use for this request. |
Consul service discovery
kind: io.l5d.consul
Consul Configuration
Configure a consul namer:
namers:
- kind: io.l5d.consul
host: 127.0.0.1
port: 2181
includeTag: true
useHealthCheck: true
setHost: true
consistencyMode: stale
Then reference the namer in the dtab to use it:
dtab: |
/svc => /#/io.l5d.consul/dc1/prod;
linker provides support for service discovery via Consul.
Key | Default Value | Description |
---|---|---|
prefix | io.l5d.consul |
Resolves names with /#/<prefix> . |
host | localhost |
The Consul host. |
port | 8500 |
The Consul port. |
includeTag | false |
If true , read a Consul tag from the path. |
useHealthCheck | false |
If true , exclude app instances that are failing Consul health checks. Even if false , linkerd’s built-in resiliency algorithms will still apply. |
token | no authentication | The auth token to use when making API calls. |
setHost | false |
If true , HTTP requests resolved by Consul will have their Host header overwritten to ${serviceName}.service.${datacenter}.${domain} . $domain is fetched from Consul. |
consistencyMode | default |
Select between Consul API consistency modes such as default , stale and consistent . |
failFast | false |
If false , disable fail fast and failure accrual for Consul client. Keep it false when using a local agent but change it to true when talking directly to an HA Consul API. |
preferServiceAddress | true |
If true use the service address if defined and default to the node address. If false always use the node address. |
Consul Path Parameters
Dtab Path Format when includeTag is false
/#/<prefix>/<datacenter>/<serviceName>
Dtab Path Format when includeTag is true
/#/<prefix>/<datacenter>/<tag>/<serviceName>
Key | Required | Description |
---|---|---|
prefix | yes | Tells Linkerd to resolve the request path using the consul namer. |
datacenter | yes | The Consul datacenter to use for this request. It can have a value .local (otherwise invalid datacenter name from Consul’s perspective) in order to reference a datacenter of the agent namer is connected to. |
tag | yes if includeTag is true |
The Consul tag to use for this request. |
serviceName | yes | The Consul service name to use for this request. |
Kubernetes service discovery
kind : io.l5d.k8s
K8s Configuration
Configure a K8s namer
namers:
- kind: io.l5d.k8s
host: localhost
port: 8001
labelSelector: version
Then reference the namer in the dtab to use it:
dtab: |
/svc => /#/io.l5d.k8s/prod/http;
Linkerd provides support for service discovery via Kubernetes.
Key | Default Value | Description |
---|---|---|
prefix | io.l5d.k8s |
Resolves names with /#/<prefix> . |
host | localhost |
The Kubernetes master host. |
port | 8001 |
The Kubernetes master port. |
labelSelector | none | The key of the label to filter services. |
K8s Path Parameters
Dtab Path Format
/#/<prefix>/<namespace>/<port-name>/<svc-name>[/<label-value>]
Key | Required | Description |
---|---|---|
prefix | yes | Tells Linkerd to resolve the request path using the k8s namer. |
namespace | yes | The Kubernetes namespace. |
port-name | yes | The port name or port number. |
svc-name | yes | The name of the service. |
label-value | yes if labelSelector is defined |
The value used to filter services. |
K8s External Configuration
Configure a K8s External namer
namers:
- kind: io.l5d.k8s.external
experimental: true
host: localhost
port: 8001
labelSelector: version
Then reference the namer in the dtab to use it:
dtab: |
/svc => /#/io.l5d.k8s.external/prod/http;
The Kubernetes External namer looks up the IP of the external load balancer for the given service on the given port. This can be used by Linkerd instances running outside of k8s to route to services running in k8s.
Key | Default Value | Description |
---|---|---|
prefix | io.l5d.k8s.external |
Resolves names with /#/<prefix> . |
experimental | required | Because this namer is still considered experimental, you must set this to true to use it. |
host | localhost |
The Kubernetes master host. |
port | 8001 |
The Kubernetes master port. |
labelSelector | none | The key of the label to filter services. |
K8s External Path Parameters
Dtab Path Format
/#/<prefix>/<namespace>/<port-name>/<svc-name>[/<label-value>]
Key | Required | Description |
---|---|---|
prefix | yes | Tells Linkerd to resolve the request path using the k8s external namer. |
namespace | yes | The Kubernetes namespace. |
port-name | yes | The port name. |
svc-name | yes | The name of the service. |
label-value | yes if labelSelector is defined |
The label value used to filter services. |
Marathon service discovery
kind: io.l5d.marathon
Marathon Configuration
Configure a marathon namer
namers:
- kind: io.l5d.marathon
prefix: /io.l5d.marathon
host: marathon.mesos
port: 80
uriPrefix: /marathon
ttlMs: 5000
useHealthCheck: false
Then reference the namer in the dtab to use it:
dtab: |
/marathonId => /#/io.l5d.marathon;
/host => /$/io.buoyant.http.domainToPathPfx/marathonId;
/svc => /host;
Linkerd provides support for service discovery via Marathon.
Key | Default Value | Description |
---|---|---|
prefix | io.l5d.marathon |
Resolves names with /#/<prefix> . |
host | marathon.mesos |
The Marathon master host. |
port | 80 |
The Marathon master port. |
uriPrefix | none | The Marathon API prefix. This prefix depends on your Marathon configuration. For example, running Marathon locally, the API is available at localhost:8080/v2/ , while the default setup on AWS/DCOS is $(dcos config show core.dcos_url)/marathon/v2/apps . |
ttlMs | 5000 |
The polling interval in milliseconds against the Marathon API. |
useHealthCheck | false |
If true , exclude app instances that are failing Marathon health checks. Even if false , linkerd’s built-in resiliency algorithms will still apply. |
Marathon Path Parameters
Dtab Path Format
/#/<prefix>/<appId>
Key | Required | Description |
---|---|---|
prefix | yes | Tells Linkerd to resolve the request path using the marathon namer. |
appId | yes | The app id of a marathon application. This id can be multiple path segments long. For example, the app with id “/users” can be reached with /#/io.l5d.marathon/users . Likewise, the app with id “/appgroup/usergroup/users” can be reached with /#/io.l5d.marathon/appgroup/usergroup/users . |
Marathon Authentication
Example DCOS environment variable
{
"login_endpoint": "https://leader.mesos/acs/api/v1/auth/login",
"private_key": "<private-key-value>",
"scheme": "RS256",
"uid": "service-acct"
}
Example basic HTTP authentication variable
dXNlcm5hbWU6cGFzc3dvcmQ=
The Marathon namer supports loading authentication data from an environment variable for DCOS private key in the DCOS_SERVICE_ACCOUNT_CREDENTIAL
variable and standalone Marathon basic HTTP authentication in the MARATHON_HTTP_AUTH_CREDENTIAL
environment variable. If both are provided the DCOS_SERVICE_ACCOUNT_CREDENTIAL
takes precedence.
Basic authentication token is base64 encoded and should not include the Basic
prefix, only in the format username:password
.
Further reading:
- Mesosphere DCOS Authentication Docs
- Marathon basic HTTP Authentication Docs
- Mesosphere Universe Repo
ZooKeeper Leader
kind: io.l5d.zkLeader
ZK Leader Configuration
A namer backed by ZooKeeper leader election.
Key | Default Value | Description |
---|---|---|
prefix | io.l5d.zkLeader |
Resolves names with /#/<prefix> . |
zkAddrs | required | A list of ZooKeeper addresses, each of which have host and port parameters. |
ZK Leader Path Parameters
Dtab Path Format
/#/<prefix>/<zkPath>
Key | Required | Description |
---|---|---|
prefix | yes | Tells Linkerd to resolve the request path using the marathon namer. |
zkPath | yes | The ZooKeeper path of a leader group. This path can be multiple path segments long. The namer resolves to the address stored in the data of the leader. |
Curator
kind: io.l5d.curator
Curator Configuration
A namer that uses the Curator discovery library to resolve names.
Note: If you have registered Curator services with a custom payload object, that class file must be on the classpath. Otherwise you will get a java.lang.IllegalArgumentException: Invalid type id '<some-payload-class'
error.
Key | Default Value | Description |
---|---|---|
prefix | io.l5d.curator |
Resolves names with /#/<prefix> . |
experimental | required | Because this namer is still considered experimental, you must set this to true to use it. |
zkAddrs | required | A list of ZooKeeper addresses, each of which have host and port parameters. |
basePath | / |
The ZooKeeper path for Curator discovery. |
Curator Path Parameters
Dtab Path Format
/#/<prefix>/<serviceName>
Key | Required | Description |
---|---|---|
prefix | yes | Tells Linkerd to resolve the request path using the curator namer. |
serviceName | yes | The name of the Curator service to lookup in ZooKeeper. |
Rewrite
kind: io.l5d.rewrite
Rewrite Configuration
Example rewrite configuration:
namers:
- kind: io.l5d.rewrite
pattern: "/{service}/api"
name: "/srv/{service}"
Then reference the namer in the dtab to use it:
dtab: |
/svc => /#/io.l5d.rewrite
A namer that completely rewrites a path. This is useful to do arbitrary reordering of the path segments that is not possible using standard prefix replacement. While this is a general purpose tool for reordering path segments, it cannot be used to modify or split individual segments (for modification or splitting of individual segments, see the rewriting namers section below).
If the name matches the pattern in the config, it will be replaced by the name in the config. Additionally, any variables in the pattern will capture the value of the matching path segment and may be used in the final name.
Key | Default Value | Description |
---|---|---|
prefix | io.l5d.rewrite |
Resolves names with /#/<prefix> . |
pattern | required | If the name matches this prefix, replace it with the name configured in the name parameter. Wildcards and variable capture are allowed (see: io.buoyant.namer.util.PathMatcher ). |
name | required | The replacement name. Variables captured in the pattern may be used in this string. |
Rewrite Path Parameters
Dtab Path Format
/#/<prefix> [/ *name ]
Key | Required | Description |
---|---|---|
prefix | yes | Tells Linkerd to resolve the request path using the rewrite namer. |
name | yes | Attempt to match this name against the pattern and replace it with the configured name. |
Rewriting Namers
In addition to service discovery namers, Linkerd supplies a number of utility
namers. These namers assist in path rewriting when the transformation is more
complicated than just prefix substitution. They are prefixed with /$/
instead
of /#/
, and can be used without explicitly adding them to the
namers
section of the config.
domainToPathPfx
/marathonId => /#/io.l5d.marathon;
/host => /$/io.buoyant.http.domainToPathPfx/marathonId;
/svc => /host;
Dtab Path Format
/$/io.buoyant.http.domainToPathPfx/<prefix>/<host>
Rewrites the path’s prefix with <prefix>
first, followed by each subdomain of
<host>
separated and in reverse order.
For example,
/$/io.buoyant.http.domainToPathPfx/pfx/foo.buoyant.io/resource/name
would be
rewritten to /pfx/io/buoyant/foo/resource/name
.
subdomainOfPfx
/consulSvc => /#/io.l5d.consul/.local
/host => /$/io.buoyant.http.subdomainOfPfx/service.consul/consulSvc;
/svc => /host;
Dtab Path Format
/$/io.buoyant.http.subdomainOfPfx/<domain>/<prefix>/<host>
Rewrites the path’s prefix with <prefix>
first, followed by <host>
with the
<domain>
dropped.
For example,
/$/io.buoyant.http.subdomainOfPfx/buoyant.io/pfx/foo.buoyant.io/resource/name
would be rewritten to /pfx/foo/resource/name
hostportPfx
/ip-hostport => /$/inet;
/svc => /$/io.buoyant.hostportPfx/ip-hostport;
Dtab Path Format
/$/io.buoyant.hostportPfx/<prefix>/<host>:<port>/etc
Rewrites a name of the form “host:ip” as a path with host followed by ip. Does not not support IPv6 host IPs (because ipv6 notation doesn’t work in Paths as- is, due to bracket characters).
For example,
/$/io.buoyant.hostportPfx/pfx/host:port/etc
would be rewritten to /pfx/host/port/etc
.
porthostPfx
/k8s-porthost => /#/io.l5d.k8s/default;
/svc => /$/io.buoyant.porthostPfx/k8s-porthost;
Dtab Path Format
/$/io.buoyant.porthostPfx/<prefix>/<host>:<port>/etc
Rewrites a name of the form “host:ip” as a path with ip followed by host. Does not not support IPv6 host IPs (because ipv6 notation doesn’t work in Paths as- is, due to bracket characters).
For example,
/$/io.buoyant.porthostPfx/pfx/host:port/etc
would be rewritten to /pfx/port/host/etc
.
Telemetry
A telemeter may receive stats and trace annotations, i.e. to send to a collector
or export. Telemetry data can be collected and exported from a Linkerd process by
configuring telemeters via a top-level telemetry
section.
Key | Default Value | Description |
---|---|---|
kind | required | Either io.l5d.prometheus , io.l5d.statsd , io.l5d.tracelog , io.l5d.recentRequests , or io.l5d.zipkin . |
experimental | false |
Set this to true to enable the telemeter if it is experimental. |
Prometheus
Example Prometheus config
telemetry:
- kind: io.l5d.prometheus
kind: io.l5d.prometheus
Exposes admin endpoints:
/admin/metrics/prometheus
: retrieve all metrics in Prometheus format
This telemeter has no additional parameters.
InfluxDB
Example InfluxDB config
telemetry:
- kind: io.l5d.influxdb
kind: io.l5d.influxdb
This telemeter is intended for collection by
Telegraf. Each measurement will have a
host
tag, set from the Host
header on the collector’s incoming request.
Recommended Telegraf configuration is using inputs.exec
plugin with
curl -s http://[LINKERD_IP]/admin/metrics/influxdb
.
Exposes admin endpoints:
/admin/metrics/influxdb
: retrieve all metrics in InfluxDB LINE protocol format
This telemeter has no additional parameters.
StatsD (experimental)
Example StatD config
telemetry:
- kind: io.l5d.statsd
experimental: true
prefix: linkerd
hostname: 127.0.0.1
port: 8125
gaugeIntervalMs: 10000
sampleRate: 1.0
kind: io.l5d.statsd
StatsD metrics exporting. This telemeter connects to a given StatsD server via UDP. Counters and timers/histograms are exported immediately, based on sample rate. Gauge export interval is configurable.
Key | Default Value | Description |
---|---|---|
experimental | required | Because this telemeter is still considered experimental, you must set this to true to use it. |
prefix | linkerd |
String to prefix all exported metric names with. |
hostname | 127.0.0.1 |
Hostname of the StatsD server. |
port | 8125 |
Port of the StatsD server. |
gaugeIntervalMs | 10000 |
Interval to export Gauges, in milliseconds. |
sampleRate | 0.01 |
Sample rate to export counter and timing/histogram events. Higher values will result in higher Linkerd latency. |
TraceLog
Example TraceLog config
telemetry:
- kind: io.l5d.tracelog
sampleRate: 0.2
level: TRACE
kind: io.l5d.tracelog
Log all tracing data, given a log-level and sample rate.
Key | Default Value | Description |
---|---|---|
host | localhost |
Host to send trace data to. |
sampleRate | 1.0 |
What percentage of traces to log. |
level | INFO |
Log-level, one of: ALL , CRITICAL , DEBUG , ERROR , FATAL , INFO , OFF , TRACE , WARNING . For full details, see com.twitter.logging.Level. |
Recent Requests
Example Recent Requests config
telemetry:
- kind: io.l5d.recentRequests
sampleRate: 1.0
capacity: 10
kind: io.l5d.recentRequests
The recent requests telemeter keeps an in-memory record of recent requests and uses it to populate
the recent requests table on the admin dashboard. This table can be viewed at /requests
on the
admin port. Recording requests can have an impact on Linkerd performance so make sure to set a
sample rate that is appropriate for your level of traffic.
Key | Default Value | Description |
---|---|---|
sampleRate | required | What percentage of traces to record. |
capacity | 10 | The maximum number of recent traces to store |
Zipkin telemeter
Example zipkin config
telemetry:
- kind: io.l5d.zipkin
host: localhost
port: 9410
sampleRate: 0.02
kind: io.l5d.zipkin
Finagle’s zipkin-tracer. Use this telemeter to send trace data to a Zipkin Scribe collector.
Key | Default Value | Description |
---|---|---|
host | localhost |
Host to send trace data to. |
port | 9410 |
Port to send trace data to (must be the Scribe collector port). |
sampleRate | 0.001 |
What percentage of requests to trace. |
Announcers
An announcer registers servers in service discovery. Each server may specify a list of concrete names to announce as in the announce server key. Each announcer has a prefix and will only announce names that begin with that prefix.
Key | Default Value | Description |
---|---|---|
kind | required | Only io.l5d.serversets is available at this time. |
prefix | kind-specific | Announces names beginning with /#/<prefix> . |
Serversets
kind: io.l5d.serversets
Announce to ZooKeeper using the serverset format.
Key | Default Value | Description |
---|---|---|
prefix | io.l5d.serversets |
Announces names beginning with /#/<prefix> . |
zkAddrs | required | A list of ZooKeeper addresses, each of which have host and port parameters. |
pathPrefix | /discovery |
The ZooKeeper path under which services should be registered. |