< Home

Announcing Linkerd 1.0

Oliver Gould 25 April 2017

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:

routers:
- 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:

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: false

Each 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 requestAttemptTimeoutMs property 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: true

This 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: 300

Upgrading 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:

Response Classifier kinds

The following response classifier kinds have been renamed for consistency:

Client and Service Parameters

The following parameter have moved or been renamed:

Timeouts

The timeoutMs property has been split into two properties, requestAttemptTimeoutMs which 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.

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:

HTTP Headers

The following outgoing request headers have changed names:

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!

Share this post on Hacker News.

< Home