背景
作为一名后端开发工程师(主要使用 Go),我希望了解运维的完整工作流程。本文记录了我在 Windows 系统下,使用 Kind 创建本地 Kubernetes 集群,部署 Go 服务,并集成独立运行的 Traefik 作为 Ingress 控制器实现负载均衡的过程。
环境准备
-
操作系统: Windows
-
开发语言: Go 1.17 (公司标准版本)
-
目标工具: Kind (Kubernetes IN Docker)
步骤 1: 安装 Kind
Github地址:kubernetes-sigs/kind: Kubernetes IN Docker - local clusters for testing Kubernetes
安装命令
利用已有的 Go 1.17 环境,通过 Go 命令安装 Kind:
go install sigs.k8s.io/kind@v0.11.1
验证安装
# 验证安装
kind version
kubectl version --client
步骤 2: 创建 Kubernetes 集群
使用 Kind 创建本地集群:
kind create cluster
验证集群:
kubectl cluster-info --context kind-kind
或者
kind get clusters
步骤 3: 安装独立 Traefik(这一步略过)
使用 Docker Compose 在主机上独立运行 Traefik(不部署到 Kind 集群内)。
文件:docker-compose.yaml
services:
traefik:
image: traefik:v2.10 # 推荐稳定版,避免 beta 版本:cite[1]:cite[5]
ports:
- "80:80" # HTTP 入口
- "8080:8080" # Dashboard 端口
command:
- "--api.insecure=true" # 启用非加密 Dashboard(仅测试用)
- "--providers.docker=true" # 启用 Docker 提供器
- "--entrypoints.web.address=:80"
- "--providers.file.filename=/etc/traefik/dynamic.yml"
- "--providers.file.watch=true"
- "--entrypoints.web.address=:80"
- "--log.level=DEBUG" # 增加调试日志
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro # 关键:允许 Traefik 监听 Docker 事件:cite[1]:cite[4]:cite[6]
- ./traefik-dynamic.yml:/etc/traefik/dynamic.yml # 添加动态配置文件
操作步骤:
-
保存为
docker-compose.yml
; -
执行启动命令:
powershell
docker-compose up -d
-
访问 Dashboard:
http://localhost:8080/dashboard/
步骤 4: 构建并部署 Go 服务到 Kind 集群
1.构建go服务
package main
import (
"fmt"
"net/http"
"os"
)
func main() {
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
hostname, _ := os.Hostname()
fmt.Fprintf(w, "Hello from %s! Request path: %s\n", hostname, r.URL.Path)
})
port := ":8080"
fmt.Printf("Server running on port %s\n", port)
http.ListenAndServe(port, nil)
}
2.构建Dockerfile
FROM golang:1.21-alpine AS builder
WORKDIR /app
COPY . .
RUN go build -o server .
FROM alpine:latest
WORKDIR /app
COPY --from=builder /app/server .
EXPOSE 8080
CMD ["./server"]
3.构建go服务镜像
docker build -t hello:1.0 .
4.加载镜像到 Kind 集群:
kind load docker-image hello:1.0 --name kind
5.应用 Deployment/Service/Ingress:
(这个yaml文件放在哪个目录下不重要)
# hello-go.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: hello-go
spec:
replicas: 3
selector:
matchLabels:
app: hello-go
template:
metadata:
labels:
app: hello-go
spec:
containers:
- name: hello-go
image: hello:1.0
ports:
- containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
name: hello-go-service
spec:
selector:
app: hello-go
ports:
- protocol: TCP
port: 80
targetPort: 8080
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: hello-go-ingress
spec:
rules:
- http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: hello-go-service
port:
number: 80
kubectl apply -f hello.yaml
验证负载均衡
kubectl -n kube-system get svc traefik
步骤 5: 集成 Traefik 与 Kind 服务 (负载均衡配置)
问题发现: 负载均衡验证报错:Error from server (NotFound): services "traefik" not found
原因分析: 根据我的配置分析,Traefik 是通过 Docker Compose 独立安装的(不在 Kubernetes 集群内),而我的 hello 服务部署在 Kind 创建的 Kubernetes 集群中。因此,在 Kubernetes 集群内执行 kubectl -n kube-system get svc traefik
命令会报错,因为 Traefik 服务并不在 Kubernetes 集群中。
解决方案:要验证负载均衡,我们需要让独立运行的 Traefik 能够将流量转发到 Kind 集群中的 hello 服务。以下是完整的解决方案:
配置步骤
1. 暴露 Kind 集群中的 hello 服务
# 确保 hello 服务已部署并运行
kubectl get pods,svc
在这个目录下建一个json文件,并执行命令:
kubectl patch svc hello-go-service --patch-file patch-svc.json
示例(文件目录):
验证:
再次执行命令:kubectl get pods,svc验证是否修改成功
获取关键网络信息:
获取NodePort端口
# 获取 NodePort 端口
$NODE_PORT = (kubectl get svc hello-go-service -o jsonpath='{.spec.ports[0].nodePort}')
echo "NodePort: $NODE_PORT"
获取结果示例
获取容器IP地址
# 获取 Kind 控制平面容器的 IP 地址
$KIND_IP = (docker inspect -f '{{range.NetworkSettings.Networks}}{{.IPAddress}}{{end}}' kind-control-plane)
echo "Kind Node IP: $KIND_IP"
获取结果示例
2. 配置 Traefik 连接到 Kind 服务
更新 docker-compose.yml
:
services:
traefik:
image: traefik:v2.10 # 推荐稳定版,避免 beta 版本:cite[1]:cite[5]
ports:
- "80:80" # HTTP 入口
- "8080:8080" # Dashboard 端口
command:
- "--api.insecure=true" # 启用非加密 Dashboard(仅测试用)
- "--providers.docker=true" # 启用 Docker 提供器
- "--entrypoints.web.address=:80"
- "--providers.file.filename=/etc/traefik/dynamic.yml"
- "--providers.file.watch=true"
- "--entrypoints.web.address=:80"
- "--log.level=DEBUG" # 增加调试日志
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro # 关键:允许 Traefik 监听 Docker 事件:cite[1]:cite[4]:cite[6]
- ./traefik-dynamic.yml:/etc/traefik/dynamic.yml # 添加动态配置文件
创建 traefik-dynamic.yml
配置文件(和traefik的docker-compose文件路径一致):
http:
routers:
hello-router:
rule: "Host(`hello.local`)"
service: hello-service
entryPoints: # 新增:关联到 80 端口的 web 入口点
- web
services:
hello-service:
loadBalancer:
servers:
- url: "http://172.18.0.2:32599" # 使用上一步获取的值# 例如:- url: "http://172.18.0.3:32456"
3. 创建共享网络(关键步骤)
# 获取 Kind 集群使用的网络名称
$KIND_NETWORK = (docker inspect kind-control-plane -f '{{range $net,$v := .NetworkSettings.Networks}}{{$net}}{{end}}')
# 将 Traefik 连接到 Kind 网络(docker-compose所在目录运行)
docker network connect $KIND_NETWORK $(docker-compose ps -q traefik)
# 验证网络连接
docker network inspect $KIND_NETWORK | Select-String "traefik"
4. 重启 Traefik 并验证配置
docker-compose down
docker-compose up -d
# 检查 Traefik 日志
docker-compose logs traefik | Select-String "hello-service"
# 查看路由配置
# 访问 Traefik 路由配置 API
curl http://localhost:8080/api/http/routers/hello-router
5. 配置本地 hosts 文件
在 C:\Windows\System32\drivers\etc\hosts
文件中添加:
127.0.0.1 hello.local
步骤六:验证负载均衡
powershell中多次执行下面的命令:
# 多次访问服务
1..10 | ForEach-Object {
curl.exe http://hello.local
}
验证结果
PS D:\Docker\Traefik> 1..10 | ForEach-Object {
>> curl.exe http://hello.local
>> }
Hello from hello-go-797f7df469-kfsqh! Request path: /
Hello from hello-go-797f7df469-kfsqh! Request path: /
Hello from hello-go-797f7df469-kfsqh! Request path: /
Hello from hello-go-797f7df469-kfsqh! Request path: /
Hello from hello-go-797f7df469-kfsqh! Request path: /
Hello from hello-go-797f7df469-kfsqh! Request path: /
Hello from hello-go-797f7df469-kfsqh! Request path: /
Hello from hello-go-797f7df469-kfsqh! Request path: /
Hello from hello-go-797f7df469-kfsqh! Request path: /
Hello from hello-go-797f7df469-kfsqh! Request path: /
总结
通过以上步骤,成功在 Windows 下使用 Kind 创建了本地 Kubernetes 集群,部署了 Go 服务,并配置了独立运行的 Traefik 作为 Ingress 控制器,实现了外部访问 (hello.local
) 的负载均衡,流量被分发到集群内的多个 Pod 实例。这个过程涵盖了容器构建、集群管理、服务部署、网络配置和 Ingress 控制等关键运维环节。
未完待续......