Introduction: Why Go and Kubernetes are the Perfect Pair
\n\nGo (Golang) and Kubernetes (K8s) are made for each other. Kubernetes itself is written in Go, so the native tooling, performance, and ease of deployment make this combination the standard for modern microservices. If you are just starting your journey in DevOps or want to automate the deployment of your Go application, this guide will help you through all the stages: from writing a simple HTTP server in Go to running it in a Kubernetes cluster.
\n\nIn this article, we will cover:
\n- \n
- Building a Go application into a Docker image \n
- Creating minimal Kubernetes manifests (Deployment, Service, Ingress) \n
- Deployment and health check verification \n
It is assumed that you already have docker, kubectl, and minikube installed (or access to any K8s cluster).
Step 1: Write a Simple Go Application
\n\nLet's create a basic HTTP server that will respond to requests. Create a file named main.go:
package main\n\nimport (\n "fmt"\n "net/http"\n "os"\n)\n\nfunc main() {\n http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {\n fmt.Fprintf(w, "Hello from Go! Version: %s", os.Getenv("APP_VERSION"))\n })\n\n port := os.Getenv("PORT")\n if port == "" {\n port = "8080"\n }\n\n fmt.Printf("Server started on port %s\\n", port)\n http.ListenAndServe(":"+port, nil)\n}\n\n\nThis application reads the APP_VERSION environment variable (can be set during deployment) and listens on the port specified in PORT. Now let's test it locally:
go run main.go\n# Open your browser at http://localhost:8080\n\n\nCreate a Go Module
\nInitialize the module for convenient building:
\ngo mod init my-go-app\n\n\nStep 2: Containerization with Docker
\n\nTo deploy to Kubernetes, you need to package the application into a Docker image. We will use a multi-stage build to keep the image minimal.
\n\nCreate a file named Dockerfile:
# Build stage\nFROM golang:1.22-alpine AS builder\nWORKDIR /app\nCOPY go.mod ./\nCOPY main.go ./\nRUN go build -o my-app .\n\n# Final image\nFROM alpine:3.19\nWORKDIR /app\nCOPY --from=builder /app/my-app .\nEXPOSE 8080\nCMD ["./my-app"]\n\n\nBuild the image and verify it:
\ndocker build -t my-go-app:v1 .\ndocker run -p 8080:8080 my-go-app:v1\n# http://localhost:8080\n\n\nStep 3: Kubernetes Manifests
\n\nNow let's prepare YAML files for deployment in the cluster. We will create three resources: Deployment (pod management), Service (network access), and Ingress (external access).
\n\n3.1. Deployment
\nCreate a file named deployment.yaml:
apiVersion: apps/v1\nkind: Deployment\nmetadata:\n name: go-app-deployment\n labels:\n app: go-app\nspec:\n replicas: 2\n selector:\n matchLabels:\n app: go-app\n template:\n metadata:\n labels:\n app: go-app\n spec:\n containers:\n - name: go-app\n image: my-go-app:v1\n ports:\n - containerPort: 8080\n env:\n - name: APP_VERSION\n value: "1.0.0"\n - name: PORT\n value: "8080"\n livenessProbe:\n httpGet:\n path: /\n port: 8080\n initialDelaySeconds: 5\n periodSeconds: 10\n\n\nHere we set 2 replicas, a liveness probe, and environment variables.
\n\n3.2. Service
\nCreate a file named service.yaml for internal access:
apiVersion: v1\nkind: Service\nmetadata:\n name: go-app-service\nspec:\n selector:\n app: go-app\n ports:\n - protocol: TCP\n port: 80\n targe