# KRA CI/CD 部署 deploy/ 目录是一套与项目名解耦的部署模板,基于 kra 框架的新项目可以整体复制后只改一个参数块。 > 完整的环境配置、凭据来源与排障说明见 [DEPLOYMENT.md](DEPLOYMENT.md)。 分支和集群的对应关系: - `dev` -> Rancher 集群 `128` -> 命名空间 `-dev` - `main` -> Rancher 集群 `129` -> 命名空间 `-prod` 代码仓库:`http://192.168.200.130/root/kra`。自动触发使用 **GitLab Jenkins 集成**(项目 设置 → 集成 → Jenkins): - Jenkins 服务器 URL:`http://192.168.200.131:8080`,Project name:`kra`,填入 Jenkins 用户名/密码(凭据由 GitLab 保管,无需手动维护 webhook 或请求头) - 集成会把完整 push 事件(含 `ref` 分支)POST 到 Jenkins `/project/` 端点,gitlab-plugin 注入 `gitlabBranch` 环境变量 - `deploy/Jenkinsfile` 的 `Select environment` 阶段按 `gitlabBranch` 路由:单 job `kra` 同时服务 dev/main 两个环境,构建阶段优先按 push payload 的最终提交 SHA 检出 - 手动构建兜底:`kra` job 手动触发时默认部署 main(不识别 tag,tag 仅作版本标记,不触发部署) 每个环境包含 3 个后端 Pod、3 个前端 Pod、1 个 MySQL Pod 和 1 个 Redis Pod。前端通过 `-backend` ClusterIP Service 访问后端,Kubernetes Service 在 Pod 之间做负载均衡;前端通过 NodePort `30080` 暴露,后端调试入口通过 NodePort `30081` 暴露。后端配置和上传文件使用支持 `ReadWriteMany` 的共享 PVC。 MySQL 和 Redis 使用节点本地目录 `/var/lib//mysql`、`/var/lib//redis` 持久化。Redis 部署会先用一次性 root initContainer 修正 hostPath 权限,主进程仍以镜像内的非 root 用户运行。当前两个 Rancher 集群都只有一个节点,这种方式适合当前环境,不提供数据库跨节点高可用。 ## Jenkins 前置条件 Jenkins 节点需要可用的 Docker CLI/daemon、`kubectl` 和 `envsubst`(Go 编译和前端构建在临时容器内完成)。Jenkins 凭据 ID 需要与 `deploy/Jenkinsfile` 中的 `CRED_*` 变量一致: - `harbor-library-push`: Harbor `192.168.200.132` 的推送账号 - `kra-rke2-128-kubeconfig`: 集群 128 的 kubeconfig 文件 - `kra-rke2-129-kubeconfig`: 集群 129 的 kubeconfig 文件 - `kra-mysql-root-password`: 应用专用 MySQL root 密码 Harbor 项目和 Kubernetes 两个环境都会由流水线自动创建 `harbor-registry` 镜像拉取 Secret。不要把真实密码写入 Git。 ## 访问地址 - 集群 128: `http://192.168.200.128:30080` - 集群 129: `http://192.168.200.129:30080` - 后端调试: 对应节点的 `30081` ## 首次部署初始化 ### 前置:放置配置文件 后端启动读取 `/data/conf/config.yaml`。流水线会把 `deploy/k8s/config.example.yaml` 渲染成 ConfigMap,并由初始化容器复制到共享配置 PVC;容器内运行用户为 UID/GID 1000,初始化向导会把数据库连接和 JWT 密钥写回该文件。 ### 初始化 部署后数据库未配置,应用以 bootstrap 模式启动,首页会出现**前往初始化**。在初始化页面填写数据库连接(以 kra 项目为例): | 字段 | 值 | |---|---| | 数据库类型 | mysql | | 主机 | `kra-mysql`(集群内 Service 名) | | 端口 | `3306` | | 用户名 | `root` | | 密码 | Jenkins 凭据 `kra-mysql-root-password` 的值 | | 库名 | `kra`(与应用名一致) | 提交后框架自动建表、写入种子数据(管理员账号、菜单、casbin)并把连接配置写回共享 PVC 中的 `config.yaml`,Pod 重建后配置不丢失。初始化期间建议暂时保持后端为 1 个副本,完成后再扩容到 `KRA_REPLICAS`,避免多个 Pod 同时执行首次初始化。初始化完成后请执行一次后端滚动重启,让所有副本加载新配置。**不要**通过环境变量注入数据库 DSN:那会让应用跳过初始化向导,导致数据库有表无种子数据、无法登录。 ## 基于 kra 模板接入新项目 复制 `deploy/` 目录到新项目,然后只需修改 `deploy/Jenkinsfile` 顶部的 **项目级参数块**: | 变量 | 说明 | 默认值(kra 项目) | |---|---|---| | `APP_NAME` | 应用名,派生所有 K8s 资源名、数据库名、存储声明、镜像后缀 | `kra` | | `IMAGE_REPO` | Harbor 镜像仓库路径 | `library/kra` | | `REGISTRY` | Harbor 地址 | `192.168.200.132` | | `BIN_NAME` | 后端二进制名,须与 `Makefile` 的 `make build` 产物一致 | `kratos-admin` | | `KRA_REPLICAS` | 前后端副本数 | `3` | | `KRA_FRONTEND_NODEPORT` / `KRA_BACKEND_NODEPORT` | NodePort 端口,同一集群多个项目必须错开 | `30080` / `30081` | | `KRA_MYSQL_IMAGE` / `KRA_REDIS_IMAGE` | 中间件镜像 | daocloud mysql:8.4 / redis:7-alpine | | `KRA_SHARED_STORAGE_CLASS` | 支持 `ReadWriteMany` 的共享存储类 | `longhorn` | | `GO_IMAGE` / `NODE_IMAGE` / `PNPM_VERSION` | 构建镜像与工具版本 | 见文件 | | `CACHE_DIR` | Jenkins 宿主机依赖缓存目录(建议每项目独立) | `/var/lib/kra-ci-cache` | | `CRED_*` | Jenkins 凭据 ID,沿用现有凭据可不改 | 见文件 | ### 模板渲染机制 - `deploy/k8s/kra.yaml` 是 K8s 清单模板,由 Jenkins 用 `envsubst "$K8S_RENDER_VARS"` 白名单渲染。所有资源名都以 `${KRA_APP}` 为前缀(由 `APP_NAME` 注入),不要把新的 `$变量` 混入清单(白名单外的 `$...` 会原样保留,例如 MySQL probe 里的 `$MYSQL_ROOT_PASSWORD`)。 - 前端 Nginx 配置 `web/.docker-compose/nginx/conf.d/my.conf` 中的后端服务名写作 `${KRA_APP}-backend`,Jenkins 构建前端镜像前渲染为 `web/nginx.k8s.conf`(已 gitignore)。本地手动构建 web 镜像前需先执行: ```sh envsubst '$KRA_APP' < web/.docker-compose/nginx/conf.d/my.conf > web/nginx.k8s.conf ``` ### 命名约定 | 资源 | 名称 | |---|---| | Deployment/Service | `-backend`、`-frontend`、`-redis` | | StatefulSet/Service | `-mysql` | | ConfigMap | `-config-template` | | 运行时 Secret | `-runtime`(key:`mysql-root-password`) | | 数据库名 | `` | `internal/logging` 等框架代码与项目名无关,接入新项目时无需修改。