Skip to content

KSail + mirrord

mirrord lets you run a local process as if it were inside the cluster: your process inherits the pod’s environment variables, file system reads, and incoming network traffic — without deploying a new image. KSail provisions and configures the cluster; mirrord connects your local process to it.

LayerResponsibilityTool
Cluster lifecycleCreate, configure, and delete clustersKSail
GitOps bootstrapInstall Flux/ArgoCD, push manifestsKSail
Local↔remote bridgingRun local process as in-cluster podmirrord

mirrord injects a layer into your local process that intercepts system calls and redirects them to a target pod in the cluster:

  • Incoming traffic — mirror a copy of pod traffic to your local process (non-destructive), or steal it entirely so only your process responds.
  • Outgoing traffic — route your local process’s outbound connections through the cluster network.
  • Environment — inherit environment variables from the target pod.
  • File system — read remote files from the pod’s file system as if they were local.

This lets you debug a specific service using real cluster traffic without image rebuilds, redeploys, or port-forward gymnastics.

  • KSail CLI installed

  • Docker running

  • mirrord CLI installed:

    Terminal window
    brew install metalbear-co/mirrord/mirrord # macOS
    # or
    curl -fsSL https://raw.githubusercontent.com/metalbear-co/mirrord/main/scripts/install.sh | bash
Terminal window
ksail cluster init --name dev --distribution K3s
ksail cluster create
Terminal window
kubectl --context k3d-dev apply -f - <<EOF
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app
namespace: default
spec:
replicas: 1
selector:
matchLabels:
app: my-app
template:
metadata:
labels:
app: my-app
spec:
containers:
- name: my-app
image: nginx:latest
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: my-app
namespace: default
spec:
selector:
app: my-app
ports:
- port: 80
targetPort: 80
EOF

Create a .mirrord/mirrord.json configuration file in your project directory:

{
"target": {
"path": "deployment/my-app",
"namespace": "default"
},
"feature": {
"network": {
"incoming": "mirror"
},
"fs": "read",
"env": true
}
}
FieldDescription
target.pathThe pod/deployment/statefulset to target
feature.network.incoming"mirror" (duplicate traffic) or "steal" (redirect all traffic)
feature.fs"read" (remote reads), "write" (read+write), or false
feature.envInherit pod environment variables
Terminal window
mirrord exec --config .mirrord/mirrord.json -- ./my-app

Your local my-app process now receives a copy of all traffic destined for deployment/my-app, and inherits its environment variables and file access.

Terminal window
# Stop the mirrord session with Ctrl+C
ksail cluster delete

mirrord supports two traffic modes:

ModeBehaviourUse case
"mirror"Duplicate incoming traffic to both the pod and your local processObserve and debug without affecting production behaviour
"steal"Redirect all incoming traffic exclusively to your local processTest responses, verify logic changes with real traffic

Switch modes by updating feature.network.incoming in your .mirrord/mirrord.json:

{
"feature": {
"network": {
"incoming": "steal"
}
}
}

Use the kubeconfig context for your KSail distribution. Pass it directly on the command line to override the default context:

Terminal window
mirrord exec --context k3d-dev --config .mirrord/mirrord.json -- ./my-app

Or set it in mirrord.json:

{
"target": {
"path": "deployment/my-app",
"namespace": "default"
},
"kube_context": "k3d-dev"
}

Replace k3d-dev with the context name for your distribution (see the context name table above).

mirrord integrates directly with VS Code and JetBrains IDEs — no CLI needed:

Both integrations use your .mirrord/mirrord.json configuration automatically.

You can layer mirrord with other inner-loop tools. For example, use Tilt to rebuild and deploy on file save, and mirrord in a separate terminal to debug a specific service with live traffic:

Terminal window
# Terminal 1 — cluster + build loop
ksail cluster create
tilt up
# Terminal 2 — live debugging with real traffic
mirrord exec --config .mirrord/mirrord.json -- dlv debug ./cmd/server

See Companion Tools for a full comparison of KSail’s companion tool integrations.

  • Start with "mirror" mode — it’s non-destructive and lets you observe real traffic without interrupting the in-cluster service.

  • Use ksail cluster info to confirm the cluster is healthy before starting a mirrord session.

  • Target specific pods by using pod/<name> instead of deployment/<name> for more precise targeting:

    { "target": { "path": "pod/my-app-abc123", "namespace": "default" } }
  • Combine with ksail workload watch for manifest editing: ksail workload watch handles YAML changes at the Kubernetes layer; mirrord connects your local process at the network layer. They operate at different layers and do not conflict.

  • Ephemeral clusters work well with mirrord — create a short-lived cluster with ksail cluster create --ttl 1h to isolate your debugging session. See Ephemeral Clusters for details.

  • Companion Tools — Compare mirrord with Telepresence, Tilt, DevSpace, and Skaffold
  • Ephemeral Clusters — Create time-limited clusters for debugging and demos
  • Use Cases — Workflows for learning, development, and CI/CD