引言:为什么 Go 和 Kubernetes 是完美搭档
Go(Golang)和 Kubernetes 是现代开发中的两个关键工具。Go 由 Google 创建,是一种编译型、静态类型的语言,非常适合构建高性能微服务。而 Kubernetes 是容器编排的事实标准。两者的结合提供了强大的生态系统:你用 Go 编写轻量、快速的代码,将其打包成 Docker 镜像,然后由 Kubernetes 管理其部署、扩展和恢复。
在本指南中,我们将逐步将一个简单的 Go 应用程序部署到 Kubernetes 上。你将学习如何编写 Dockerfile、创建 Deployment 和 Service 清单,并在集群中应用它们。本文面向已经熟悉 Go 基础知识并对 Docker 有基本了解的开发者。
第一步:创建并容器化一个 Go 应用程序
我们从 Go 中的一个简单 HTTP 服务器开始。创建一个文件 main.go:
package main
import ( "fmt" "net/http" "os")
func main() { port := os.Getenv("PORT") if port == "" { port = "8080" } http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, "Hello from Go on Kubernetes!") }) http.ListenAndServe(":"+port, nil)}这段代码监听 PORT 环境变量指定的端口(默认为 8080),并返回一条简单的消息。
构建 Docker 镜像
现在我们来创建一个用于多阶段构建的 Dockerfile——这能减小最终镜像的大小:
# Build stageFROM golang:1.21-alpine AS builderWORKDIR /appCOPY go.mod go.sum ./RUN go mod downloadCOPY . .RUN CGO_ENABLED=0 GOOS=linux go build -o /app/server .
# Final imageFROM 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:v1 .docker push yourusername/go-k8s-app:v1第二步:Deployment 清单
Kubernetes 使用 YAML 清单来描述集群的期望状态。创建一个文件 deployment.yaml:
apiVersion: apps/v1kind: Deploymentmetadata: name: go-app-deployment labels: app: go-appspec: replicas: 3 selector: matchLabels: app: go-app template: metadata: labels: app: go-app spec: containers: - name: go-app image: yourusername/go-k8s-app:v1 ports: - containerPort: 8080 env: - name: PORT value: "8080" readinessProbe: httpGet: path: / port: 8080 initialDelaySeconds: 5 periodSeconds: 10 livenessProbe: httpGet: path: / port: 8080 initialDelaySeconds: 15 periodSeconds: 20关键字段说明:
replicas: 3— Kubernetes 将保持应用程序的 3 个运行实例(Pod)。readinessProbe— 检查 Pod 是否已准备好接受流量(向 / 发送请求)。livenessProbe— 检查 Pod 是否存活;如果不存活,Kubernetes 将重新启动它。
第三步:Service 清单
为了使应用程序能够在集群内部或从外部被访问,需要创建一个 Service。创建 service.yaml:
apiVersion: v1kind: Servicemetadata: name: go-app-servicespec: selector: app: go-app ports: - protocol: TCP port: 80 targetPort: 8080 type: LoadBalancerselector— 将 Service 与具有该标签的 Pod 关联起来