Deploying Go on Kubernetes: A Basic Practical Guide

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

Introduction: Why Go and Kubernetes are the Perfect Pair

\n\n

Modern development increasingly relies on microservice architecture and containerization. The Go language (Golang), thanks to its performance, simplicity, and native support for concurrency, has become one of the leaders for writing backend services. At the same time, Kubernetes (K8s) is the de facto standard for container orchestration.

\n\n

Deploying a Go application on Kubernetes is a process that may seem complex to beginners. However, by following a step-by-step guide, you can set up a CI/CD pipeline and launch your service in minutes. In this article, we will cover creating a Docker image, writing Kubernetes manifests, configuring services and Ingress, and provide practical optimization tips.

\n\n

1. Preparing the Go Application and Dockerfile

\n\n

Before deploying the application to a cluster, you need to package it into a container. In Go, this is especially convenient thanks to static compilation.

\n\n

1.1. Example of a Simple HTTP Server in Go

\n\n

Let's create a minimal server that will respond to requests. This is a typical microservice for demonstration.

\n\n
// main.go\npackage main\n\nimport (\n    "fmt"\n    "net/http"\n    "os"\n)\n\nfunc main() {\n    port := os.Getenv("PORT")\n    if port == "" {\n        port = "8080"\n    }\n\n    http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {\n        fmt.Fprintf(w, "Hello from Go on Kubernetes!")\n    })\n\n    http.HandleFunc("/health", func(w http.ResponseWriter, r *http.Request) {\n        w.WriteHeader(http.StatusOK)\n        w.Write([]byte("OK"))\n    })\n\n    fmt.Printf("Server is running on port %s\\n", port)\n    http.ListenAndServe(":"+port, nil)\n}\n
\n\n

1.2. Multi-Stage Dockerfile Build

\n\n

We use a multi-stage build to minimize the size of the final image. This is critically important for fast loading into the cluster.

\n\n
# ---- First stage: build the binary ----\nFROM golang:1.21-alpine AS builder\n\nWORKDIR /app\nCOPY go.mod go.sum ./\nRUN go mod download\n\nCOPY . .\nRUN CGO_ENABLED=0 GOOS=linux go build -o /app/server .\n\n# ---- Second stage: minimal image ----\nFROM alpine:latest\n\nRUN apk --no-cache add ca-certificates\n\nWORKDIR /root/\nCOPY --from=builder /app/server .\n\nEXPOSE 8080\n\nCMD ["./server"]\n
\n\n

Important: the CGO_ENABLED=0 flag disables CGO, which allows building a fully static binary that does not require external libraries.

\n\n

2. Creating Kubernetes Manifests

\n\n

Now that we have the image, we need to describe how Kubernetes will manage our application. The main objects are: Deployment (for managing replicas) and Service (for network access).

\n\n

2.1. Deployment

\n\n

A Deployment ensures that the required number of Pods with our application are always running. It is important to configure liveness and readiness probes for automatic recovery.

\n\n
// deployment.yaml\napiVersion: apps/v1\nkind: Deployment\nmetadata:\n  name: go-app\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: your-dockerhub-username/go-app:latest\n        ports:\n        - containerPort: 8080\n        env:\n        - name: PORT\n          value: "8080"\n        livenessProbe:\n          httpGet:\n            path: /health\n            port: 8080\n          initialDelaySeconds: 5\n          periodSeconds: 10\n        readinessProbe:\n          httpGet:\n            path: /health\n            port: 8080\n          initialDelaySeconds: 3\n          periodSeconds: 5\n        resources:\n          requests:\n            memory: "64Mi"\n                

Blogs

Book Recommendations