← Back to DevBytes

Linkerd Service Mesh: Complete Setup and Configuration Guide

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

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

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.

πŸš€ Need a reliable AI agent for your project?

Deploy Hermes Agent in 10 minutes. Managed hosting, zero DevOps.

Get Started β€” $23.99/mo
← Back to all articles