Code and debug an application locally
Telepresence allows you to code and debug an application locally, while giving it access to resources in a remote cluster. You can either do an ingest, to gain read-only access to a service, or an intercept, to provide read-write access to a service and also re-route traffic intended for it to your workstation.
Prerequisites
Before you begin, you need to have Telepresence installed. This document uses the Kubernetes command-line tool, kubectl
in several examples. OpenShift users can substitute oc commands instead.
This guide assumes you have an application represented by a Kubernetes deployment and service accessible publicly by an ingress controller, and that you can run a copy of that application on your laptop.
Intercept your application
Running everything directly on the workstation
This approach offers the benefit of direct cluster connectivity from your workstation, simplifying debugging and modification of your application within its familiar environment. However, it requires root access to configure network telepresence, and remote mounts must be made relative to a specific mount point, which can add complexity.
-
Connect to your cluster with
telepresence connect
and try to curl to the Kubernetes API server. A 401 or 403 response code is expected and indicates that the service could be reached:Terminal$ curl -ik https://kubernetes.defaultHTTP/1.1 401 UnauthorizedCache-Control: no-cache, privateContent-Type: application/json...You now have access to your remote Kubernetes API server as if you were on the same network. You can now use any local tools to connect to any service in the cluster.
-
Enter
telepresence list
and make sure the workload (deployment in this case) you want to intercept is listed. For example:Terminal$ telepresence list...example-app: ready to intercept (traffic-agent not yet installed)... -
Get the name of the port you want to intercept on your service:
kubectl get service <service name> --output yaml
.If we assume that the service and deployment use the same name:
Terminal$ kubectl get service example-app --output yaml...ports:- name: httpport: 80protocol: TCPtargetPort: http... -
Intercept all traffic going to the application in your cluster:
telepresence intercept <workload-name> --port [<local-port>][:<remote-port>] --env-file <path-to-env-file>`.
- For
--port
: specify the port the local instance of your application is running on. If the intercepted service exposes multiple ports, specify the port you want to intercept after a colon. - For
--env-file
: specify a file path for Telepresence to write the environment variables that are set for the intercepted container.
The example below shows Telepresence intercepting traffic going to deployment
example-app
. Requests to the service on porthttp
in the cluster get routed to8080
on the workstation and the environment variables of the service are written to~/example-app-intercept.env
.Terminal$ telepresence intercept example-app --port 8080:http --env-file ~/example-app-intercept.envUsing Deployment example-appinterceptedIntercept name: example-appState : ACTIVEWorkload kind : DeploymentDestination : 127.0.0.1:8080Intercepting : all TCP connections - For
-
Start your local application using the environment variables retrieved in the previous step. The following are some examples of how to pass the environment variables to your local process:
- Visual Studio Code: specify the path to the environment variables file in the
envFile
field of your configuration. - JetBrains IDE (IntelliJ, WebStorm, PyCharm, GoLand, etc.): use the EnvFile plugin.
- Visual Studio Code: specify the path to the environment variables file in the
-
Query the cluster in which you intercepted an application and verify your local instance being invoked. All the traffic previously routed to your Kubernetes Service is now routed to your local environment
You can now:
- Make changes on the fly and see them reflected when interacting with your Kubernetes environment.
- Query services only exposed in your cluster's network.
- Set breakpoints in your IDE to investigate bugs.
Running everything using Docker
This approach eliminates the need for root access and confines the Telepresence network interface to a container. Additionally, it allows for precise replication of the target container's volume mounts, using identical mount points. However, this method sacrifices direct cluster connectivity from the workstation and the containerized environment can present challenges in terms of toolchain integration, debugging, and the overall development workflow.
-
Connect to your cluster with
telepresence connect --docker
and try to curl the Kubernetes API server from a container. A 401 or 403 response code is expected and indicates that the service could be reached. Thetelepresence curl
command used here is the same ascurl
but uses a container initiated with the network created by the Telepresence daemon:Terminal$ telepresence curl -ik https://kubernetes.defaultHTTP/1.1 401 UnauthorizedCache-Control: no-cache, privateContent-Type: application/json...You now have access to your remote Kubernetes API server as if you were on the same network. You can now use any local tools to connect to any service in the cluster.
-
Enter
telepresence list
and make sure the workload (deployment in this case) you want to intercept is listed. For example:Terminal$ telepresence list...example-app: ready to intercept (traffic-agent not yet installed)... -
Get the name of the port you want to intercept on your service:
kubectl get service <service name> --output yaml
.If we assume that the service and deployment use the same name:
Terminal$ kubectl get service example-app --output yaml...ports:- name: httpport: 80protocol: TCPtargetPort: http... -
Intercept all traffic going to the application in your cluster, and start a local container to handle that intercept:
telepresence intercept <workload-name> --port [<local-port>][:<remote-port>] --docker-run -- <your local container>.
- For
--port
: If the intercepted service exposes multiple ports, specify the service port you want to intercept after a colon. The local port can be empty to default to the same as the targeted container port.
The example below shows Telepresence intercepting traffic going to deployment
example-app
. The local container inherits the environment and the volume mounts from the targeted container, and requests to the service on porthttp
in the cluster get routed to the local container and the environment variables of the service are written to~/example-app-intercept.env
.Terminal$ telepresence intercept example-app --port :http --docker-run -- <your local container>Using Deployment example-appinterceptedIntercept name: example-appState : ACTIVEWorkload kind : DeploymentDestination : 127.0.0.1:8080Intercepting : all TCP connections<output from your local container> - For
-
Query the cluster in which you intercepted an application and verify your local instance being invoked. All the traffic previously routed to your Kubernetes Service is now routed to your local container.
You can now:
- Make changes on the fly and see them reflected when interacting with your Kubernetes environment; although depending on how your local container is configured, this might require that it is rebuilt.
- Query services only exposed in your cluster's network using
telepresence curl
. - Set breakpoints in a Remote Debug configuration in your IDE to investigate bugs.
Ingest your service
In some situations, you want to work and debug the code locally, and you want it to be able to access other services in the cluster,
but you don't wish to intercept any traffic intended for the targeted workload. This is where the telepresence ingest
command
comes into play. Just like intercept, it will make the environment and mounted containers of the targeted container available locally,
but it will not intercept any traffic.
This example assumes that you have the example-app
Running everything directly on the workstation
-
Connect and run and start an ingest from
example-app
:Terminal$ telepresence connectLaunching Telepresence User DaemonLaunching Telepresence Root DaemonConnected to context xxx, namespace default (https://<some url>)$ telepresence ingest example-app --env-file ~/example-app-intercept.envUsing Deployment example-appContainer : example-appVolume Mount Point: /tmp/telfs-166994305 -
Start your local application using the environment variables retrieved in the previous step.
You can now:
- Code and debug your local app while it interacts with other services in your cluster.
- Query services only exposed in your cluster's network.
- Set breakpoints in your IDE to investigate bugs.
Running everything using Docker
- Connect using docker start an ingest from
example-app
, and run a container locally with the ingested environment and volume mounts:Terminal$ telepresence connect --dockerLaunching Telepresence User DaemonConnected to context xxx, namespace default (https://<some url>)$ telepresence ingest example-app --expose 8080 --docker-run -- <your local container>Using Deployment example-app, container example-app<output from your local container>
You can now:
- Code and debug your local container while it interacts with other services in your cluster.
- Send request to your local container using localhost:<local port>
- Query services only exposed in your cluster's network using
telepresence curl
. - Set breakpoints in a Remote Debug configuration in your IDE to investigate bugs.