Telepresence connects your workstation to a Kubernetes cluster as if it were one more pod: you can resolve and call cluster services by name, and you can route traffic addressed to a service in the cluster to a process running on your laptop. That lets you edit, run and debug a service locally with your own IDE while it talks to the real databases and dependencies in the cluster, without building and deploying an image for every change. In this tutorial you will install Telepresence on Ubuntu 24.04, install its Traffic Manager in the cluster, and use intercepts (including header-based personal intercepts) against a sample service.
Prerequisites
To follow this tutorial you need:
- A workstation running Ubuntu 24.04 (amd64 or arm64) with a user that can run
sudo. Telepresence also runs on macOS and Windows, but the commands here are for Ubuntu. - A Kubernetes cluster, for example a managed Kubernetes cluster on CubePath, and
kubectlconfigured to access it. - Cluster-admin permissions once, to install the Traffic Manager. Day-to-day use only needs access to the namespaces you work in.
- Python 3, which Ubuntu 24.04 includes, to run a small local web server as the "service under development".
Telepresence does not work on a workstation that is itself inside a restricted container. Run it on your laptop or a development VM.
Step 1 - Installing the Telepresence client
The project publishes a .deb package that installs the telepresence binary and a systemd service for its root daemon. The root daemon creates the virtual network interface and DNS resolver, and running it as a service means you do not need to type your password on every connection.
Download the package for your architecture (replace amd64 with arm64 on ARM machines):
curl -fLO https://github.com/telepresenceio/telepresence/releases/latest/download/telepresence-linux-amd64.deb
Install it with apt, which also resolves its dependencies:
sudo apt install ./telepresence-linux-amd64.deb
Telepresence mounts the remote container's volumes on your workstation with sshfs. Install it now so volume mounts work later:
sudo apt install sshfs
Check the client version:
telepresence version
The first line of the output shows the client version, for example OSS Client : v2.32.1. The exact version will be the latest release at the time you install.
Step 2 - Installing the Traffic Manager in the cluster
The Traffic Manager is the cluster-side component. It keeps track of connected clients and injects a small traffic agent into the pods you intercept. Install it once per cluster; by default it goes into the ambassador namespace:
telepresence helm install
Traffic Manager installed successfully
Verify that its pod is running:
kubectl -n ambassador get pods
NAME READY STATUS RESTARTS AGE
traffic-manager-6c9b8b8f7d-x2q7m 1/1 Running 0 40s
For a shared cluster you will keep using, telepresence helm install --namespace your_namespace installs it in another namespace, and telepresence setup --apply runs a guided setup that inspects the cluster before installing.
Step 3 - Deploying a sample service
To have something to intercept, deploy the echo server that the Telepresence project maintains. It answers every HTTP request with the name of the host that served it, which makes it obvious where your request ended up.
Create the manifest:
nano hello.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: hello
labels:
app: hello
spec:
replicas: 1
selector:
matchLabels:
app: hello
template:
metadata:
labels:
app: hello
spec:
containers:
- name: echo-server
image: ghcr.io/telepresenceio/echo-server:latest
ports:
- name: http
containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
name: hello
spec:
selector:
app: hello
ports:
- port: 80
targetPort: http
Apply it in the default namespace and wait for the rollout:
kubectl apply -f hello.yaml
kubectl rollout status deployment hello
deployment.apps/hello created
service/hello created
deployment "hello" successfully rolled out
Step 4 - Connecting your workstation to the cluster
telepresence connect starts the user daemon, adds a virtual network interface routed to the cluster's pod and service networks, and configures DNS so that cluster names resolve on your machine. Connect to the namespace where the sample service lives:
telepresence connect --namespace default
Launching Telepresence User Daemon
Connected to context your_context, namespace default (https://your_cluster_api)
If you work with several clusters, add --context your_context to choose a kubeconfig context explicitly.
Now call the service by its cluster DNS name, from your workstation, exactly as another pod in the namespace would:
curl http://hello
Request served by hello-69fbdc98cf-4bnkl
...
The fully qualified name (hello.default.svc.cluster.local) and names in other namespaces (service.namespace) also resolve. Your local tools, such as a database client or your browser, can reach cluster-only services the same way. Check the connection details at any time with:
telepresence status
Step 5 - Running the service locally
In real work, the local copy is your service started from your IDE or debugger. For this tutorial, a Python web server that returns a recognizable page is enough.
Create a directory with an index page:
mkdir -p ~/hello-local
echo "Hello from my workstation" > ~/hello-local/index.html
Start the server on port 8080 in a separate terminal and leave it running:
python3 -m http.server 8080 --directory ~/hello-local
Check it locally from your first terminal:
curl http://localhost:8080
Hello from my workstation
Step 6 - Intercepting all traffic to the service
An intercept tells the traffic agent in the cluster to forward requests for the service to your workstation. List the workloads Telepresence can attach to in the current namespace:
telepresence list
deployment hello: ready to attach (traffic-agent not yet installed)
Create an intercept that sends the service's traffic to local port 8080. Because the Service exposes a single port, you only need to give the local port. The --env-file flag writes the environment variables of the remote container to a file, and --mount mounts its volumes under the given directory:
telepresence intercept hello --port 8080 --env-file ~/hello.env --mount /tmp/hello-mounts
Using Deployment hello
intercepted
Intercept name : hello
State : ACTIVE
Workload kind : Deployment
Destination : 127.0.0.1:8080
Volume Mount Point: /tmp/hello-mounts
Intercepting : all TCP connections
The first intercept restarts the pod once, because the traffic agent is injected as a sidecar. Now call the cluster service again:
curl http://hello
Hello from my workstation
The request went to the cluster Service, and your local Python process answered it. Any other pod that calls hello, and any ingress route pointing to it, now reaches your workstation too. Edit ~/hello-local/index.html and repeat the request: the change is live with no image build.
Using the remote environment and volumes
Your local process often needs the same configuration as the pod: database URLs, feature flags, credentials mounted from Secrets. Look at the environment file Telepresence wrote:
grep HELLO_SERVICE ~/hello.env
HELLO_SERVICE_HOST=10.43.12.87
HELLO_SERVICE_PORT=80
Load it into the shell that starts your service, for example:
set -a; source ~/hello.env; set +a
The container's volumes, including the projected ServiceAccount token, are available under the mount point:
ls /tmp/hello-mounts/var/run/secrets/kubernetes.io/serviceaccount
ca.crt namespace token
Point your application at files under /tmp/hello-mounts (Telepresence also exports this path as $TELEPRESENCE_ROOT in the environment file) instead of the absolute paths it uses in the pod.
End the intercept when you are done. The traffic goes back to the pod in the cluster:
telepresence detach hello
curl http://hello
Request served by hello-69fbdc98cf-4bnkl
...
Step 7 - Personal intercepts with HTTP headers
A full intercept affects everyone using the service. On a shared development cluster, a personal intercept is safer: only requests that carry a specific HTTP header are sent to your workstation, and everything else is still served by the pod. Several developers can intercept the same service at the same time, each with their own header.
Create an intercept that only matches requests with the header x-dev: alice:
telepresence intercept hello --port 8080 --http-header "x-dev=alice"
Using Deployment hello
intercepted
Intercept name: hello
State : ACTIVE
Workload kind : Deployment
Destination : 127.0.0.1:8080
Intercepting : HTTP requests with header 'X-Dev: alice'
Compare a request without and with the header:
curl http://hello
curl -H "x-dev: alice" http://hello
Request served by hello-69fbdc98cf-4bnkl
...
Hello from my workstation
For this to work end to end, the services in front of the intercepted one must propagate the header (the same way they propagate tracing headers). You can also filter by path with --http-path-prefix /api.
Remove the intercept:
telepresence detach hello
Step 8 - Disconnecting and cleaning up
Disconnect your workstation from the cluster. This removes the virtual interface and the DNS configuration:
telepresence quit
Delete the sample service:
kubectl delete -f hello.yaml
The Traffic Manager can stay installed for the next session. If you want to remove it from the cluster:
telepresence helm uninstall
Troubleshooting
telepresence connect fails with a Traffic Manager error. The Traffic Manager is not installed or is in a different namespace. Check with kubectl get pods -A -l app=traffic-manager and install it as shown in Step 2. Its logs are available with kubectl -n ambassador logs deploy/traffic-manager.
Cluster names do not resolve after connecting. Run telepresence status to confirm that both daemons are connected, then reconnect with telepresence quit followed by telepresence connect. The root daemon installed from the .deb package logs to the journal:
journalctl -u telepresence-rootd -n 50
The intercept is stuck waiting for the agent. The pod must restart to receive the traffic agent. Check the rollout and pod events with kubectl rollout status deployment hello and kubectl describe pod -l app=hello. Admission policies that block sidecars or unknown images are a common cause.
Telepresence asks for the port to intercept. When a Service exposes several ports, name the one you want after a colon, for example --port 8080:http, using the port name or number from the Service.
Volume mounts are empty or fail. Confirm that sshfs is installed. To skip mounting entirely, pass --mount=false.
Conclusion
You installed the Telepresence client and Traffic Manager, reached cluster services by name from Ubuntu 24.04, and routed Kubernetes traffic to a local process with a full intercept and with a header-based personal intercept, using the remote environment and volumes locally. That removes the build, push and deploy loop from day-to-day development.
Next steps:
- Try
telepresence replacewhen the remote container must stop completely while you work, ortelepresence ingestto get only its environment and volumes without touching traffic. - Run Telepresence's daemon in Docker with
telepresence connect --dockeron machines where you cannot install system services. - Use the Traffic Manager's Helm values to restrict which namespaces it manages on shared clusters.
