feat: 三种部署方式全部验证通过
方案1: docker-compose 双容器(原有,不变) 方案2: 二进制部署(go:embed 前端嵌入) - 修复 SPA fallback(c.FileFromFS 301 → c.Data 直接返回) - 二进制 22MB,内存 21.5MB - 支持全部 CLI 参数(--db-host --redis-host --port 等) 方案3: K8s 部署(hostNetwork + 外部 MySQL/Redis) - devops 声明空间 - embed 单容器 Deployment + NodePort Service - 健康检查改为 /version(/health 尚未实现) - hostNetwork 解决 K8s pod 网络到外部 MySQL 的连通性 新增: Dockerfile.embed, docker-compose.embed.yml, deploy/binary/
This commit is contained in:
1 parent
4631b02f13
commit
2a0521340f
15 files changed
+734
-488
No files matched your search
+79
-86
@@ -2,6 +2,8 @@
|
||||
|
||||
AIOps 平台在 Kubernetes 上的部署清单(Go/Gin 后端 + go:embed 前端 + MySQL 8.0 + Redis 7)。
|
||||
|
||||
**单容器架构**:前端通过 `go:embed` 嵌入后端二进制,一个容器同时服务 API + WebSocket + SPA 静态资源,端口统一 8080。
|
||||
|
||||
所有资源部署在 **`devops`** 命名空间。
|
||||
|
||||
## 目录结构
|
||||
@@ -9,150 +11,141 @@ AIOps 平台在 Kubernetes 上的部署清单(Go/Gin 后端 + go:embed 前端
|
||||
| 文件 | 说明 |
|
||||
|------|------|
|
||||
| `namespace.yaml` | `devops` 命名空间 |
|
||||
| `configmap.yaml` | 后端 `config.yaml`(ConfigMap)+ MySQL/JWT 密码(Secret) |
|
||||
| `mysql.yaml` | MySQL 8.0 StatefulSet + Headless/ClusterIP Service + 8Gi 持久卷 |
|
||||
| `redis.yaml` | Redis 7 StatefulSet + Headless/ClusterIP Service + 2Gi 持久卷 |
|
||||
| `backend.yaml` | 后端 Deployment(端口 8080=API/WS,80=embed 前端)+ ClusterIP Service |
|
||||
| `ingress.yaml` | Ingress:`/api`、`/ws` → 8080;`/` → 80 |
|
||||
| `secret.yaml` | MySQL/JWT 密码(Secret) |
|
||||
| `configmap.yaml` | 后端 `config.yaml`(ConfigMap) |
|
||||
| `mysql.yaml` | MySQL 8.0 StatefulSet + Headless Service + 10Gi 持久卷 |
|
||||
| `redis.yaml` | Redis 7 StatefulSet + Headless Service + 2Gi 持久卷 |
|
||||
| `deployment.yaml` | AIOps Deployment(embed 单端口 8080)+ NodePort Service (30080) |
|
||||
| `ingress.yaml` | Ingress:所有流量 → aiops:8080(含 WebSocket 支持) |
|
||||
|
||||
## 架构与端口
|
||||
## 架构
|
||||
|
||||
```
|
||||
┌──────────────── Ingress (nginx) ────────────────┐
|
||||
/api, /ws ──▶│ │──▶ aiops-backend:8080 (API + WebSocket)
|
||||
/ ──▶│ │──▶ aiops-backend:80 (go:embed 前端)
|
||||
└──────────────────────────────────────────────────┘
|
||||
│
|
||||
┌──────────────┴──────────────┐
|
||||
▼ ▼
|
||||
aiops-backend aiops-backend
|
||||
│ (DB_HOST=mysql) │ (REDIS_HOST=redis)
|
||||
▼ ▼
|
||||
MySQL 8.0 (StatefulSet) Redis 7 (StatefulSet)
|
||||
aiops / aiops_pass_2026 无密码, db 0
|
||||
数据库 aiops, 8Gi PV 2Gi PV
|
||||
NodePort:30080 / Ingress
|
||||
│
|
||||
▼
|
||||
┌─── aiops (Deployment) ───┐
|
||||
│ 单端口 8080: │
|
||||
│ • API (/api/*) │
|
||||
│ • WebSocket (/ws/*) │
|
||||
│ • 前端 SPA (go:embed) │
|
||||
└───────────┬───────────────┘
|
||||
│
|
||||
┌──────────────┼──────────────┐
|
||||
▼ ▼
|
||||
MySQL 8.0 Redis 7
|
||||
(StatefulSet) (StatefulSet)
|
||||
mysql:3306 redis:6379
|
||||
10Gi PV 2Gi PV
|
||||
```
|
||||
|
||||
- **8080**:API + WebSocket
|
||||
- **80**:前端(go:embed 嵌入后端二进制,由后端进程提供静态资源)
|
||||
- 配置文件 `config.yaml` 中 DB/Redis 连接均以环境变量 `${VAR}` 占位,由 Deployment 的 `env` 注入;密码走 Secret。
|
||||
## 快速部署
|
||||
|
||||
## 前置条件
|
||||
### 方式一:run.sh 一键部署(推荐)
|
||||
|
||||
1. 一个可用的 Kubernetes 集群(≥ 1.22)。
|
||||
2. 已安装 **nginx Ingress Controller**。
|
||||
3. 集群具备可用的 **StorageClass**(MySQL/Redis 的 `volumeClaimTemplates` 依赖动态卷供应)。
|
||||
- minikube / kind 自带默认 StorageClass(如 `standard`)。
|
||||
- 如需指定,取消各 StatefulSet 中 `storageClassName` 的注释。
|
||||
4. 后端镜像 `aiops-backend:latest` 已构建并推送到集群可访问的镜像仓库(或本地 `kind load docker-image` / `minikube image load`)。
|
||||
```bash
|
||||
# 构建镜像 + 部署全部资源
|
||||
./run.sh k8s deploy
|
||||
|
||||
## 部署步骤
|
||||
# 查看状态
|
||||
./run.sh k8s status
|
||||
|
||||
按顺序 apply(资源间存在依赖:Secret → 数据库 → 后端 → Ingress):
|
||||
# 查看日志
|
||||
./run.sh k8s logs
|
||||
|
||||
# 更新(重新构建镜像 + 滚动更新)
|
||||
./run.sh k8s upgrade
|
||||
|
||||
# 清理
|
||||
./run.sh k8s delete
|
||||
```
|
||||
|
||||
### 方式二:手动 kubectl
|
||||
|
||||
```bash
|
||||
cd deploy/k8s
|
||||
|
||||
# 1. 命名空间(必须最先)
|
||||
# 1. 全量部署(文件按序: namespace → secret → configmap → mysql → redis → deployment)
|
||||
kubectl apply -f namespace.yaml
|
||||
|
||||
# 2. 配置 + 密码(ConfigMap / Secret)
|
||||
kubectl apply -f secret.yaml
|
||||
kubectl apply -f configmap.yaml
|
||||
|
||||
# 3. MySQL(启动后自动建库 aiops 与用户 aiops)
|
||||
kubectl apply -f mysql.yaml
|
||||
|
||||
# 4. Redis
|
||||
kubectl apply -f redis.yaml
|
||||
|
||||
# 5. 等待数据库就绪
|
||||
# 2. 等待数据库就绪
|
||||
kubectl -n devops rollout status statefulset/mysql
|
||||
kubectl -n devops rollout status statefulset/redis
|
||||
|
||||
# 6. 后端
|
||||
kubectl apply -f backend.yaml
|
||||
kubectl -n devops rollout status deployment/aiops-backend
|
||||
# 3. 构建镜像(在本地)
|
||||
cd ../..
|
||||
docker build -f Dockerfile.embed -t aiops:embed .
|
||||
|
||||
# 7. Ingress(部署前修改 host 与 ingressClassName)
|
||||
# 4. 部署应用
|
||||
kubectl apply -f deployment.yaml
|
||||
kubectl -n devops rollout status deployment/aiops
|
||||
|
||||
# 5. Ingress(按需修改 host)
|
||||
kubectl apply -f ingress.yaml
|
||||
```
|
||||
|
||||
一键全量部署(文件名按字典序,namespace 会最先应用):
|
||||
|
||||
```bash
|
||||
kubectl apply -f deploy/k8s/
|
||||
```
|
||||
|
||||
## 访问
|
||||
|
||||
- 将 Ingress 中的 `host`(默认 `aiops.local`)解析到 Ingress Controller 的入口 IP:
|
||||
```bash
|
||||
echo "<INGRESS_IP> aiops.local" | sudo tee -a /etc/hosts
|
||||
```
|
||||
- 浏览器打开 `http://aiops.local` 即前端;API 在 `http://aiops.local/api`。
|
||||
```bash
|
||||
# NodePort 方式
|
||||
curl http://<NODE_IP>:30080/health
|
||||
|
||||
# 或配置 Ingress host
|
||||
echo "<INGRESS_IP> aiops.local" | sudo tee -a /etc/hosts
|
||||
# 浏览器: http://aiops.local
|
||||
```
|
||||
|
||||
## 常用运维命令
|
||||
|
||||
```bash
|
||||
# 查看所有资源
|
||||
kubectl -n devops get all,configmap,secret,ingress,pvc
|
||||
kubectl -n devops get all,pvc,configmap,secret
|
||||
|
||||
# 查看后端日志
|
||||
kubectl -n devops logs -f deployment/aiops-backend
|
||||
# 查看应用日志
|
||||
kubectl -n devops logs -f deployment/aiops
|
||||
|
||||
# 进入应用容器
|
||||
kubectl -n devops exec -it deployment/aiops -- bash
|
||||
|
||||
# 进入 MySQL
|
||||
kubectl -n devops exec -it mysql-0 -- mysql -uaiops -paiops_pass_2026 aiops
|
||||
|
||||
# 进入 Redis
|
||||
kubectl -n devops exec -it redis-0 -- redis-cli
|
||||
# 滚动更新(重新构建镜像后)
|
||||
kubectl -n devops rollout restart deployment/aiops
|
||||
|
||||
# 进入后端容器
|
||||
kubectl -n devops exec -it deployment/aiops-backend -- sh
|
||||
|
||||
# 查看 PVC 绑定状态
|
||||
# 查看 PVC
|
||||
kubectl -n devops get pvc
|
||||
```
|
||||
|
||||
## 配置与密码
|
||||
## 配置说明
|
||||
|
||||
| 项目 | 来源 | 值 |
|
||||
|------|------|----|
|
||||
| MySQL 业务账号 | Secret `aiops-secret` | 用户 `aiops` / 密码 `aiops_pass_2026` / 库 `aiops` |
|
||||
| MySQL root | Secret `aiops-secret` | `aiops_root_2026` |
|
||||
| JWT | Secret `aiops-secret` | `jwt-secret`(生产请替换为强随机值) |
|
||||
| JWT | Secret `aiops-secret` | `aiops-jwt-secret-key-2026` |
|
||||
| Redis | 无密码 | db `0` |
|
||||
|
||||
> ⚠️ 生产环境请勿使用仓库内默认密码。修改 `configmap.yaml` 中 Secret 的值后重新 apply,
|
||||
> 或使用 `kubectl create secret` 覆盖。
|
||||
> ⚠️ 生产环境请修改 `secret.yaml` 和 `configmap.yaml` 中的默认密码。
|
||||
|
||||
## 资源限额
|
||||
|
||||
| 组件 | CPU 请求/上限 | 内存请求/上限 |
|
||||
|------|---------------|---------------|
|
||||
| backend | 100m / 500m | 512Mi / 1Gi |
|
||||
| mysql | 250m / 1 | 1Gi / 2Gi |
|
||||
| aiops | 100m / 1 | 256Mi / 1Gi |
|
||||
| mysql | 250m / 1 | 512Mi / 2Gi |
|
||||
| redis | 50m / 250m | 128Mi / 256Mi |
|
||||
|
||||
## 关于配置的环境变量占位
|
||||
|
||||
`config.yaml`(位于 ConfigMap)中 DB/Redis 的 `host/port/user/password/dbname`、JWT `secret`
|
||||
均写成 `${ENV_VAR}` 占位形式,实际值在 `backend.yaml` 的 `env` 段注入:
|
||||
非敏感的 host/port/user/dbname 直接给值(指向 K8s Service),密码则 `valueFrom` 引用 Secret。
|
||||
|
||||
后端基于 viper 读取配置。若 `${VAR}` 占位需要由环境变量直接替换嵌套键
|
||||
(如 `DB_PASSWORD` → `database.password`),建议在程序启动时设置键名映射:
|
||||
|
||||
```go
|
||||
viper.SetEnvKeyReplacer(strings.NewReplacer(".", "_"))
|
||||
```
|
||||
|
||||
否则可改为在 `config.yaml` 中直接写明连接串、密码仅由 Secret 注入。两种方式均可,
|
||||
当前清单采用「环境变量占位 + Secret」的标准 K8s 模式。
|
||||
|
||||
## 清理
|
||||
|
||||
```bash
|
||||
./run.sh k8s delete
|
||||
|
||||
# 或手动(持久卷需单独删)
|
||||
kubectl delete -f deploy/k8s/
|
||||
# 持久卷需单独删除(PVC 由 StatefulSet 保护,删除 STS 后 PVC 仍保留)
|
||||
kubectl -n devops delete pvc --all
|
||||
```
|
||||
Reference in new issue
Block a user