
Today, we’re thrilled to announce Linkerd version 1.0. A little more than one year from our initial launch, Linkerd is part of the Cloud Native Computing Foundation and has a thriving community of contributors and users. Adopters range from startups like Monzo, which is disrupting the UK banking industry, to high scale Internet companies like Paypal, Ticketmaster, and Credit Karma, to companies that have been in business for hundreds of years like Houghton Mifflin Harcourt.
A 1.0 release is a meaningful milestone for any open source project. In our case, it’s a recognition that we’ve hit a stable set of features that our users depend on to handle their most critical production traffic. It also signals a commitment to limiting breaking configuration changes moving forward.
It’s humbling that our little project has amassed such an amazing group of operators and developers. I’m continually stunned by the features and integrations coming out of the Linkerd community; and there’s simply nothing more satisfying than hearing how Linkerd is helping teams do their jobs with a little less fear and uncertainty.
THE SERVICE MESH
Linkerd is a *service mesh* for cloud native applications. As part of this release, we wanted to define what this actually meant. My cofounder William Morgan has a writeup in another post we released today, What’s a service mesh? And why do I need one?
NEW FEATURES
Beyond stability and performance improvements, Linkerd 1.0 has a couple new features worth talking about.
This release includes a substantial change to the way that routers are configured in Linkerd. New plugin interfaces have been introduced to allow for much finer-grained policy control.
PER-SERVICE CONFIGURATION
There is a new section in the router config called service where service-level parameters may be configured. This parallels the client sections where client-level parameters are configured. The current parameters that can be specified in the service section are:
totalTimeoutMsretriesresponseClassifierrouters: - protocol: http service: totalTimeoutMs: 200 retries: budget: minRetriesPerSec: 5 percentCanRetry: 0.5 ttlSecs: 15 backoff: kind: jittered minMs: 10 maxMs: 10000 responseClassifier: kind: io.l5d.http.retryableRead5XX
With this change, a router now has three main subsections:
servers— where the router listens for incoming requestsservice— the logical destination of the request based on the identifierclient— where the router sends outgoing requests to concrete destinations
PER-CLIENT CONFIGURATION
Prior to version 1.0 any client configuration such as timeouts or TLS would apply globally to all clients. We now support the ability to configure clients in a more granular way by specifying kind: io.l5d.static in the client section and providing a list of configs. For example:
routers:
- protocol: http
client:
kind: io.l5d.static
configs:
- prefix: /
requestAttemptTimeoutMs: 1000
failFast: true
- prefix: /#/io.l5d.k8s/default/http/hello
requestAttemptTimeoutMs: 300
- prefix: /#/io.l5d.k8s/default/http/world
failureAccrual:
kind: none
failFast: falseEach item in the list of configs must specify a prefix and some parameters. Those parameters will apply to all clients with an id that matches the prefix. In the example above, the first config with prefix / applies to all clients. The next two configs apply to the hello and world clients respectively. If a client matches more than one config, all matching configs will be applied with configs later in the file taking precedence over earlier ones. For example, the hello client overrides the requestAttemptTimeoutMsproperty to 300 whereas the world client inherits the 1000 value from the first config.
If you don’t specify kind: io.l5d.static then kind: io.l5d.global will be assumed and you can specify client configuration directly on the client object which will apply globally to all clients.
routers:
- protocol: http
client:
requestAttemptTimeoutMs: 1000
failFast: trueThis same fine-grained level of control applies to the new service section as well. In the service configs, the prefix is compared to the service name i.e. the name produced by the identifier (which typically starts with /svc).
routers:
- protocol: http
service:
kind: io.l5d.static
configs:
- prefix: /svc
totalTimeout: 1000
responseClassifier:
kind: io.l5d.http.retryableRead5XX
- prefix: /svc/hello
responseClassifier:
kind: io.l5d.http.nonRetryable5XX
- prefix: /svc/world
totalTimeout: 300UPGRADING GUIDE
There are a couple changes you’ll have to make to your config files to move from pre-1.0 to 1.0.
IDENTIFIER KINDS
The following identifier kinds have been renamed for consistency:
- The
io.l5d.headerTokenid has been renamed toio.l5d.header.token. - The
io.l5d.headerPathid has been renamed toio.l5d.header.path. - The
io.l5d.h2.ingressid has been renamed toio.l5d.ingress. - The
io.l5d.http.ingressid has been renamed toio.l5d.ingress.
RESPONSE CLASSIFIER KINDS
The following response classifier kinds have been renamed for consistency:
- The
io.l5d.nonRetryable5XXid has been renamed toio.l5d.http.nonRetryable5XX. - The
io.l5d.retryableRead5XXid has been renamed toio.l5d.http.retryableRead5XX. - The
io.l5d.retryableIdempotent5XXid has been renamed toio.l5d.http.retryableIdempotent5XX.
CLIENT AND SERVICE PARAMETERS
The following parameter have moved or been renamed:
failFastmoved from router to clientresponseClassifiermoved from router to serviceretriesmoved from client to servicetimeoutMsmoved from router torequestAttemptTimeoutMsin clienttotalTimeoutMsin service
TIMEOUTS
The timeoutMs property has been split into two properties, requestAttemptTimeoutMswhich is configured in the client section and totalTimeoutMs which is configured in the service section.
requestAttemptTimeoutMs configures the timeout for each individual request or retry. As soon as this timeout is exceeded, the current attempt is canceled. If the request is retryable and the retry budget is not empty, a retry will be attempted with a fresh timeout.
totalTimeoutMs configures the total timeout for the request and all retries. A running timer is started when the first request is attempted and continues running if the request is retried. Once this timeout is exceeded, the request is canceled and no more retries may be attempted.
TLS
The client TLS section no longer has a kind parameter and instead can simply be configured with these 3 parameters:
| 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 |
Fine-grained client configuration can be used to only configure TLS for certain clients. Furthermore, segments from the prefix can be captured into variables and used in the commonName. For example:
routers:
- protocol: http
client:
kind: io.l5d.static
configs:
- prefix: /#/io.l5d.k8s/default/http/{service}
tls:
commonName: '{service}.linkerd.io'METRICS
The following metrics scopes have changed names. You will need to update any consumers of these metrics such as dashboards or alerts.
rt/*/dst/idhas changed tort/*/servicert/*/dst/pathhas changed tort/*/clientrt/*/dst/id/*/pathhas changed tort/*/client/*/servicert/*/srvhas changed tort/*/server
These three metrics scopes (server, service, client) mirror the three main subsections of the router config (servers, service, client).
TRACE ANNOTATIONS
The following trace annotations have changed names:
dst.idhas changed toclientdst.pathhas changed toresidualnamer.pathhas changed toservice
HTTP HEADERS
The following outgoing request headers have changed names:
l5d-dst-logicalhas changed tol5d-dst-servicel5d-dst-concretehas changed tol5d-dst-client
THANKS
Linkerd is only possible thanks to the community of amazing people around it. I’d like to thank everyone who helps in the Linkerd Slack, files issues, and contributes pull requests. The 1.0 release was made possible by contributions from Amédée d’Aboville, Zack Angelo, Ian Macalinao, Alexander Pakulov, Jordan Taylor, and users like you!


