v0.3.3 — Now available

The service mesh that
stays out of your way

Ananse is a lightweight, Go-native service mesh for Kubernetes. Transparent traffic interception, observability, and optional mTLS — without the operational weight of Istio or Linkerd.

Get started View on GitHub
# Add the Ananse Helm repo
helm repo add ananse https://ananselabs.github.io/ananse
helm repo update

# Install into your cluster
helm install ananse ananse/ananse \
  --set-file caBundle=./ca.crt.b64 \
  -n ananse-system --create-namespace

What you get

Everything a mesh needs.
Nothing it doesn't.

Ananse handles the plumbing — traffic interception, routing, and observability — so your services stay focused on business logic.

Transparent injection

Mutating webhook automatically injects a sidecar proxy into labelled namespaces. Your pods need zero changes.

📡

gRPC control plane

The control plane streams routing config to every proxy over gRPC. Updates propagate in milliseconds.

📊

Full observability stack

Metrics via Prometheus (PodMonitor per sidecar), logs via Loki/Promtail, and distributed traces via OpenTelemetry + Tempo — all linked in Grafana.

🔒

Optional mTLS

Mutual TLS between sidecars, enabled per-pod with a single annotation. Off by default — turn it on when you need it.

🔍

Service discovery

Kubernetes-native discovery, Consul for VM/Docker deployments, or static file config. One control plane, any backend.

🪶

Tiny footprint

Each sidecar runs at ~100m CPU / 64Mi memory. The full mesh adds minimal overhead to your cluster.


Battle tested

Built for production.
Proven under pressure.

Numbers from a real production Kubernetes deployment running a sustained soak test — 50 concurrent users, 8 hours straight, no warmup exceptions.

2.6M
requests processed
without a single pod restart
87
req/s sustained
for 8+ hours continuously
0
sidecar crashes
zero memory leaks detected
flat
memory over 8 hours
goroutine count stable throughout

The mesh was transparent throughout. Errors observed during the test originated from application-layer configuration (gateway connection pool), not the proxy — confirmed via per-pod Prometheus metrics.


How Ananse works

Three components. No CRDs to learn. No separate CLI.

1

Webhook intercepts pods

When a pod is created in a labelled namespace, the mutating webhook injects an init container and a sidecar proxy before the pod starts.

2

Init sets up iptables

The init container writes iptables rules that redirect all inbound and outbound TCP traffic through the sidecar proxy on ports 15006 and 15001.

3

Proxy connects to control plane

The sidecar subscribes to the control plane over gRPC. The control plane streams routing tables derived from Kubernetes service discovery.

4

Traffic flows through the mesh

The proxy handles TLS, metrics, and tracing transparently. Your app code talks to localhost — the proxy handles the rest.


Deployment modes

Sidecar or gateway —
your call

Ananse works whether you're on Kubernetes or running containers on bare VMs.

Kubernetes

Sidecar mode

One proxy per pod. The webhook handles injection automatically. Works with any CNI.

discovery: k8s
VM / Docker

Gateway mode

A single Ananse instance acts as an ingress gateway. Integrates with Consul for service discovery.

discovery: consul

Metrics, logs, and traces — wired together

Every sidecar exposes Prometheus metrics on port 15021. Traces flow via OTLP gRPC. Loki captures logs with namespace/pod/container labels. All three link up in Grafana.

M

Metrics

PodMonitor auto-discovers injected pods across all namespaces. Works with any Prometheus Operator install.

L

Logs

Promtail ships pod logs to Loki with namespace, pod, and container labels. Log lines link to traces via TraceID.

T

Traces

Sidecars emit OTLP spans to Tempo (or Jaeger). Grafana Tempo links traces back to Loki log lines. Enable filterHealthChecks to drop successful probe spans and keep Tempo clean.

Enable full observability stack
helm install ananse ananse/ananse \
  --set-file caBundle=./ca.crt.b64 \
  --set observability.tracing.enabled=true \
  --set observability.tracing.endpoint=tempo.monitoring.svc:4317 \
  --set observability.tracing.filterHealthChecks=true \
  -n ananse-system --create-namespace

Quick start

Up in five minutes

Install Ananse, label your namespace, and your services join the mesh on next rollout.

1 — Add the Helm repo
helm repo add ananse https://ananselabs.github.io/ananse
helm repo update
2 — Generate TLS certs for the webhook
curl -sL https://raw.githubusercontent.com/ananselabs/ananse/main/scripts/generate-certs.sh | bash
3 — Install
helm install ananse ananse/ananse \
  --set-file caBundle=./ca.crt.b64 \
  -n ananse-system --create-namespace
4 — Label your namespace
kubectl label namespace default ananse.io/inject=enabled

# Restart your workloads — sidecars inject automatically
kubectl rollout restart deployment -n default
Read the docs on GitHub →