kra-new/deploy/DEPLOYMENT.md

202 lines
12 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# KRA 部署与配置文档
本文档完整描述 kra 框架项目从代码推送到双集群部署的全链路各组件如何串联、GitLab / Jenkins / Harbor 三块各自需要配置什么、首次部署步骤与排障方法。
> 快速接入新项目只看 [README.md](README.md);本文是完整运维文档。
> 文中账号密码遵循内网环境约定,不写入仓库,凭据统一存放在 Jenkins Credentials 中。
## 1. 环境拓扑
| 节点 | 角色 | 关键端口 / 路径 |
|------|------|----------------|
| 192.168.200.128 | Rancher + RKE2 集群1dev | 前端 30080 / 后端 30081命名空间 `<APP_NAME>-dev` |
| 192.168.200.129 | RKE2 集群2prod | 前端 30080 / 后端 30081命名空间 `<APP_NAME>-prod` |
| 192.168.200.130 | GitLab | 仓库 `http://192.168.200.130/root/kra`,分支 `main` / `dev` |
| 192.168.200.131 | Jenkins | 8080容器挂载宿主机 docker.sock |
| 192.168.200.132 | Harbor | HTTPS自签名证书项目 `library` |
所有节点 SSH 使用 root各系统账号密码见内网环境约定。
## 2. 总体流程
```
开发者
│ git push (dev 或 main)
GitLab ──(Jenkins 集成,请求内嵌凭据)──► Jenkins job「kra」
│ gitlab-plugin 解析 push payload
│ 注入环境变量 gitlabBranch
┌─────────────────────────────┤
▼ Test/Build宿主机 Docker ▼ Build & push
Go 编译 / pnpm 构建 ────────► Harbor镜像 tag: {分支}-{commit前12位}
▼ Deploykubectl + 对应集群 kubeconfig
┌─────────┴─────────┐
▼ ▼
128 / kra-dev 129 / kra-prod
3 后端 + 3 前端 + MySQL + Redis
```
分支路由的核心GitLab 集成发送的 push payload 中带 `ref`分支Jenkins 的 gitlab-plugin 把它注入为环境变量 `gitlabBranch`,并把 push 的最终提交注入为 `gitlabAfter`。`deploy/Jenkinsfile` 的 `Select environment` 阶段按分支派生出命名空间、环境标识、目标集群与 kubeconfig 凭据,随后优先按 `gitlabAfter` 的 SHA 检出构建内容。**单 job 同时服务两个环境,不会串**
- 镜像 tag 含分支与 commit`dev-f0657c1abc12`),按 commit 不可变;
- 构建不并发(`disableConcurrentBuilds`),同时推送时排队执行;
- job 的 SCM 分支规格 `*/main` 只影响 Jenkinsfile 脚本本身的加载(两分支脚本内容同步),不影响实际构建内容。
> tag 推送不触发部署GitLab 集成未启用标签事件Jenkinsfile 也只认 dev/maintag 仅作 GitLab 版本标记。
## 3. GitLab 侧配置
**只需配置一项Jenkins 集成**(不需要手工建 webhook
路径:项目 → 设置 → 集成 → Jenkins
| 字段 | 值 |
|------|-----|
| Jenkins 服务器 URL | `http://192.168.200.131:8080` |
| Project name | `kra`(与 Jenkins job 名一致) |
| Username / Password | Jenkins 的 admin 账号 |
| 触发事件 | 仅勾选"推送" |
**原理**GitLab 把 Jenkins 用户名/密码内嵌进 URLPOST 到 `http://<user>:<pass>@131:8080/project/kra`,请求体为完整 push 事件 JSON含分支 ref。带凭据的请求天然通过 Jenkins 权限检查,无需匿名授权、无需维护自定义请求头。
- 交付记录:集成编辑页底部的"最近事件"hook_logs可看每次请求体与响应码是排障第一入口。
- 修改 Jenkins 密码后:只需回此表单改一次密码,所有分支自动生效。
- 注意GitLab 的 Jenkins 集成每个项目只能配一个(所以采用单 job 分支路由模型)。
## 4. Harbor 侧配置
1. **项目**`library`(镜像最终路径 `library/kra-backend`、`library/kra-frontend`)。
2. **机器人账号**:项目管理 → library → 机器人账户 → 创建 `kra-ci`push/pull 权限),凭据存入 Jenkins 凭据 `harbor-library-push`
3. **自签名证书信任**Harbor 用自签 HTTPSdocker/kubelet 需要信任):
```bash
# ① Jenkins 宿主机131——docker login/push 用
mkdir -p /etc/docker/certs.d/192.168.200.132
cp harbor-ca.crt /etc/docker/certs.d/192.168.200.132/ca.crt
# docker daemon 自动读取,无需重启
# ② 两台 RKE2 节点128/129——kubelet 拉镜像用
cat >/etc/rancher/rke2/registries.yaml <<'EOF'
mirrors:
"192.168.200.132":
endpoint:
- "https://192.168.200.132"
rewrite:
"^rancher/(.*)": "library/$1"
configs:
"192.168.200.132":
tls:
insecure_skip_verify: true
auth:
username: kra-ci
password: "<robot 密码>"
EOF
systemctl restart rke2-server
```
> 集群内另有流水线自动创建/更新的 `harbor-registry` imagePullSecret每次部署时同步 robot 凭据Pod 拉镜像走它;`registries.yaml` 是节点级兜底。
## 5. Jenkins 侧配置
### 5.1 部署形态与系统依赖
- Jenkins 以容器运行在 131容器内挂载宿主机 `/var/run/docker.sock`:流水线里的 `docker build/push` 实际跑在宿主机 daemon 上(注意容器内 docker CLI 无 buildxDockerfile 不能用 BuildKit 语法)。
- 宿主机依赖缓存:`/var/lib/kra-ci-cache/{go-mod,go-build,pnpm-store,corepack}` 挂进构建容器,避免重复下载。
- 容器内需有 `kubectl`、`envsubst`、`git`。
### 5.2 插件清单(关键)
| 插件 | 作用 |
|------|------|
| gitlab-plugin | `/project/<job>` 接收端点、触发构建、注入 `gitlabBranch` |
| Pipeline | 流水线核心Pipeline script from SCM |
| Git | SCM 检出 |
| Credentials / Credentials Binding | 凭据管理与注入 |
### 5.3 凭据6 个ID 与 `deploy/Jenkinsfile` 中变量对应)
| 凭据 ID | 类型 | 来源 / 获取方式 |
|---------|------|----------------|
| `gitlab-root-http` | 用户名/密码 | GitLab 账号(代码检出用) |
| `harbor-library-push` | 用户名/密码 | Harbor robot 账号 `kra-ci` |
| `kra-rke2-128-kubeconfig` | Secret file | 128 节点 `/etc/rancher/rke2/rke2.yaml`**把 server 的 127.0.0.1 改为 192.168.200.128** 后保存 |
| `kra-rke2-129-kubeconfig` | Secret file | 129 节点同上server 改为 192.168.200.129 |
| `kra-mysql-root-password` | Secret text | 自定的 MySQL root 密码(与节点上 MySQL 一致) |
| `kra-jwt-signing-key` | Secret text | 首次生成运行时配置时使用的 JWT 签名密钥;必须非空且为单行文本 |
kubeconfig 添加路径:系统管理 → 凭据 → Add Credentials → 类型 Secret file → 上传文件 → 填 ID。
> kubeconfig 可用性验证:`kubectl --kubeconfig <文件> -n kra-dev get pods`。若报证书错误,在节点 `/etc/rancher/rke2/config.yaml` 追加 `tls-san: <节点IP>` 并 `systemctl restart rke2-server`。
### 5.4 Job 配置(唯一 job「kra」
1. 新建 Item → Pipeline命名 `kra`
2. 勾选"不允许并发构建"。
3. 触发器:勾选 **Build when a change is pushed to GitLab**gitlab-plugin 的 `/project/<job>` 端点依赖该触发器存在)。
4. 流水线:定义 = **Pipeline script from SCM**SCM = Git仓库 `http://192.168.200.130/root/kra.git`;凭据 `gitlab-root-http`;分支规格 `*/main`;脚本路径 `deploy/Jenkinsfile`;勾选轻量级检出。
5. Jenkins 安全策略保持"登录用户可做任何事"即可——集成请求自带凭据,天然有构建权限。
### 5.5 分支解析优先级Jenkinsfile
```
gitlabBranch集成/推送触发)
> BRANCH_NAME多分支流水线场景
> JOB_NAME手动触发兜底以 -dev 结尾按 dev否则默认 main
```
## 6. Kubernetes 节点配置
| 项 | 说明 |
|----|------|
| Harbor 拉镜像信任 | 见 §4 第 3 步 `registries.yaml` |
| 应用配置文件 | Jenkins 将 [k8s/config.example.yaml](k8s/config.example.yaml) 渲染为 `<APP_NAME>-config-template` Secret初始化容器首次复制到 `/var/lib/<APP_NAME>/conf/config.yaml` |
| 配置与上传存储 | `/var/lib/<APP_NAME>/conf`、`/var/lib/<APP_NAME>/uploads`required podAffinity 保证后端与 MySQL 同节点,仅适用于当前单节点方案 |
| 数据持久化 | `/var/lib/<APP_NAME>/mysql`、`/var/lib/<APP_NAME>/redis`节点本地目录Redis/后端 initContainer 需要允许 root 修正 hostPath 权限) |
| kubectl | 节点用 `/var/lib/rancher/rke2/bin/kubectl`,并 `export KUBECONFIG=/etc/rancher/rke2/rke2.yaml` |
**首次部署初始化流程**kra 框架约定,勿用环境变量注入数据库 DSN
1. 服务启动时数据库未就绪,首页显示"前往初始化"。
2. 走完 `/init/initdb` 向导:建库建表 + 写入种子数据(默认账号 admin
3. 向导最后一步把数据库连接**写回**节点目录中的 `/data/conf/config.yaml`,配置不会随 Pod 重建消失。
4. 当前 Jenkins 默认将前后端都部署为 1 个副本,适配单节点和 hostPath 存储。初始化完成后如需扩容,必须先迁移到真正的共享存储,再调整 Jenkinsfile 中的 `KRA_REPLICAS` 并重新部署;后续手工改配置也需要执行滚动重启。
> `<APP_NAME>-config-template` Secret 只负责首次创建配置文件。初始化后,运行时配置以 hostPath 中的 `/data/conf/config.yaml` 为准;更新 Secret 或 Jenkins JWT 凭据不会覆盖已有配置避免覆盖初始化写入的数据库连接。JWT 后续轮换应通过系统设置完成并滚动重启后端。
## 7. 首次部署清单(按顺序)
1. Harbor`library` 项目 + robot 账号;证书分发到 131 宿主机与 128/129 节点。
2. RKE2 集群:确认 `/var/lib/<APP_NAME>/` 所在磁盘容量足够,并允许清单中的 root initContainer 修正目录权限。
3. Jenkins安装插件添加 §5.3 所列 6 个凭据;按 §5.4 建 `kra` job。
4. GitLab配置 Jenkins 集成§3
5. 推送任意分支触发构建,观察首次构建(有依赖缓存预热,耗时会比后续长)。
6. 初始化向导§6完成后浏览器验证。
## 8. 部署验证
```bash
curl -I http://192.168.200.128:30080/ # 前端 200
curl http://192.168.200.128:30081/health # "ok"
curl -I http://192.168.200.129:30080/ # 同上验证 129
```
构建日志里的 `resolved branch='xxx'``building commit <sha>` 两行可分别确认部署环境和实际构建版本。
## 9. 排障速查
| 现象 | 排查点 |
|------|--------|
| push 后没有构建 | GitLab 集成"最近事件"hook_logs看响应码与请求体确认集成启用且勾选推送 |
| 构建失败 | Jenkins 构建日志;先看 `resolved branch` 是否符合预期 |
| Pod 镜像拉取失败 | 节点 `registries.yaml`、Harbor robot 是否有效、`harbor-registry` Secret |
| 后端 503 / 初始化异常 | `/var/lib/<APP_NAME>/conf/config.yaml` 权限、配置模板 Secret、后端日志是否连上 `<APP_NAME>-mysql:3306` |
| 登录态全部失效 | 是否在系统设置中更换了 JWT 签名密钥(换值即失效所有 token |
| 构建慢 | 缓存目录是否挂载成功镜像源goproxy/npmmirror/daocloud偶发卡顿需重试 |
## 10. 附录:安全与维护
- 所有账号密码只存 Jenkins Credentials / 各系统自身,不写入仓库;`configs/config.yaml` 不要提交真实密钥。
- 轮换 Jenkins 密码GitLab 集成表单改一次即可。
- 轮换 Harbor robot更新 Jenkins 凭据后重新部署即可。轮换 MySQL 密码必须先在 MySQL 中执行 `ALTER USER` 并确认连接正常,再更新 Jenkins 凭据并重启相关 Pod仅更新 Secret 不会修改已初始化 MySQL 数据目录中的 root 密码。JWT 签名密钥通过系统设置修改并保存到 hostPath 配置文件,随后滚动重启后端;换值会使现有登录态失效。