Remote Debugging KubeVela Applications
This guide provides comprehensive instructions for configuring remote debugging of KubeVela applications using IntelliJ IDEA or VS Code. It outlines the essential configurations and provides a step-by-step process for attaching the debugger to a KubeVela application running within a Kubernetes cluster. This setup empowers developers to examine application behavior, identify issues, and enhance performance by directly interacting with the runtime environment.
Prerequisites
Before you begin, ensure you have:
- KubeVela source code cloned from github.com/kubevela/kubevela
- Go 1.19 or later installed
- A running Kubernetes cluster accessible via
~/.kube/config - Docker installed for building container images
- Access to a container registry (e.g., Docker Hub)
- An IDE with Go debugger support (VS Code or IntelliJ IDEA / GoLand)
- Delve debugger (will be installed in the container)
For local debugging without containers, see Debugging KubeVela Controllers.
Overview
Remote debugging allows you to debug a KubeVela application running inside a Kubernetes pod. This approach is useful when you need to debug issues that only occur in a cluster environment. The setup involves:
- Building a debug-enabled Docker image with Delve
- Modifying the deployment configuration
- Deploying the debug image to your cluster
- Attaching the remote debugger from your IDE
Step 1: Update the Dockerfile for Remote Debugging
Modify the Dockerfile in the root of the KubeVela repository to enable remote debugging.
Install the Delve Debugger During the Build Stage
Add the following command to install Delve (ensure the version matches your Go version):
RUN go install github.com/go-delve/delve/cmd/dlv@v1.22.0
This installs Delve, the Go debugger, which enables remote debugging and allows IntelliJ IDEA or VS Code to interact with your running application.
Modify the Build Command
Original Command:
RUN GO111MODULE=on CGO_ENABLED=0 GOOS=linux GOARCH=${TARGETARCH} \
go build -a -ldflags "-s -w -X github.com/oam-dev/kubevela/version.VelaVersion=${VERSION:-undefined} -X github.com/oam-dev/kubevela/version.GitRevision=${GITVERSION:-undefined}" \
-o manager-${TARGETARCH} cmd/core/main.go
Updated Command:
RUN GO111MODULE=on CGO_ENABLED=0 GOOS=linux GOARCH=${TARGETARCH} \
go build -gcflags="all=-N -l" -a -ldflags "-X github.com/oam-dev/kubevela/version.VelaVersion=${VERSION:-undefined} -X github.com/oam-dev/kubevela/version.GitRevision=${GITVERSION:-undefined}" \
-o manager-${TARGETARCH} cmd/core/main.go
Key Changes:
- Added:
-gcflags="all=-N -l"- Disables optimizations and inlining, preserving debugging information - Removed:
-s -wflags from ldflags - These strip symbol tables and debug information
Expose the Debugger Port
Add the following line to expose the debugger port:
EXPOSE 40000
Port 40000 is the default port for Delve. You can use any port, but ensure consistency across all configurations.
Copy the Delve Binary into the Runtime Container
Add this line to copy the Delve binary to the runtime container:
COPY --from=builder /go/bin/dlv /
This makes the debugger available during runtime.
Build and Push the Docker Image
Build your Docker image with a designated tag and push it to your container registry:
docker build -t <docker-hub-username>/kubevela:debug -f Dockerfile .
docker push <docker-hub-username>/kubevela:debug
Replace <docker-hub-username> with your actual Docker Hub username or registry path.

Step 2: Modify the kubevela-controller.yaml
Edit the file charts/vela-core/templates/kubevela-controller.yaml to make the following changes:
Remove Leader Election
Remove the --enable-leader-election argument from the spec.containers.args section in the deployment manifest.
Leader election ensures high availability by keeping only one active controller instance. During debugging, breakpoints can pause the pod for extended periods, potentially triggering restarts. Disabling leader election prevents this interruption during debugging sessions.

Update the Deployment Image
In the deployment manifest, find the spec.containers.image section and update it with your debug image:
image: <docker-hub-username>/kubevela:debug
Ensure you use the same image name and tag specified during the docker push command.

Remove Readiness and Liveness Probes
Disable the readiness and liveness probes by removing both the readinessProbe and livenessProbe sections under spec.containers in the deployment manifest.
Disabling probes prevents Kubernetes from restarting the pod when it becomes unresponsive during debugging. Breakpoints can cause the application to halt, leading to probe failures and unwanted restarts.

Step 3: Deploy KubeVela Core to Your Kubernetes Cluster
Navigate to the root directory of the KubeVela repository and execute the following Helm command:
helm upgrade --install --create-namespace --namespace vela-system \
--set image.pullPolicy=IfNotPresent \
--set image.repository=<docker-hub-username>/kubevela \
--set image.tag=debug \
--set applicationRevisionLimit=5 \
--set controllerArgs.reSyncPeriod=1m \
--set optimize.disableComponentRevision=false \
--set multicluster.clusterGateway.image.repository=ghcr.io/oam-dev/cluster-gateway \
--set admissionWebhooks.patch.image.repository=ghcr.io/oam-dev/kube-webhook-certgen/kube-webhook-certgen \
--wait kubevela ./charts/vela-core --debug
The --wait flag ensures the command pauses until all resources are ready, while --debug provides detailed output for troubleshooting.
Verify the Deployment
After successful execution, verify the status:
kubectl get all -n vela-system
Expected Output:
NAME READY STATUS RESTARTS AGE
pod/kubevela-cluster-gateway-7b8d9cb47d-wbz44 1/1 Running 0 50s
pod/kubevela-vela-core-7f96576fcd-tqsq2 1/1 Running 0 50s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/kubevela-cluster-gateway-service ClusterIP 10.43.197.61 <none> 9443/TCP 30s
service/vela-core-webhook ClusterIP 10.43.220.182 <none> 443/TCP 30s
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/kubevela-cluster-gateway 1/1 1 1 29s
deployment.apps/kubevela-vela-core 1/1 1 1 29s
NAME DESIRED CURRENT READY AGE
replicaset.apps/kubevela-cluster-gateway-7b8d9cb47d 1 1 1 50s
replicaset.apps/kubevela-vela-core-7f96576fcd 1 1 1 50s
Once the Vela core is running, proceed to attach the debugger.
Uninstalling KubeVela
To remove KubeVela from the cluster:
helm delete kubevela --namespace vela-system --debug
Step 4: Attach the Go Delve Debugger to the Vela Core Pod
Attach the Delve debugger to the running Vela Core pod:
kubectl exec -it pod/<pod_name> -n vela-system -- /dlv attach 1 --headless --listen=:40000 --api-version=2 --accept-multiclient
Replace <pod_name> with your actual pod name (e.g., kubevela-vela-core-7f96576fcd-tqsq2).
Command Breakdown:
dlv attach <PID>- Attaches to the Go process with the specified Process ID (PID 1 is typically the main process)--headless- Runs Delve in headless mode (no interactive terminal)--listen=:40000- Listens on port 40000 for remote connections--api-version=2- Uses Delve API version 2--accept-multiclient- Allows multiple debugger clients to connect
Expected Output:
API server listening at: [::]:40000
2025-02-23T17:11:52Z warning layer=rpc Listening for remote connections (connections are not authenticated nor encrypted)
The debugger warns that connections are not authenticated or encrypted. Only use this in trusted development environments.
Step 5: Enable External Access to the Debugger Port
For local clusters (e.g., K3d, minikube), forward the debugger port to your local machine:
kubectl port-forward pod/<pod_name> -n vela-system 40000:40000
Replace <pod_name> with your actual pod name.
Expected Output:
Forwarding from 127.0.0.1:40000 -> 40000
Forwarding from [::1]:40000 -> 40000
Run this port forwarding command in a separate terminal as it's a continuous process. Closing the terminal will terminate port forwarding.
Step 6: Configure Remote Debugging in Your IDE
VS Code Configuration
Create or update .vscode/launch.json in your project root:
{
"version": "0.2.0",
"configurations": [
{
"name": "Attach to Remote KubeVela",
"type": "go",
"request": "attach",
"mode": "remote",
"host": "localhost",
"port": 40000
}
]
}
To start debugging:
- Open the Run and Debug view (Ctrl+Shift+D / Cmd+Shift+D)
- Select "Attach to Remote KubeVela" from the dropdown
- Click the green play button or press F5
IntelliJ IDEA / GoLand Configuration
-
Open Run/Debug Configurations:
- Navigate to
Run > Edit Configurations
- Navigate to
-
Add a New Configuration:
- Click the plus icon (+) and select
Go Remote
- Click the plus icon (+) and select
-
Configure Connection Settings:
- Name:
Remote Debug KubeVela - Host:
localhost(or the hostname where your cluster is accessible) - Port:
40000
- Name:
-
Save and Launch:
- Click
Applyand thenOK - Select your configuration and click the Debug button (Shift+F9)
- Click

Once connected, you'll see a message in the port forwarding terminal indicating active connections on port 40000.

Step 7: Debug with Breakpoints
Set a Breakpoint
- Open a source file in your IDE (e.g.,
pkg/webhook/core.oam.dev/v1beta1/componentdefinition/validating_handler.go) - Click in the gutter next to a line number to set a breakpoint
- The breakpoint will be marked with a red dot
Trigger the Breakpoint
Create a test manifest to trigger your breakpoint. For example, create component.yaml:
apiVersion: core.oam.dev/v1beta1
kind: ComponentDefinition
metadata:
name: configmap-component
spec:
workload:
definition:
apiVersion: v1
kind: ConfigMap
schematic:
cue:
template: |
parameter: {
firstkey: string
secondkey: string
}
output: {
apiVersion: "v1"
kind: "ConfigMap"
metadata: {
name: context.name
}
data: {
firstkey: parameter.firstkey
secondkey: parameter.secondkey
data: "10"
}
}
Apply the manifest:
kubectl apply -f component.yaml