# Linkerd Linkerd is an ultralight, security-first service mesh for Kubernetes that adds critical security, observability, and reliability features to your Kubernetes stack with no code change required. As a Cloud Native Computing Foundation (CNCF) graduated project, Linkerd provides automatic mTLS between meshed pods, intelligent load balancing, automatic retries, detailed traffic metrics, and powerful policy controls for your microservices. The Linkerd 2.x architecture consists of a control plane (installed via the `linkerd` CLI or Helm) and a data plane made up of ultralight Rust proxies injected as sidecars into your application pods. The control plane components include the destination controller for service discovery and routing, the identity controller for certificate management, and the proxy injector webhook. Extensions like `linkerd-viz` provide observability dashboards and metrics, while `linkerd-multicluster` enables cross-cluster communication. ## CLI Installation Commands ### linkerd install - Install Linkerd Control Plane The `install` command outputs Kubernetes manifests to install the Linkerd control plane. It generates CRDs and control plane resources that can be applied to your cluster using kubectl. ```bash # First, install the Custom Resource Definitions (CRDs) linkerd install --crds | kubectl apply -f - # Then install the core control plane linkerd install | kubectl apply -f - # Install with custom configuration using Helm values linkerd install \ --set proxy.resources.cpu.limit=500m \ --set proxy.resources.memory.limit=256Mi \ --set controllerReplicas=3 \ | kubectl apply -f - # Install with identity trust anchors from a file linkerd install \ --identity-trust-anchors-file ca.crt \ --identity-issuer-certificate-file issuer.crt \ --identity-issuer-key-file issuer.key \ | kubectl apply -f - # Install using a custom values file linkerd install --values custom-values.yaml | kubectl apply -f - # Generate installation YAML without applying (for GitOps) linkerd install --ignore-cluster -o yaml > linkerd-install.yaml ``` ### linkerd inject - Add Proxy Sidecar to Deployments The `inject` command adds the Linkerd proxy sidecar to Kubernetes workloads. It modifies pod specs to include the proxy container and init container for traffic interception. ```bash # Inject all deployments in a namespace kubectl get deploy -n my-app -o yaml | linkerd inject - | kubectl apply -f - # Inject a single deployment file linkerd inject deployment.yaml | kubectl apply -f - # Inject from a remote URL linkerd inject https://run.linkerd.io/emojivoto.yml | kubectl apply -f - # Inject an entire directory of Kubernetes manifests linkerd inject ./k8s/ | kubectl apply -f - # Inject with custom proxy configuration kubectl get deploy web -o yaml | linkerd inject - \ --proxy-cpu-request=100m \ --proxy-memory-request=64Mi \ --proxy-log-level=debug \ | kubectl apply -f - # Manual injection (includes proxy spec in output, bypasses auto-injector) linkerd inject --manual deployment.yaml | kubectl apply -f - # Inject with debug sidecar for troubleshooting linkerd inject --enable-debug-sidecar deployment.yaml | kubectl apply -f - # Inject with ingress mode for ingress controllers linkerd inject --ingress deployment.yaml | kubectl apply -f - ``` ### linkerd check - Validate Linkerd Installation The `check` command validates that Linkerd is correctly installed and configured. It runs a series of health checks on the control plane and optionally the data plane. ```bash # Run all default checks linkerd check # Run pre-installation checks before installing linkerd check --pre # Check only CRD installation linkerd check --crds # Check data plane proxies in a specific namespace linkerd check --proxy --namespace my-app # Check with custom timeout (useful for slow clusters) linkerd check --wait 10m # Output check results as JSON (for automation) linkerd check --output json # Check with CNI plugin mode linkerd check --pre --linkerd-cni-enabled # Expected output for healthy installation: # kubernetes-api # -------------- # √ can initialize the client # √ can query the Kubernetes API # # linkerd-existence # ----------------- # √ 'linkerd-config' config map exists # √ control plane replica sets are ready # √ no unschedulable pods # # Status check results are √ ``` ### linkerd upgrade - Upgrade Linkerd Installation The `upgrade` command generates Kubernetes manifests to upgrade an existing Linkerd installation while preserving configuration. ```bash # First upgrade CRDs linkerd upgrade --crds | kubectl apply -f - # Then upgrade the control plane linkerd upgrade | kubectl apply -f - # Upgrade with configuration changes linkerd upgrade \ --set proxy.resources.cpu.limit=1 \ --set controllerReplicas=3 \ | kubectl apply -f - # Upgrade from local manifests (offline upgrade) linkerd upgrade --from-manifests linkerd-backup.yaml | kubectl apply -f - # Force upgrade even with certificate warnings linkerd upgrade --force | kubectl apply -f - # After upgrade, prune removed resources linkerd prune | kubectl delete -f - ``` ### linkerd uninstall - Remove Linkerd from Cluster The `uninstall` command generates Kubernetes manifests to completely remove Linkerd from the cluster. ```bash # Uninstall Linkerd (will warn about injected pods) linkerd uninstall | kubectl delete -f - # Force uninstall even with injected workloads present linkerd uninstall --force | kubectl delete -f - # Output as JSON format linkerd uninstall -o json | kubectl delete -f - ``` ### linkerd uninject - Remove Proxy from Deployments The `uninject` command removes the Linkerd proxy sidecar from Kubernetes workloads. ```bash # Remove proxy from a deployment kubectl get deploy web -o yaml | linkerd uninject - | kubectl apply -f - # Uninject from a file linkerd uninject deployment.yaml | kubectl apply -f - # Uninject from a directory linkerd uninject ./k8s/ | kubectl apply -f - ``` ## Service Profile Commands ### linkerd profile - Generate Service Profiles Service profiles define per-route metrics, retries, and timeouts for services. The `profile` command generates ServiceProfile resources from OpenAPI specs, protobuf definitions, or templates. ```bash # Generate a basic service profile template linkerd profile --template -n emojivoto web-svc > web-svc-profile.yaml # Generate from OpenAPI/Swagger specification linkerd profile --open-api web-api.swagger -n emojivoto web-svc \ | kubectl apply -f - # Generate from protobuf definition linkerd profile --proto voting.proto -n emojivoto vote-svc \ | kubectl apply -f - # Generate offline (without cluster access) linkerd profile --template --ignore-cluster -n emojivoto web-svc # Output as JSON linkerd profile --template -n emojivoto web-svc -o json # Example ServiceProfile structure: # apiVersion: linkerd.io/v1alpha2 # kind: ServiceProfile # metadata: # name: web-svc.emojivoto.svc.cluster.local # namespace: emojivoto # spec: # routes: # - name: GET /api/vote # condition: # method: GET # pathRegex: /api/vote # responseClasses: # - condition: # status: # min: 500 # max: 599 # isFailure: true # retryBudget: # retryRatio: 0.2 # minRetriesPerSecond: 10 # ttl: 10s ``` ## Identity and Security Commands ### linkerd identity - Display Pod Certificates The `identity` command retrieves and displays the mTLS certificates used by meshed pods for authentication. ```bash # Get certificate from a specific pod linkerd identity web-7d9fd4b4c9-abc123 # Get certificates from pods matching a label selector linkerd identity -l app=web -n emojivoto # Get certificate from pod in specific namespace linkerd identity -n emojivoto web-7d9fd4b4c9-abc123 # Example output shows certificate details: # POD web-7d9fd4b4c9-abc123 (1 of 1) # # Certificate: # Data: # Version: 3 (0x2) # Serial Number: ... # Issuer: CN=identity.linkerd.cluster.local # Subject: CN=web.emojivoto.serviceaccount.identity.linkerd.cluster.local # Validity: # Not Before: ... # Not After: ... ``` ### linkerd authz - List Authorization Policies The `authz` command displays authorization policies that apply to a specific resource. ```bash # List authorizations for a deployment linkerd authz -n emojivoto deploy/web # List authorizations for a pod linkerd authz -n emojivoto pod/web-7d9fd4b4c9-abc123 # List authorizations for a service linkerd authz -n emojivoto svc/web-svc # Example output: # ROUTE SERVER AUTHORIZATION_POLICY SERVER_AUTHORIZATION # * web-server web-authz - # GET / web-server public-get - ``` ## Viz Extension Commands ### linkerd viz install - Install Observability Extension The viz extension provides dashboards, metrics, and traffic inspection capabilities. ```bash # Install the viz extension linkerd viz install | kubectl apply -f - # Install with custom Prometheus configuration linkerd viz install \ --set prometheus.enabled=true \ --set grafana.enabled=true \ | kubectl apply -f - # Install in high-availability mode linkerd viz install --ha | kubectl apply -f - # Uninstall viz extension linkerd viz uninstall | kubectl delete -f - ``` ### linkerd viz stat - Display Traffic Statistics The `stat` command shows real-time traffic statistics including success rates, request rates, and latency percentiles. ```bash # Get stats for all deployments in a namespace linkerd viz stat deployments -n emojivoto # Get stats for a specific deployment linkerd viz stat deploy/web -n emojivoto # Get stats for all namespaces linkerd viz stat namespaces # Get stats for pods linkerd viz stat pods -n emojivoto # Get stats with traffic direction (from/to) linkerd viz stat deploy/web --to deploy/voting -n emojivoto linkerd viz stat deploy/web --from deploy/emoji -n emojivoto # Get stats across all namespaces linkerd viz stat pods --all-namespaces # Filter by label selector linkerd viz stat pods -l app=web -n emojivoto # Custom time window linkerd viz stat deploy -n emojivoto --time-window 5m # Output as JSON linkerd viz stat deploy -n emojivoto -o json # Wide output with TCP stats linkerd viz stat deploy -n emojivoto -o wide # Example output: # NAME MESHED SUCCESS RPS LATENCY_P50 LATENCY_P95 LATENCY_P99 TCP_CONN # emoji 1/1 100.00% 2.0rps 1ms 1ms 1ms 3 # voting 1/1 85.71% 0.7rps 1ms 2ms 3ms 2 # web 1/1 100.00% 2.0rps 1ms 4ms 18ms 3 ``` ### linkerd viz tap - Live Traffic Stream The `tap` command provides real-time visibility into live requests flowing through the mesh. ```bash # Tap all traffic to a deployment linkerd viz tap deploy/web -n emojivoto # Tap with filter for specific destination linkerd viz tap ns/emojivoto --to deploy/voting # Filter by HTTP method linkerd viz tap deploy/web -n emojivoto --method GET # Filter by path prefix linkerd viz tap deploy/web -n emojivoto --path /api/ # Filter by authority header linkerd viz tap deploy/web -n emojivoto --authority voting-svc:8080 # Limit request rate linkerd viz tap deploy/web -n emojivoto --max-rps 10 # Output as JSON linkerd viz tap deploy/web -n emojivoto -o json # Wide output with additional metadata linkerd viz tap deploy/web -n emojivoto -o wide # Example output: # req id=0:0 proxy=in src=10.244.0.1:54321 dst=10.244.0.15:8080 tls=true :method=GET :authority=web-svc:8080 :path=/ # rsp id=0:0 proxy=in src=10.244.0.1:54321 dst=10.244.0.15:8080 tls=true :status=200 latency=1234µs # end id=0:0 proxy=in src=10.244.0.1:54321 dst=10.244.0.15:8080 tls=true duration=100µs response-length=1024B ``` ### linkerd viz top - Live Request Table The `top` command shows aggregated live request data in a table format. ```bash # Show top requests for a deployment linkerd viz top deploy/web -n emojivoto # Show top requests for all resources in namespace linkerd viz top all -n emojivoto # Hide successful requests (show only failures) linkerd viz top deploy/web -n emojivoto --hide-success # Show routes linkerd viz top deploy/web -n emojivoto --routes ``` ### linkerd viz dashboard - Open Web Dashboard The `dashboard` command opens the Linkerd web dashboard in your browser. ```bash # Open the Linkerd dashboard linkerd viz dashboard # Open on a specific port linkerd viz dashboard --port 9999 # Open on a specific address linkerd viz dashboard --address 0.0.0.0 # Show Grafana dashboard instead linkerd viz dashboard --show grafana # Only show URLs without opening browser linkerd viz dashboard --show url # Wait for dashboard to become available linkerd viz dashboard --wait 5m ``` ### linkerd viz routes - Display Route Metrics The `routes` command shows per-route metrics when ServiceProfiles are configured. ```bash # Show route metrics for a deployment linkerd viz routes deploy/web -n emojivoto # Show routes with destination filter linkerd viz routes deploy/web -n emojivoto --to svc/voting-svc # Show routes to a service linkerd viz routes svc/web-svc -n emojivoto # Output as JSON linkerd viz routes deploy/web -n emojivoto -o json # Example output: # ROUTE SERVICE SUCCESS RPS LATENCY_P50 LATENCY_P95 LATENCY_P99 # GET /api/list web-svc 100.00% 1.0rps 1ms 1ms 1ms # POST /api/vote voting-svc 85.71% 0.7rps 2ms 5ms 10ms # [DEFAULT] web-svc 100.00% 2.0rps 1ms 3ms 8ms ``` ### linkerd viz edges - Display Service Connections The `edges` command shows the connections between meshed resources. ```bash # Show edges for deployments in a namespace linkerd viz edges deploy -n emojivoto # Show edges for pods linkerd viz edges pods -n emojivoto # Output as JSON linkerd viz edges deploy -n emojivoto -o json # Example output: # SRC DST SRC_NS DST_NS SECURED # web emoji emojivoto emojivoto √ # web voting emojivoto emojivoto √ # vote-bot web emojivoto emojivoto √ ``` ## Multicluster Commands ### linkerd multicluster install - Install Multicluster Gateway The multicluster extension enables service mirroring and communication between Kubernetes clusters. ```bash # Install multicluster components (gateway) linkerd multicluster install | kubectl apply -f - # Install with custom gateway configuration linkerd multicluster install \ --gateway-port 4143 \ --gateway-probe-port 4191 \ | kubectl apply -f - # Uninstall multicluster components linkerd multicluster uninstall | kubectl delete -f - ``` ### linkerd multicluster link - Link Clusters Together The `link` command generates resources to allow one cluster to mirror services from another. ```bash # Generate link resources from the target (east) cluster # Apply to source (west) cluster to enable service mirroring linkerd --context=east multicluster link --cluster-name east \ | kubectl --context=west apply -f - # Link with custom gateway settings linkerd --context=east multicluster link \ --cluster-name east \ --gateway-addresses "1.2.3.4,5.6.7.8" \ --gateway-port 4143 \ | kubectl --context=west apply -f - # Link with custom service selector linkerd --context=east multicluster link \ --cluster-name east \ --selector "mirror.linkerd.io/exported=true" \ | kubectl --context=west apply -f - # Link in high-availability mode linkerd --context=east multicluster link \ --cluster-name east \ --ha \ | kubectl --context=west apply -f - # Link without gateway (for remote discovery mode) linkerd --context=east multicluster link \ --cluster-name east \ --gateway=false \ | kubectl --context=west apply -f - ``` ### linkerd multicluster gateways - List Multicluster Gateways ```bash # List all linked gateways linkerd multicluster gateways # Example output: # CLUSTER ALIVE NUM_SVC LATENCY_P50 LATENCY_P95 LATENCY_P99 # east True 5 1ms 2ms 3ms # west True 3 2ms 3ms 5ms ``` ## Helm Installation ### Installing with Helm Linkerd can be installed using Helm for more customizable deployments. ```bash # Add the Linkerd Helm repository helm repo add linkerd-edge https://helm.linkerd.io/edge helm repo update # Install CRDs first helm install linkerd-crds linkerd-edge/linkerd-crds -n linkerd --create-namespace # Generate certificates (for production, use cert-manager or external CA) step certificate create root.linkerd.cluster.local ca.crt ca.key \ --profile root-ca --no-password --insecure step certificate create identity.linkerd.cluster.local issuer.crt issuer.key \ --profile intermediate-ca --not-after 8760h --no-password --insecure \ --ca ca.crt --ca-key ca.key # Install control plane with generated certificates helm install linkerd-control-plane linkerd-edge/linkerd-control-plane \ -n linkerd \ --set identityTrustAnchorsPEM="$(cat ca.crt)" \ --set identity.issuer.tls.crtPEM="$(cat issuer.crt)" \ --set identity.issuer.tls.keyPEM="$(cat issuer.key)" # Install with custom values file helm install linkerd-control-plane linkerd-edge/linkerd-control-plane \ -n linkerd \ -f custom-values.yaml # Install viz extension helm install linkerd-viz linkerd-edge/linkerd-viz -n linkerd-viz --create-namespace # Upgrade Linkerd helm upgrade linkerd-control-plane linkerd-edge/linkerd-control-plane -n linkerd # Example custom-values.yaml: # clusterDomain: cluster.local # controllerReplicas: 3 # enablePodAntiAffinity: true # proxy: # resources: # cpu: # request: 100m # limit: 500m # memory: # request: 64Mi # limit: 256Mi # identity: # issuer: # clockSkewAllowance: 30s # issuanceLifetime: 48h ``` ## Authorization Policy Configuration ### Creating Server and Authorization Policies Linkerd's authorization policies control which workloads can communicate with each other. ```yaml # Server resource defines a port to apply policy to apiVersion: policy.linkerd.io/v1beta3 kind: Server metadata: name: web-http namespace: emojivoto spec: podSelector: matchLabels: app: web port: 8080 proxyProtocol: HTTP/2 --- # MeshTLSAuthentication requires clients to have valid mesh identity apiVersion: policy.linkerd.io/v1alpha1 kind: MeshTLSAuthentication metadata: name: web-clients namespace: emojivoto spec: identities: - "*.emojivoto.serviceaccount.identity.linkerd.cluster.local" --- # AuthorizationPolicy allows specific clients to access the server apiVersion: policy.linkerd.io/v1alpha1 kind: AuthorizationPolicy metadata: name: web-authz namespace: emojivoto spec: targetRef: group: policy.linkerd.io kind: Server name: web-http requiredAuthenticationRefs: - name: web-clients kind: MeshTLSAuthentication group: policy.linkerd.io ``` ```bash # Apply authorization policies kubectl apply -f server.yaml kubectl apply -f authn.yaml kubectl apply -f authz.yaml # Verify policies are working linkerd authz -n emojivoto deploy/web # Check for unauthorized requests linkerd viz stat server -n emojivoto ``` ## Proxy Annotations ### Configuring Proxy Behavior via Annotations The Linkerd proxy can be configured per-workload using annotations on pods or namespaces. ```yaml apiVersion: apps/v1 kind: Deployment metadata: name: web namespace: emojivoto spec: template: metadata: annotations: # Enable/disable injection linkerd.io/inject: enabled # Proxy resource configuration config.linkerd.io/proxy-cpu-request: "100m" config.linkerd.io/proxy-cpu-limit: "500m" config.linkerd.io/proxy-memory-request: "64Mi" config.linkerd.io/proxy-memory-limit: "256Mi" # Logging configuration config.linkerd.io/proxy-log-level: "warn,linkerd=info" config.linkerd.io/proxy-log-format: "json" # Skip specific ports from proxying config.alpha.linkerd.io/proxy-wait-before-exit-seconds: "10" config.linkerd.io/skip-inbound-ports: "25,587" config.linkerd.io/skip-outbound-ports: "25,587" # Opaque ports (skip protocol detection) config.linkerd.io/opaque-ports: "3306,5432,6379" # Default inbound policy config.linkerd.io/default-inbound-policy: "cluster-authenticated" # Native sidecar mode (requires Kubernetes 1.29+) config.alpha.linkerd.io/proxy-enable-native-sidecar: "true" # Access logging config.linkerd.io/access-log: "apache" spec: containers: - name: web image: web:latest ``` ```bash # Apply configured deployment kubectl apply -f deployment.yaml # Verify proxy configuration kubectl get pod -n emojivoto -l app=web -o jsonpath='{.items[0].metadata.annotations}' ``` ## Diagnostics and Troubleshooting ### linkerd diagnostics - Advanced Debugging The diagnostics subcommand provides tools for debugging Linkerd internals. ```bash # Get proxy metrics from a pod linkerd diagnostics proxy-metrics -n emojivoto deploy/web # Get controller metrics linkerd diagnostics controller-metrics # Export control plane endpoints for debugging linkerd diagnostics endpoints -n emojivoto web-svc # Profile proxy CPU and memory usage linkerd diagnostics profile -n emojivoto deploy/web ``` ### Common Troubleshooting Commands ```bash # Check control plane logs kubectl logs -n linkerd deploy/linkerd-destination -c destination # Check proxy logs for a specific pod kubectl logs -n emojivoto deploy/web -c linkerd-proxy # Describe proxy-injector webhook kubectl describe mutatingwebhookconfigurations linkerd-proxy-injector-webhook-config # Check if proxies can connect to control plane linkerd viz tap deploy/web -n emojivoto | head -20 # Verify mTLS is working linkerd viz edges deploy -n emojivoto # Check identity certificates linkerd identity -n emojivoto -l app=web # Debug network issues kubectl exec -n emojivoto deploy/web -c linkerd-proxy -- \ /bin/sh -c "cat /var/run/linkerd/config/proxy.json" ``` ## Summary Linkerd provides a comprehensive service mesh solution for Kubernetes that prioritizes simplicity and security. The CLI offers commands for complete lifecycle management including installation (`install`), validation (`check`), proxy injection (`inject`), and upgrades (`upgrade`). The viz extension adds powerful observability through `stat`, `tap`, `top`, and `routes` commands that provide real-time traffic insights. Service profiles enable per-route configuration for retries and timeouts, while authorization policies control service-to-service communication. For multi-cluster deployments, Linkerd's multicluster extension enables secure service mirroring between clusters using the `link` command. Integration patterns typically involve installing via CLI or Helm, annotating namespaces/deployments for automatic proxy injection, configuring service profiles for critical services, and establishing authorization policies for zero-trust security. The proxy configuration can be customized per-workload through Kubernetes annotations, allowing teams to fine-tune resource limits, logging, and protocol handling for specific applications. Linkerd's design philosophy emphasizes minimal operational complexity while delivering enterprise-grade security and observability features out of the box.