Debugging a Kubernetes application

Cloud Code allows you to easily debug your application deployed to a Kubernetes cluster by leveraging skaffold debug. You can debug your application on a local cluster (like Minikube or Docker Desktop), Google Kubernetes Engine, or any other Cloud provider.

Furthermore, with Cloud Code's debugging support, you don't have to worry about any manual setup like setting up port forwarding or injecting language-specific debug arguments. All you need to do is have a Cloud Code-ready Kubernetes application that includes a skaffold.yaml configuration file and a cloudcode.kubernetes launch configuration.

Debugging an application

  • Choose the Debug on Kubernetes command using the Cloud Code status bar.
  • If your application doesn't have necessary Skaffold configuration or cloudcode.kubernetes launch configuration, Cloud Code will help you set these up.
  • Confirm whether you'd like to use the current Kubernetes context to run the app in (or switch to a preferred one).
  • If the context chosen is of a remote cluster, you will be prompted to provide an image registry to push the images to.

    Here are examples of how to specify where container images are stored for some common registries:

    Docker Hub docker.io/{account}
    Ensure that you are properly authenticated if you are using a private Docker Hub repository.
    Google Container Repository (GCR) gcr.io/{project_id}
    AWS Container Repository (ECR) {aws_account_id}.dkr.ecr.{region}.amazonaws.com/{my-app}
    Azure Container Registry (ACR) {my_acr_name}.azurecr.io/{my-app}

    Cloud Code concatenates this image registry with the image name specified in the Kubernetes manifests to generate the final image repository name.

    For more information, refer to the image registry handling guide.

    This choice is stored in your cloudcode.kubernetes launch configuration (found in .vscode/launch.json).

  • Cloud Code then builds your containers, pushes them to the registry, applies Kubernetes configurations to the cluster, and waits for the rollout.

  • After the completion of rollout, Cloud Code automatically port-forwards all declared container ports to your machine and displays the URLs in the output window so you can browse your live application.

    Port-forwards and displays the URLs in the output window

  • For each debuggable container in your application, you'll be prompted to confirm or enter the directory in the remote container where the program you'd like to debug is found.

    • Alternatively, you can press ESC to skip debugging the container.

    Remote Root prompt

  • Cloud Code will attach a debug session for each debuggable container in the application.

  • You can now perform all the tasks you normally do when debugging local code, like setting breakpoints and stepping through code, except with the added advantage of debugging against a live Kubernetes cluster.

  • To inspect variables and stack info, use the Debug Sidebar. To interact with the debugging session, use the Debug Console in the bottom pane debugger.

    App paused at breakpoint and variables and call stack sections populated with values in scope

  • To end the debugging session, click the stop icon on the Debug Toolbar.

    • Upon termination of the application, all the deployed Kubernetes resources will be deleted from the cluster.

    Stop debugging the Kubernetes application

Configuration Details

Cloud Code, powered by Skaffold under the hood, will automatically take care of the following configuration details:

  • Port forwarding the debug port so that the debugger can be attached.
  • Attaching a debugger to one or more debuggable containers in your application. If your application has multiple debuggable containers (containers whose language is supported by Cloud Code debug) configured in skaffold.yaml, then a debugger will be attached to each of these.
  • Persisting source mapping definitions across sessions; you can customize these definitions by editing your .vscode/launch.json directly.

In addition to the above, depending on the language, Cloud Code will also take care of:

Node.js

Rewriting the entrypoint to invoke:

node --inspect=localhost:9229

Python

Installing the ptvsd module using an Init Container and rewriting the entrypoint to invoke:

python -m ptvsd --host localhost --port 5678

Go

Installing the dlv debugger using an Init Container and rewriting the entrypoint such that the launched debug session runs with a debug server only (in headless mode), continues the debugged process on start, accepts multiple client connections, and listens at localhost:56268:

dlv exec --headless --continue --accept-multiclient --listen=localhost:56268 --api-version=2, <app> --

Java

Adding an environment JAVA_TOOLS_OPTIONS with the appropriate JDWP configuration such that the JDWP debugging agent knows to listen for a socket connection on port 5005 and allows the VM to begin executing before the debugger is attached:

jdwp=transport=dt_socket,server=y,suspend=n,address=5005,quiet=y

For more details on Skaffold-powered debugging, refer to the skaffold debug documentation.

Attaching debugger to a Kubernetes Pod

Cloud Code VS Code also supports attaching a debugger to a Kubernetes Pod. To know the differences, refer to this table.

Getting Support

To send feedback, report issues on GitHub, or ask a question on Stack Overflow.