What is Linkerd?
Linkerd is an open-source, cloud-native service mesh designed for Kubernetes. It provides a dedicated infrastructure layer that transparently handles service-to-service communication, adding critical capabilities like reliability, security, and observability without requiring changes to application code. Unlike many other service meshes, Linkerd is built with a strong focus on simplicity, performance, and minimal operational overhead.
Key Features
- Zero-config mTLS β automatically encrypts all communication between meshed services.
- Automatic retries and timeouts β improves reliability with minimal configuration.
- Traffic-aware load balancing β uses real-time latency metrics to route requests intelligently.
- Built-in observability β provides golden metrics (success rate, latency, request volume) out of the box.
- Lightweight Rust-based proxies β extremely low CPU and memory footprint compared to Envoy-based meshes.
- Easy injection and removal β add or remove the mesh from a pod with a single annotation or CLI command.
- Service Profiles β enable per-route metrics, retries, and timeouts.
Why Linkerd Matters
π Deploy your AI agent in 10 minutes
Managed Hermes hosting. Zero DevOps. 100M tokens/mo included.
Try it free →In modern microservice architectures, the network becomes a critical dependency. Developers face challenges such as cascading failures, latency spikes, unauthorized access, and lack of visibility into service health. A service mesh like Linkerd addresses these issues at the platform level rather than requiring each team to implement custom resilience logic. Linkerd matters because it delivers production-grade reliability, security, and observability with a fraction of the complexity and resource consumption of alternatives like Istio. Its "zero configuration" philosophy means you can install it, inject it into your services, and immediately see results β no YAML gymnastics required.
Prerequisites and Setup
Before installing Linkerd, you need a working Kubernetes cluster (version 1.16 or later, though 1.21+ is recommended) and kubectl configured to talk to it. Youβll also need the Linkerd CLI (linkerd) on your local machine. The CLI is the primary tool for installation, verification, and mesh interaction.
Installing the Linkerd CLI
The easiest way to install the CLI is via the official script:
curl --proto '=https' --tlsv1.2 -sSfL https://run.linkerd.io/install | sh
Or, if you prefer Homebrew:
brew install linkerd
After installation, verify the CLI works and check your cluster compatibility:
linkerd version
linkerd check --pre
The linkerd check --pre command validates that your Kubernetes cluster meets all requirements (RBAC enabled, correct API versions, etc.) and will give you specific actions to fix any issues.
Cluster Validation
Run the pre-install checks to ensure everything is ready:
linkerd check --pre
Look for all checks passing with green status. Common issues include missing cluster-admin permissions or unsupported Kubernetes versions β the output will tell you exactly what to fix.
Installing the Linkerd Control Plane
The Linkerd control plane is a set of Kubernetes deployments and services that manage the mesh. Installation is a two-step process: first install the Custom Resource Definitions (CRDs), then deploy the control plane components.
Install CRDs
Install the Linkerd CRDs (ServiceProfile, etc.) on the cluster:
linkerd install --crds | kubectl apply -f -
This step is idempotent and safe to run multiple times.
Deploy the Control Plane
Now install the control plane into the linkerd namespace (or a custom namespace if you prefer). The default installation uses self-signed certificate authority for mTLS:
linkerd install | kubectl apply -f -
You can also customize the installation with flags like --cluster-domain, --identity-trust-domain, or provide your own CA certificates for production setups.
Verify the Installation
After applying the manifests, run the post-install check to ensure everything is healthy:
linkerd check
All checks should pass. You should see the control plane pods in the linkerd namespace:
kubectl get pods -n linkerd
Expected output includes the linkerd-destination, linkerd-proxy-injector, linkerd-identity, and linkerd-controller pods.
Injecting Linkerd into Your Services
To add a service to the mesh, you inject a Linkerd sidecar proxy into its pod. Linkerd supports multiple injection methods: manual CLI injection, automatic annotation-based injection, and namespace-wide injection.
Manual CLI Injection
The simplest way is to pipe your deployment manifest through the linkerd inject command:
kubectl get deploy my-app -o yaml | linkerd inject - | kubectl apply -f -
This adds the Linkerd sidecar container and init container to your pod spec. You can also inject YAML files directly:
linkerd inject deployment.yaml | kubectl apply -f -
Automatic Annotation Injection
Add the annotation linkerd.io/inject: enabled to your pod template. The Linkerd proxy injector webhook will automatically inject the sidecar when the pod is created:
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app
spec:
replicas: 3
selector:
matchLabels:
app: my-app
template:
metadata:
labels:
app: my-app
annotations:
linkerd.io/inject: enabled
spec:
containers:
- name: my-app
image: myapp:latest
ports:
- containerPort: 8080
Apply the deployment normally β the webhook does the rest.
Namespace-wide Injection
To inject all pods in a namespace, label the namespace:
kubectl label namespace my-namespace linkerd.io/inject=enabled
After labeling, every new pod created in that namespace will automatically get the Linkerd proxy. To remove automatic injection, change the label value to disabled or delete the label.
Verify Injection
After injecting, check that pods have two containers (the app and the linkerd-proxy):
kubectl get pods -n my-namespace -o jsonpath='{.items[*].spec.containers[*].name}'
You can also use the linkerd check command to verify data plane health.
Configuring Mutual TLS (mTLS)
By default, Linkerd enables mTLS for all meshed services. It automatically generates a trust anchor (root CA) and issues per-pod certificates via the identity component. This encrypts all TCP traffic between proxies and provides workload identity verification. No application changes are required.
To verify mTLS is working, use the linkerd edges command to see encrypted connections:
linkerd edges pods -n my-namespace
Output shows the TLS state, client and server identities, and the underlying service names.
Bringing Your Own CA (Production)
For production, you should provide your own root CA and intermediate CA. During installation, you pass the certificates to linkerd install using flags:
linkerd install \
--identity-trust-anchors-file ca.crt \
--identity-issuer-certificate-file issuer.crt \
--identity-issuer-key-file issuer.key \
| kubectl apply -f -
This ensures certificate rotation and trust domain configuration are under your control.
Observability with Linkerd Viz
Linkerd comes with an optional observability extension called linkerd-viz that provides pre-built dashboards, metrics, and tap capabilities. Install it after the control plane:
linkerd viz install | kubectl apply -f -
linkerd check
This deploys Prometheus, Grafana, a web dashboard, and the tap API. Access the dashboard via:
linkerd viz dashboard
The dashboard shows service-level golden metrics: success rate, request rate, and p95 latency. It also allows you to tap live requests to inspect headers and payloads.
Using Grafana
The Viz extension includes a pre-configured Grafana instance with dashboards for Linkerd control plane and data plane metrics. Access it by port-forwarding:
kubectl -n linkerd-viz port-forward svc/grafana 3000
You can also integrate with your existing Grafana/Prometheus stack by pointing them to the linkerd-prometheus service.
Tap and Live Traffic Inspection
Tap allows you to see real-time requests flowing through a specific pod or service:
linkerd tap pod my-app-7f4c9d6b-xqz9s -n my-namespace
You'll get a stream of request metadata: source, destination, path, latency, and response code. Tap is invaluable for debugging.
Traffic Management with Service Profiles
Service Profiles are custom resources that define per-route behavior for a service. They enable route-level metrics, retries, timeouts, and can be used for progressive delivery. Without a Service Profile, Linkerd only tracks service-level metrics. With one, you get granular insight into each HTTP route.
Creating a Service Profile
Create a YAML file defining routes for your service. For example, for a service called webapp:
apiVersion: linkerd.io/v1alpha2
kind: ServiceProfile
metadata:
name: webapp.namespace.svc.cluster.local
namespace: my-namespace
spec:
routes:
- condition:
method: GET
pathRegex: /api/v1/users
name: get-users
isFailure: false # marks successful HTTP 5xx as non-failure (optional)
responseCodes:
- 200
- 201
- condition:
method: POST
pathRegex: /api/v1/users
name: create-user
isFailure: false
- condition:
method: GET
pathRegex: /api/v1/products
name: get-products
- condition:
method: GET
pathRegex: /health
name: health-check
Apply it:
kubectl apply -f service-profile.yaml
Adding Retries and Timeouts
You can augment routes with retry policies and timeouts directly in the ServiceProfile:
apiVersion: linkerd.io/v1alpha2
kind: ServiceProfile
metadata:
name: webapp.namespace.svc.cluster.local
namespace: my-namespace
spec:
routes:
- condition:
method: GET
pathRegex: /api/v1/users
name: get-users
isFailure: false
timeout: 500ms
retryBudget:
retryRatio: 0.2
minRetriesPerSecond: 10
ttl: 10s
retry5XX: true
retryReadIdTimeout: 200ms
These settings are applied by the Linkerd proxy on the client side, so no application changes are needed. The retryBudget ensures retries donβt overwhelm the server during overload.
Best Practices for Production
- Start small and expand gradually. Mesh one namespace at a time, verify success rates and latency, then expand.
- Use namespace labeling for automatic injection. This reduces toil and ensures new deployments are always meshed.
- Bring your own CA for mTLS. The default self-signed CA is fine for testing, but for production, integrate with your PKI infrastructure and rotate certificates regularly.
- Deploy the Viz extension on a separate cluster or use existing observability stack. The bundled Prometheus/Grafana are convenient but not meant for long-term retention. Integrate with your production monitoring tools.
- Define Service Profiles for critical services. They give you route-level metrics and allow you to configure per-route timeouts and retries, improving resilience.
- Monitor proxy resource usage. Linkerd's micro-proxies are extremely lightweight (typically <10 MB RAM and near-zero CPU), but monitor them alongside your applications to detect anomalies.
- Use
linkerd checkregularly. This command validates mesh health, certificate expiry, and configuration drift. Integrate it into your CI/CD or monitoring. - Keep the control plane up to date. Linkerd releases are frequent and backward-compatible. Use
linkerd upgradeto update without downtime. - Disable injection for non-critical or batch jobs. Not every pod needs the mesh. Use the annotation
linkerd.io/inject: disabledon pods that donβt benefit from mTLS and metrics (like one-off scripts). - Test failover and retry behavior. Simulate pod failures and validate that retries and timeouts work as configured.
Conclusion
Linkerd brings enterprise-grade reliability, security, and observability to Kubernetes with unmatched simplicity. Its zero-config mTLS, automatic injection, and lightweight proxies make it an ideal choice for teams that want the benefits of a service mesh without the operational complexity. By following this guide β installing the CLI, deploying the control plane, injecting your services, and layering on observability and traffic management β you can transform your microservice architecture into a resilient, transparent, and secure system. The best practices outlined here will help you operate Linkerd confidently in production, giving you deep visibility and control over your service-to-service communication while keeping your applications focused on business logic.