k3d 本地部署
本文说明 ovra-zero 使用 k3d + Helm 在本地 Docker 环境中部署的流程。k3d 适合开发验证、演示和排查 Kubernetes 部署拓扑。
准备工作
| 工具 | 用途 |
|---|---|
| Docker | 运行 k3d 节点、构建镜像、运行外部 MySQL |
| k3d | 创建本地 Kubernetes 集群 |
| kubectl | 操作 Kubernetes 资源 |
| Helm | 安装和升级 Chart |
Go 1.24+ | 构建服务二进制 |
Chart 目录:
deploy/helm/ovra-zero
k3d 镜像 Dockerfile:
deploy/k3d/Dockerfile
部署拓扑
| 组件 | Kubernetes 资源 | 默认规模 | 说明 |
|---|---|---|---|
| auth | Deployment + Service | 1 | 登录、验证码、租户列表 |
| system | Deployment + Service | 1 | 系统 API 和 system RPC |
| demo | Deployment + Service | 1 | 示例业务 API 和 demo RPC |
| etcd | StatefulSet + Headless Service | 3 | RPC 服务发现 |
| Redis Cluster | StatefulSet + 初始化 Job | 3 | 缓存和业务状态 |
| MySQL | 外部 Docker 容器 + EndpointSlice | 1 | 本地数据库 |
| Ingress | Traefik Ingress | 1 | 统一 HTTP 入口 |
默认路由:
| Path | Service |
|---|---|
/auth | auth:8091 |
/system | system:8092 |
/monitor | system:8092 |
/resource | system:8092 |
/demo | demo:8099 |
一键部署
项目提供脚本:
scripts/deploy-k3d.sh deploy
脚本会执行:
- 编译 Linux 版本的
app-auth、app-system、app-demo。 - 构建
ovra-zero:local镜像。 - 导入镜像到 k3d 集群。
- 自动检测
ovra-zero-mysql容器 IP。 - 执行
helm upgrade --install。 - 等待
auth、system、demorollout 完成。
重新安装 release:
scripts/deploy-k3d.sh redeploy
x86_64 环境:
PLATFORM=linux/amd64 GOARCH_TARGET=amd64 scripts/deploy-k3d.sh deploy
手动部署
1. 构建 Linux 二进制
ARM64:
mkdir -p .deploy/k3d/bin
GOOS=linux GOARCH=arm64 CGO_ENABLED=0 go build -ldflags='-s -w' -tags no_k8s -o .deploy/k3d/bin/app-auth app/auth/auth.go
GOOS=linux GOARCH=arm64 CGO_ENABLED=0 go build -ldflags='-s -w' -tags no_k8s -o .deploy/k3d/bin/app-system app/system/system.go
GOOS=linux GOARCH=arm64 CGO_ENABLED=0 go build -ldflags='-s -w' -tags no_k8s -o .deploy/k3d/bin/app-demo app/demo/demo.go
x86_64 将 GOARCH=arm64 改为 GOARCH=amd64。
2. 构建并导入镜像
ARM64:
docker build --platform linux/arm64 -t ovra-zero:local -f deploy/k3d/Dockerfile .
k3d image import ovra-zero:local -c ovra
x86_64 将 --platform linux/arm64 改为 --platform linux/amd64。
3. 准备 MySQL
本地 k3d 推荐使用同一个 Docker 网络中的外部 MySQL:
docker run -d --name ovra-zero-mysql --network k3d-ovra \
-e MYSQL_ROOT_PASSWORD='Pl@1221view' \
-e MYSQL_DATABASE=ovra_zero \
-v "$PWD/bin/sql/ovra_zero.sql:/docker-entrypoint-initdb.d/ovra_zero.sql:ro" \
mysql:8.4
查看 MySQL 容器 IP:
docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' ovra-zero-mysql
4. 安装 Helm Chart
helm upgrade --install ovra-zero deploy/helm/ovra-zero \
--namespace ovra-zero \
--create-namespace \
--wait \
--timeout 5m \
--set image.repository=ovra-zero \
--set image.tag=local \
--set config.mountPath=/app/etc/config \
--set ingress.className=traefik \
--set ingress.host=ovra-zero.localhost \
--set mysql.internal.enabled=false \
--set mysql.external.enabled=true \
--set mysql.external.ip=<MYSQL_CONTAINER_IP>
核心配置
配置文件:
deploy/helm/ovra-zero/values.yaml
Redis Cluster:
redis:
password: Pl@1221view
port: 6379
busPort: 16379
cluster:
replicas: 3
replicasPerMaster: 0
etcd:
etcd:
port: 2379
peerPort: 2380
replicas: 3
Ingress:
ingress:
enabled: true
className: traefik
host: ovra-zero.localhost
应用配置模板位于:
deploy/helm/ovra-zero/files/config/*.gotmpl
Helm 会渲染 etcd、Redis Cluster 和 MySQL 地址,并写入 ConfigMap ovra-zero-config。
验证系统
查看资源:
kubectl -n ovra-zero get pods,svc,statefulset,ingress,endpointslice
等待应用:
kubectl -n ovra-zero rollout status deployment/auth --timeout=5m
kubectl -n ovra-zero rollout status deployment/system --timeout=5m
kubectl -n ovra-zero rollout status deployment/demo --timeout=5m
验证 etcd:
kubectl -n ovra-zero exec etcd-0 -- etcdctl \
--endpoints=http://etcd-0.etcd-headless.ovra-zero.svc.cluster.local:2379,http://etcd-1.etcd-headless.ovra-zero.svc.cluster.local:2379,http://etcd-2.etcd-headless.ovra-zero.svc.cluster.local:2379 \
member list
验证 Redis:
kubectl -n ovra-zero exec redis-0 -- redis-cli -a 'Pl@1221view' cluster info
kubectl -n ovra-zero exec redis-0 -- redis-cli -a 'Pl@1221view' cluster nodes
验证入口:
curl -sS http://ovra-zero.localhost:18080/auth/code
常见问题
k3d 节点 NotReady
kubectl get nodes -o wide
docker restart k3d-ovra-agent-1
替换成实际 NotReady 的节点容器名。
MySQL EndpointSlice IP 变化
Docker 重启后,外部 MySQL 容器 IP 可能变化:
docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' ovra-zero-mysql
kubectl -n ovra-zero get endpointslice mysql-external -o yaml
如果 IP 不一致,更新 Helm:
helm upgrade ovra-zero deploy/helm/ovra-zero \
--namespace ovra-zero \
--set mysql.external.ip=<MYSQL_CONTAINER_IP> \
--wait \
--timeout 5m
Redis Cluster 状态异常
查看状态:
kubectl -n ovra-zero exec redis-0 -- redis-cli -a 'Pl@1221view' cluster info
kubectl -n ovra-zero logs job/redis-cluster-init
开发环境可重建 Redis:
kubectl -n ovra-zero delete statefulset redis --ignore-not-found
kubectl -n ovra-zero delete pod -l app.kubernetes.io/component=redis --ignore-not-found
kubectl -n ovra-zero delete job redis-cluster-init --ignore-not-found
helm upgrade ovra-zero deploy/helm/ovra-zero -n ovra-zero --wait --timeout 5m
应用使用旧配置
Chart 会给 Deployment 添加配置校验和,配置变化通常会自动滚动。必要时手动重启:
kubectl -n ovra-zero rollout restart deployment/auth deployment/system deployment/demo