docker.recipes

Linkerd Service Mesh Stack

advanced

Lightweight service mesh with automatic mTLS, traffic splitting, and observability.

Overview

Linkerd is an ultralight service mesh for Kubernetes and containerized applications, originally developed by Buoyant and now a CNCF graduated project. Built with Rust and Go, Linkerd provides automatic mutual TLS encryption, intelligent load balancing, and comprehensive observability for microservices communication without requiring code changes. This stack demonstrates Linkerd's core functionality using the popular Emojivoto demo application along with full observability infrastructure. The combination of Linkerd's control plane, visualization components, Jaeger for distributed tracing, Prometheus for metrics collection, and Grafana for dashboards creates a complete service mesh observability platform. This setup showcases how Linkerd automatically encrypts service-to-service communication, provides traffic metrics, and integrates with cloud-native observability tools. Platform engineers and SREs looking to understand service mesh concepts, evaluate Linkerd's capabilities, or prototype microservices observability solutions will find this stack invaluable for hands-on learning and proof-of-concept deployments.

Key Features

  • Automatic mutual TLS encryption between all meshed services without certificate management
  • Linkerd's ultralight Rust-based proxy with minimal latency and resource overhead
  • Real-time service topology visualization through Linkerd's web dashboard
  • Traffic splitting and canary deployment capabilities via Linkerd's traffic policies
  • Distributed tracing integration with Jaeger for request flow analysis
  • Prometheus metrics collection for Linkerd proxy and application telemetry
  • Pre-configured Grafana dashboards for service mesh observability
  • Emojivoto demo application demonstrating real microservices mesh behavior

Common Use Cases

  • 1Service mesh proof-of-concept for evaluating Linkerd versus Istio or Consul Connect
  • 2Microservices security demonstration showing automatic mTLS encryption capabilities
  • 3Developer training environment for learning service mesh concepts and observability
  • 4CI/CD pipeline testing for applications destined for Linkerd-enabled Kubernetes clusters
  • 5Performance benchmarking of service mesh overhead using realistic demo applications
  • 6Distributed tracing workshop setup for understanding microservices request flows
  • 7Local development environment mimicking production Linkerd mesh behavior

Prerequisites

  • Docker Engine 20.10+ with Docker Compose V2 for multi-container orchestration
  • Minimum 4GB available RAM for Linkerd components, Prometheus, Grafana, and demo services
  • Available ports 3000, 8080-8085, 9090, 9995, 14268, and 16686 for service access
  • Basic understanding of service mesh concepts and microservices architecture
  • Familiarity with Prometheus metrics and Grafana dashboard navigation
  • Knowledge of distributed tracing concepts for effective Jaeger usage

For development & testing. Review security settings, change default credentials, and test thoroughly before production use. See Terms

docker-compose.yml

docker-compose.yml
1services:
2 # Simulated Linkerd control plane
3 linkerd-controller:
4 image: ghcr.io/linkerd/controller:stable-2.14.0
5 ports:
6 - "8085:8085"
7 - "9995:9995"
8 networks:
9 - linkerd_net
10
11 # Linkerd Viz extension
12 linkerd-viz:
13 image: ghcr.io/linkerd/metrics-api:stable-2.14.0
14 ports:
15 - "8084:8084"
16 networks:
17 - linkerd_net
18
19 # Web dashboard
20 linkerd-web:
21 image: ghcr.io/linkerd/web:stable-2.14.0
22 ports:
23 - "8080:8080"
24 environment:
25 - LINKERD_CONTROLLER_API_ADDR=linkerd-controller:8085
26 depends_on:
27 - linkerd-controller
28 networks:
29 - linkerd_net
30
31 # Sample meshed service
32 emojivoto-web:
33 image: docker.l5d.io/buoyantio/emojivoto-web:v11
34 ports:
35 - "8081:8080"
36 networks:
37 - linkerd_net
38
39 emojivoto-emoji-svc:
40 image: docker.l5d.io/buoyantio/emojivoto-emoji-svc:v11
41 networks:
42 - linkerd_net
43
44 emojivoto-voting-svc:
45 image: docker.l5d.io/buoyantio/emojivoto-voting-svc:v11
46 networks:
47 - linkerd_net
48
49 # Distributed tracing
50 jaeger:
51 image: jaegertracing/all-in-one:latest
52 ports:
53 - "16686:16686"
54 - "14268:14268"
55 networks:
56 - linkerd_net
57
58 prometheus:
59 image: prom/prometheus:latest
60 ports:
61 - "9090:9090"
62 volumes:
63 - ./prometheus.yml:/etc/prometheus/prometheus.yml
64 - prometheus_data:/prometheus
65 networks:
66 - linkerd_net
67
68 grafana:
69 image: grafana/grafana:latest
70 ports:
71 - "3000:3000"
72 environment:
73 - GF_SECURITY_ADMIN_PASSWORD=${GRAFANA_PASSWORD}
74 volumes:
75 - grafana_data:/var/lib/grafana
76 networks:
77 - linkerd_net
78
79volumes:
80 prometheus_data:
81 grafana_data:
82
83networks:
84 linkerd_net:

.env Template

.env
1# Linkerd Service Mesh
2GRAFANA_PASSWORD=secure_grafana_password
3
4# Dashboard at http://localhost:8080
5# Emojivoto demo at http://localhost:8081
6# Jaeger at http://localhost:16686

Usage Notes

  1. 1Dashboard at http://localhost:8080
  2. 2Emojivoto demo at http://localhost:8081
  3. 3Automatic mTLS between services
  4. 4Lightweight Rust-based proxy
  5. 5Demo setup - use Kubernetes for production

Individual Services(9 services)

Copy individual services to mix and match with your existing compose files.

linkerd-controller
linkerd-controller:
  image: ghcr.io/linkerd/controller:stable-2.14.0
  ports:
    - "8085:8085"
    - "9995:9995"
  networks:
    - linkerd_net
linkerd-viz
linkerd-viz:
  image: ghcr.io/linkerd/metrics-api:stable-2.14.0
  ports:
    - "8084:8084"
  networks:
    - linkerd_net
linkerd-web
linkerd-web:
  image: ghcr.io/linkerd/web:stable-2.14.0
  ports:
    - "8080:8080"
  environment:
    - LINKERD_CONTROLLER_API_ADDR=linkerd-controller:8085
  depends_on:
    - linkerd-controller
  networks:
    - linkerd_net
emojivoto-web
emojivoto-web:
  image: docker.l5d.io/buoyantio/emojivoto-web:v11
  ports:
    - "8081:8080"
  networks:
    - linkerd_net
emojivoto-emoji-svc
emojivoto-emoji-svc:
  image: docker.l5d.io/buoyantio/emojivoto-emoji-svc:v11
  networks:
    - linkerd_net
emojivoto-voting-svc
emojivoto-voting-svc:
  image: docker.l5d.io/buoyantio/emojivoto-voting-svc:v11
  networks:
    - linkerd_net
jaeger
jaeger:
  image: jaegertracing/all-in-one:latest
  ports:
    - "16686:16686"
    - "14268:14268"
  networks:
    - linkerd_net
prometheus
prometheus:
  image: prom/prometheus:latest
  ports:
    - "9090:9090"
  volumes:
    - ./prometheus.yml:/etc/prometheus/prometheus.yml
    - prometheus_data:/prometheus
  networks:
    - linkerd_net
grafana
grafana:
  image: grafana/grafana:latest
  ports:
    - "3000:3000"
  environment:
    - GF_SECURITY_ADMIN_PASSWORD=${GRAFANA_PASSWORD}
  volumes:
    - grafana_data:/var/lib/grafana
  networks:
    - linkerd_net

Quick Start

terminal
1# 1. Create the compose file
2cat > docker-compose.yml << 'EOF'
3services:
4 # Simulated Linkerd control plane
5 linkerd-controller:
6 image: ghcr.io/linkerd/controller:stable-2.14.0
7 ports:
8 - "8085:8085"
9 - "9995:9995"
10 networks:
11 - linkerd_net
12
13 # Linkerd Viz extension
14 linkerd-viz:
15 image: ghcr.io/linkerd/metrics-api:stable-2.14.0
16 ports:
17 - "8084:8084"
18 networks:
19 - linkerd_net
20
21 # Web dashboard
22 linkerd-web:
23 image: ghcr.io/linkerd/web:stable-2.14.0
24 ports:
25 - "8080:8080"
26 environment:
27 - LINKERD_CONTROLLER_API_ADDR=linkerd-controller:8085
28 depends_on:
29 - linkerd-controller
30 networks:
31 - linkerd_net
32
33 # Sample meshed service
34 emojivoto-web:
35 image: docker.l5d.io/buoyantio/emojivoto-web:v11
36 ports:
37 - "8081:8080"
38 networks:
39 - linkerd_net
40
41 emojivoto-emoji-svc:
42 image: docker.l5d.io/buoyantio/emojivoto-emoji-svc:v11
43 networks:
44 - linkerd_net
45
46 emojivoto-voting-svc:
47 image: docker.l5d.io/buoyantio/emojivoto-voting-svc:v11
48 networks:
49 - linkerd_net
50
51 # Distributed tracing
52 jaeger:
53 image: jaegertracing/all-in-one:latest
54 ports:
55 - "16686:16686"
56 - "14268:14268"
57 networks:
58 - linkerd_net
59
60 prometheus:
61 image: prom/prometheus:latest
62 ports:
63 - "9090:9090"
64 volumes:
65 - ./prometheus.yml:/etc/prometheus/prometheus.yml
66 - prometheus_data:/prometheus
67 networks:
68 - linkerd_net
69
70 grafana:
71 image: grafana/grafana:latest
72 ports:
73 - "3000:3000"
74 environment:
75 - GF_SECURITY_ADMIN_PASSWORD=${GRAFANA_PASSWORD}
76 volumes:
77 - grafana_data:/var/lib/grafana
78 networks:
79 - linkerd_net
80
81volumes:
82 prometheus_data:
83 grafana_data:
84
85networks:
86 linkerd_net:
87EOF
88
89# 2. Create the .env file
90cat > .env << 'EOF'
91# Linkerd Service Mesh
92GRAFANA_PASSWORD=secure_grafana_password
93
94# Dashboard at http://localhost:8080
95# Emojivoto demo at http://localhost:8081
96# Jaeger at http://localhost:16686
97EOF
98
99# 3. Start the services
100docker compose up -d
101
102# 4. View logs
103docker compose logs -f

One-Liner

Run this command to download and set up the recipe in one step:

terminal
1curl -fsSL https://docker.recipes/api/recipes/linkerd-service-mesh/run | bash

Troubleshooting

  • Linkerd web dashboard shows 'Controller API unavailable': Verify linkerd-controller container is running and port 8085 is accessible
  • Emojivoto services not appearing in topology: Check that emojivoto containers are on the linkerd_net network and controllers are healthy
  • Prometheus not scraping Linkerd metrics: Ensure prometheus.yml includes Linkerd endpoints and containers can communicate on linkerd_net
  • Jaeger traces not appearing: Verify Linkerd proxy trace sampling configuration and Jaeger collector port 14268 connectivity
  • Grafana dashboards showing no data: Confirm Prometheus data source configuration and verify Prometheus is successfully scraping targets
  • High memory usage: Linkerd proxy and Prometheus can be memory-intensive; allocate at least 4GB total system memory for stable operation

Community Notes

Loading...
Loading notes...

Download Recipe Kit

Get all files in a ready-to-deploy package

Includes docker-compose.yml, .env template, README, and license

Ad Space