VS Code: Debug node.js app in Kubernetes šŸ³

Maksim Ryzhikov
4 min readMar 18, 2023

Story about how to debug node.js application on Kubernetes using VS Code.

Iā€™ll use Minikube as a local Kubernetes cluster. Minikube allows playing with k8s without fear to break something.

Setup environment

Letā€™s create a simple express application. The first step is creating the app folder:

mkdir /tmp/app && \
pushd /tmp/app && \
npm init -y && \
npm install express && \
mkdir src

Now create index.js with simple express server:

cat > src/index.js <<EOF
function main() {
const express = require('express');
const app = express();

app.get('/', (_, res) => {
res.send('Hello World!!!');
});

app.listen(3000, () => {
console.log('Example app listening on port 3000!');
});
}

main();
EOF

Add Dockerfile for our simple app:

cat > Dockerfile <<EOF
FROM node:18-slim

WORKDIR /app

COPY package.json ./
COPY package-lock.json ./
COPY src ./src

RUN npm ci --only=production

EXPOSE 3000

CMD ["node", "src/index.js"]
EOF

Build node-app docker image:

docker build -t node-app .

Start Minikube

minikube start

Push our image to Minikube docker registry:

minikube image load node-app

Add deployment.yaml for Kubernetes cluster:

cat > deployment.yaml <<EOF
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: node-app
name: node-app
spec:
replicas: 1
selector:
matchLabels:
app: node-app
template:
metadata:
labels:
app: node-app
spec:
containers:
- image: node-app
name: node-app
imagePullPolicy: Never
resources: {
limits: {
cpu: 500m,
memory: 512Mi
}
}
ports:
- containerPort: 3000
---
apiVersion: v1
kind: Service
metadata:
name: node-service
spec:
type: NodePort
selector:
app: node-app
ports:
- port: 3000
targetPort: 3000
nodePort: 30000
EOF

Create test namespace in:

kubectl create namespace test

Use test namespace by default for kubectl:

kubectl config set-context --current --namespace=test

Upload depolyment.yaml :

kubectl apply -f deployment.yaml

Check that our pods are running:

kubectl get pods

Start proxy Minikube to allow accessing our Kubernetes app from localhost. The following command will create a proxy, so donā€™t terminate it:

minikube service node-service --url -n test

Copy URL from previous command output and test that we can send a request to our pod from the localhost:

curl http://127.0.0.1:61127

Setup VS Code

Open /tmp/app folder in VS Code

code -n /tmp/app

Install Kubernetes extension for VS Code

code --install-extension ms-kubernetes-tools.vscode-kubernetes-tools --force

Run command in VS Code.

Kubernetes: Focus on Cluster View

There you should see minikube cluster. You can expand Workloads > Pods to see our running pods.

Now letā€™s open src/index.js the file and set the breakpoint on line:6 where we send the response res.send. Open command pallet and type:

 Kubernetes: Debug(Attach). 
  • Select our pod
  • Select nodejs

VS Code will start node.js debug session inside our pod container. Now letā€™s check that weā€™ll stop at breakpoint by sending a request to our service:

curl http://127.0.0.1:61127

Look at VS Code, you should see that we have stopped on our breakpoint.

Stop on breakpoint inside Pod container

Now we can debug our deployed application on Kubernetes.

Develop local app inside Kubernetes

In previous section, we have learned how to debug deployed application, but we canā€™t modify it without rebuilding & redeploying the whole app. In this section, we set up a workflow so that we can proxy all Kubernetes requests to our local application, so we can develop our app inside Kubernetes environment.

Stop debug session from the previous section.

Install Bridge to Kubernetes extension for VS Code:

code --install-extension mindaro.mindaro --force

Open command pallet in VS Code and type

Bridge to Kubernetes: Configure
  • Select node-service
  • Enter port 3000. This is the port where we start our local app.
  • Select Configure Bridge to Kubernetes without a launch configuration
  • And No this will redirect all requests to our local machine. But Yes is helpful when you run it on shared Kubernetes cluster.

OK, now we have finished Bridge configuration. Letā€™s start our local application. You can start it in terminal:

node src/index.js

Or run in debug mode via VS Code

Debug: Start Debugging

Now run command:

Bridge to Kubernetes: Open Menu

And select Connect to the cluster. This command will modify Kubernetes deployment. And create an additional pod and job. This is required to proxy all request from Kubernetes node-app to local machine. You can see it by running:

kubectl get all

Or other Kubernetes introspection command. How does it work, in more details you can read here.

For now, letā€™s change res.send('Hello World!!!'); on res.send('Oh boy!!!') and run the same curl command to send request to our service:

curl http://127.0.0.1:61127

as a result, you will see

Oh boy!!!

so now you can develop and debug your application in live mode on Kubernetes šŸŽ‰

--

--