Debugging Go programs
running in a Kubernetes Pod
using Delve with GoLand
by Mike Schinkel on May 4th, 2023
github.com/mikeschinkel
Or more accurately:
25+ years involved with dev as
Contractor with these teams:
Currently:
youtube.com/@gearboxworks
K3s — k3s.io
A lightweight distro of K8s
k3d — k3d.io
Runs a K3s cluster in a Docker container
Delve — github.com/go-delve
The defacto-standard debugger for Go
package main
import (
"fmt"
"time"
)
const (
DateFormat = "2006-01-02 3:04:05PM"
DelayTime = 5
)
// Debug with Go Remote = localhost:8765
func main() {
fmt.Println("Starting Debuggable Pod")
for {
dt := time.Now().Format(DateFormat)
fmt.Printf("\n[%s] Hello World!", dt)
time.Sleep(DelayTime * time.Second)
}
}
# PRESENTING CODE
module debuggable-pod
go 1.19
# PRESENTING CODE
---
apiVersion: k3d.io/v1alpha4
kind: Simple
servers: 1
kubeAPI:
hostPort: "6443"
image: rancher/k3s:v1.23.8-k3s1
registries:
use:
- k3d-registry.localhost:5000
options:
k3d:
wait: true
timeout: "60s"
ports:
- port: 8765:30800
nodeFilters:
- server:0
# PRESENTING CODE
---
apiVersion: v1
kind: Pod
metadata:
name: debuggable-pod
labels:
debugger: dlv
annotations:
container.apparmor.security.beta.kubernetes.io/debuggable-app-container: unconfined
spec:
restartPolicy: Always
containers:
- name: debuggable-app-container
image: k3d-registry.localhost:5000/debuggable-app-image
imagePullPolicy: Always
securityContext:
capabilities:
add:
- SYS_PTRACE
ports:
- containerPort: 32345
hostPort: 32345
protocol: TCP
# PRESENTING CODE
---
apiVersion: v1
kind: Service
metadata:
name: dlv-port-service
spec:
type: NodePort
selector:
debugger: dlv
ports:
- name: dlv-port
protocol: TCP
port: 32345
nodePort: 30800
# PRESENTING CODE
FROM golang:1.19-alpine AS builder
ENV CGO_ENABLED=0
RUN apk update \
&& apk add --no-cache git \
&& go install github.com/go-delve/delve/cmd/dlv@v1.9.1
WORKDIR /app
COPY . /app
RUN go build -o debuggable-go-app -gcflags="all=-N -l" /app/main.go
EXPOSE 32345 32345
CMD [ "dlv", \
"--listen=:32345", \
"--headless=true", \
"--api-version=2", \
"--accept-multiclient", \
"exec", "/app/debuggable-go-app"]
# PRESENTING CODE
git clone https://github.com/mikeschinkel/go-debuggable-k3d-pod
make install # Installs required software
make init # Initializes k3d registry and cluster
make build # Builds the Go App and Docker container
make deploy # Push container to K8s registry, apply Pod YAML
# PRESENTING CODE
# DEMONSTRATION
Commands | Notice |
---|---|
docker ps | Images, ports for proxy |
kubectl get all | Names, service ports |
kubectl exec -it pod/debuggable-pod -- sh | |
top | PID 1's command |
ls -al | files |
kubectl logs pods/debuggable-pod |
Output |
# DEMONSTRATION
Component | Port |
---|---|
The K8s Cluster | 8765 |
The K8s Pod | 30800 |
The Go App | 32345 |
You can use any available port numbers here, they just need to be used in the right places.
github.com/mikeschinkel/go-debuggable-k3d-pod
(Again, find the code here:)
Who am I, again? | Mike Schinkel |
Code | github.com/mikeschinkel/go-debuggable-k3d-pod |
These Slides | slides.com/mikeschinkel/debugging-go-apps-in-k8s |
YouTube channel (Coming soon) |
www.youtube.com/@gearboxworks |
Available for contract work | mike@newclarity.net |
My LinkedIn | www.linkedin.com/in/mikeschinkel |