引言:为什么Go和Kubernetes是理想组合
Go(Golang)和Kubernetes是构建和部署微服务架构的现代标准。Go编译为静态二进制文件,在目标机器上无需依赖,启动速度快且内存使用高效。而Kubernetes则提供了容器部署、扩展和管理的自动化能力。
在本指南中,我们将实际操作,完整解析一个简单Go应用在Kubernetes上的部署流程。您将学习如何编写Dockerfile,创建Kubernetes清单(Deployment、Service、ConfigMap),并在集群中运行应用。所有代码示例均可直接用于您自己的项目。
1. 准备用于容器化的Go应用
首先,我们创建一个简单的Go HTTP服务器,用于响应请求并输出问候语。重要的是,应用需要监听我们通过环境变量指定的端口。这是Kubernetes的标准做法。
创建文件 main.go:
package main
import ( "fmt" "log" "net/http" "os")
func main() { port := os.Getenv("PORT") if port == "" { port = "8080" }
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { name := os.Getenv("APP_NAME") if name == "" { name = "Go App" } fmt.Fprintf(w, "来自%s的问候!在端口%s上运行", name, port) })
log.Printf("服务器已在端口%s上启动", port) log.Fatal(http.ListenAndServe(":"+port, nil))}这段代码读取环境变量 PORT 和 APP_NAME,这将使我们能够通过Kubernetes中的ConfigMap灵活配置应用。
2. 为Go应用创建Dockerfile
为了部署到Kubernetes,我们需要一个Docker镜像。我们使用多阶段构建(multi-stage build)——这可以减小镜像大小并提高安全性。
创建文件 Dockerfile:
# 构建阶段FROM golang:1.22-alpine AS builder
WORKDIR /appCOPY go.mod go.sum ./RUN go mod downloadCOPY . .RUN CGO_ENABLED=0 GOOS=linux go build -o /app/server .
# 最终镜像FROM alpine:latestRUN apk --no-cache add ca-certificatesWORKDIR /root/COPY --from=builder /app/server .EXPOSE 8080CMD ["./server"]构建镜像并将其推送到仓库(例如Docker Hub):
docker build -t yourusername/go-k8s-app:latest .docker push yourusername/go-k8s-app:latest3. Kubernetes清单:Deployment、Service、ConfigMap
现在,我们创建用于在集群中部署应用的清单文件。建议将它们存放在 k8s/ 文件夹中。
3.1. 用于配置的ConfigMap
我们将应用设置提取到ConfigMap中——这样可以在不重新构建镜像的情况下更改它们。
文件 k8s/configmap.yaml:
apiVersion: v1kind: ConfigMapmetadata: name: go-app-configdata: APP_NAME: "我的Go应用" PORT: "8080"3.2. Deployment——Pod的描述
Deployment管理Pod的副本,并确保无停机更新。
文件 k8s/deployment.yaml:
apiVersion: apps/v1kind: Deploymentmetadata: name: go-app-deployment labels: app: go-appspec: replicas: 2 selector: matchLabels: app: go-app template: metadata: labels: app: go-app spec: containers: - name: go-app image: yourusername/go-k8s-app:latest ports: - containerPort: 8080 envFrom: - configMapRef: name: go-app-config livenessProbe: httpGet: path: / port: 8080 initialDelaySeconds: 5 periodSeconds: 10\