引言:为什么 Go 和 Kubernetes 是理想组合
\n\n现代开发越来越依赖于微服务架构和容器化。Go 语言 (Golang) 凭借其高性能、简洁性以及对并发的原生支持,已成为编写后端服务的主流语言之一。与此同时,Kubernetes (K8s) 是容器编排的事实标准。
\n\n将 Go 应用部署到 Kubernetes 的过程,对于新手来说可能显得复杂。然而,遵循本分步指南,您可以在几分钟内配置好 CI/CD 流水线并启动您的服务。在本文中,我们将介绍如何创建 Docker 镜像、编写 Kubernetes 清单文件、配置服务和 Ingress,并提供一些实用的优化建议。
\n\n1. 准备 Go 应用和 Dockerfile
\n\n在将应用部署到集群之前,需要将其打包到容器中。由于 Go 支持静态编译,这一过程尤其方便。
\n\n1.1. 一个简单的 Go HTTP 服务器示例
\n\n让我们创建一个最小的服务器来响应请求。这是一个典型的用于演示的微服务。
\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\n1.2. 多阶段构建 Dockerfile
\n\n我们使用多阶段构建 (multi-stage build) 来最小化最终镜像的大小。这对于快速加载到集群至关重要。
\n\n# ---- 第一阶段:编译二进制文件 ----\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# ---- 第二阶段:最小化镜像 ----\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重要提示: 标志 CGO_ENABLED=0 禁用了 CGO,从而可以编译出完全静态的二进制文件,无需依赖外部库。
2. 创建 Kubernetes 清单文件
\n\n现在我们已经有了镜像,需要描述 Kubernetes 如何管理我们的应用。主要对象包括:Deployment(用于管理副本)和 Service(用于网络访问)。
\n\n2.1. Deployment
\n\nDeployment 确保运行所需数量的 Pod(包含我们的应用)。配置 liveness 和 readiness probes 对于自动恢复非常重要。
\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