DEV Community

Maksim
Maksim

Posted on • Originally published at maksimrv.Medium on

VS Code: Debug node.js app in Kubernetes

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

Build node-app docker image:

docker build -t node-app .
Enter fullscreen mode Exit fullscreen mode

Start Minikube

minikube start
Enter fullscreen mode Exit fullscreen mode

Push our image to Minikube docker registry:

minikube image load node-app
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

Create test namespace in:

kubectl create namespace test
Enter fullscreen mode Exit fullscreen mode

Use test namespace by default for kubectl:

kubectl config set-context --current --namespace=test
Enter fullscreen mode Exit fullscreen mode

Upload depolyment.yaml :

kubectl apply -f deployment.yaml
Enter fullscreen mode Exit fullscreen mode

Check that our pods are running:

kubectl get pods
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

Setup VS Code

Open /tmp/app folder in VS Code

code -n /tmp/app
Enter fullscreen mode Exit fullscreen mode

Install Kubernetes extension for VS Code

code --install-extension ms-kubernetes-tools.vscode-kubernetes-tools --force
Enter fullscreen mode Exit fullscreen mode

Run command in VS Code.

Kubernetes: Focus on Cluster View
Enter fullscreen mode Exit fullscreen mode

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). 
Enter fullscreen mode Exit fullscreen mode
  • 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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

Open command pallet in VS Code and type

Bridge to Kubernetes: Configure
Enter fullscreen mode Exit fullscreen mode
  • 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
Enter fullscreen mode Exit fullscreen mode

Or run in debug mode via VS Code

Debug: Start Debugging
Enter fullscreen mode Exit fullscreen mode

Now run command:

Bridge to Kubernetes: Open Menu
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

as a result, you will see

Oh boy!!!
Enter fullscreen mode Exit fullscreen mode

so now you can develop and debug your application in live mode on Kubernetes 🎉

Top comments (0)