Linkerd 2.0: Rust Rewrite & Kubernetes-Native Service Mesh

Linkerd 2.0: Rust Rewrite & Kubernetes-Native Service Mesh

Introduction

On September 18, 2018, Buoyant released Linkerd 2.0, a complete architectural rewrite of the service mesh. Moving from a Finagle-based DaemonSet model to a Rust-powered sidecar architecture, Linkerd 2.0 prioritized performance, simplicity, and Kubernetes-native operations.

The shift from Linkerd 1.x to 2.0 wasn’t just an upgrade—it was a fundamental reimagining. Where 1.x used a DaemonSet (one proxy per node), 2.0 adopted sidecars (one proxy per pod). Where 1.x used complex dtab routing, 2.0 used Kubernetes Service objects directly. The result: a service mesh that felt native to Kubernetes, not bolted on.


Architectural Changes

From DaemonSet to Sidecar

  • 1.x Model: Single Linkerd proxy per node handled all traffic, requiring complex routing rules.
  • 2.0 Model: Each pod gets its own linkerd-proxy sidecar, providing isolation and simpler configuration.
  • Benefits: Better resource isolation, per-pod metrics, and alignment with Kubernetes pod model.

From Finagle to Rust

  • Performance: Rust’s zero-cost abstractions and memory safety deliver lower latency and CPU usage.
  • Resource Footprint: Linkerd 2.0 proxies use ~10MB memory vs. 1.x’s JVM overhead.
  • Startup Time: Rust binaries start in milliseconds, not seconds.

Key Features

  1. Automatic mTLS: Transparent mutual TLS encryption between services without certificate management.
  2. Automatic Retries: Configurable retry budgets with exponential backoff.
  3. Request-Level Load Balancing: Routes to healthy endpoints with automatic failover.
  4. Observability: Built-in metrics, distributed tracing, and service topology visualization.
  5. Kubernetes-Native Config: Uses Kubernetes Services, no custom routing language.

Control Plane Components

  • linkerd-controller: Manages service discovery and routing configuration.
  • linkerd-identity: Issues and validates mTLS certificates using Kubernetes ServiceAccounts.
  • linkerd-proxy-injector: Mutating webhook automatically injects sidecars into pods.
  • linkerd-web: Web UI for service topology and metrics visualization.

Getting Started

Install Linkerd 2.0:

curl -sL https://run.linkerd.io/install | sh
linkerd install | kubectl apply -f -
linkerd check

Enable automatic sidecar injection:

kubectl annotate namespace default linkerd.io/inject=enabled

Deploy a workload:

kubectl apply -f https://run.linkerd.io/emojivoto.yml

View the dashboard:

linkerd dashboard

Why the Rewrite Mattered

  • Performance: Rust’s performance characteristics made Linkerd competitive with C++-based proxies like Envoy.
  • Simplicity: Kubernetes-native configuration eliminated the learning curve of dtab routing.
  • Resource Efficiency: Lower memory and CPU usage made Linkerd viable for resource-constrained environments.
  • CNCF Alignment: The rewrite positioned Linkerd for CNCF contribution and broader adoption.

Comparison: Linkerd 1.x vs 2.0

AspectLinkerd 1.xLinkerd 2.0
DeploymentDaemonSetSidecar
LanguageScala/FinagleRust
Configurationdtab routingKubernetes Services
Resource UsageHigher (JVM)Lower (native binary)
IsolationPer-nodePer-pod
ComplexityHigherLower

Operational Improvements

  • Automatic Injection: Mutating webhook eliminates manual sidecar configuration.
  • Health Checks: Built-in liveness/readiness probes for proxies and control plane.
  • Upgrade Strategy: linkerd upgrade command simplifies control plane updates.
  • Observability: Prometheus metrics and Grafana dashboards included out of the box.

Use Cases

  • Zero-Trust Networking: Automatic mTLS provides encryption without application changes.
  • Canary Deployments: Traffic splitting via Service objects enables gradual rollouts.
  • Multi-Cluster: Linkerd 2.0 can span multiple clusters with shared identity.
  • Edge Computing: Low resource footprint makes Linkerd suitable for edge deployments.

Migration from Linkerd 1.x

  • Not a Drop-in Replacement: 1.x and 2.0 are architecturally different; plan for migration.
  • Configuration Translation: dtab rules need to be re-expressed as Kubernetes Services.
  • Gradual Migration: Run both versions in parallel, migrating services namespace by namespace.
  • Community Support: Linkerd 1.x remains supported but 2.0 is the future.

Common Gotchas

  • Sidecar Resource Limits: Set appropriate CPU/memory limits for linkerd-proxy containers.
  • Init Container Timing: Linkerd’s init container configures iptables; ensure it completes before app starts.
  • mTLS Compatibility: Some tools (e.g., kubectl port-forward) may not work with mTLS; use linkerd tap instead.
  • Service Discovery: Linkerd 2.0 relies on Kubernetes Service endpoints; ensure Services are correctly configured.

Looking Ahead

Linkerd 2.0’s architecture set the foundation for:

  • CNCF Graduation (2019): Linkerd became the first graduated service mesh project.
  • Performance Improvements: Continued Rust optimizations and eBPF integration.
  • Policy Engine: Introduction of Service Profiles for advanced traffic management.
  • Multi-Cluster Support: Enhanced capabilities for spanning multiple Kubernetes clusters.

Summary

AspectDetails
Release DateSeptember 18, 2018
Key InnovationsRust rewrite, sidecar model, Kubernetes-native configuration
SignificanceReimagined service mesh architecture for performance and simplicity

Linkerd 2.0 proved that service meshes could be both powerful and simple. By embracing Kubernetes-native patterns and Rust’s performance, it created a service mesh that felt like a natural extension of Kubernetes, not a complex overlay. This architectural shift influenced the entire service mesh ecosystem and positioned Linkerd as a leading choice for teams prioritizing simplicity and performance.