199 lines
11 KiB
Markdown
199 lines
11 KiB
Markdown
# KRA 部署与配置文档
|
||
|
||
本文档完整描述 kra 框架项目从代码推送到双集群部署的全链路:各组件如何串联、GitLab / Jenkins / Harbor 三块各自需要配置什么、首次部署步骤与排障方法。
|
||
|
||
> 快速接入新项目只看 [README.md](README.md);本文是完整运维文档。
|
||
> 文中账号密码遵循内网环境约定,不写入仓库,凭据统一存放在 Jenkins Credentials 中。
|
||
|
||
## 1. 环境拓扑
|
||
|
||
| 节点 | 角色 | 关键端口 / 路径 |
|
||
|------|------|----------------|
|
||
| 192.168.200.128 | Rancher + RKE2 集群1(dev) | 前端 30080 / 后端 30081,命名空间 `<APP_NAME>-dev` |
|
||
| 192.168.200.129 | RKE2 集群2(prod) | 前端 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位})
|
||
│
|
||
▼ Deploy(kubectl + 对应集群 kubeconfig)
|
||
┌─────────┴─────────┐
|
||
▼ ▼
|
||
128 / kra-dev 129 / kra-prod
|
||
(3 后端 + 3 前端 + MySQL + Redis)
|
||
```
|
||
|
||
分支路由的核心:GitLab 集成发送的 push payload 中带 `ref`(分支),Jenkins 的 gitlab-plugin 把它注入为环境变量 `gitlabBranch`,`deploy/Jenkinsfile` 的 `Select environment` 阶段按它派生出命名空间、环境标识、目标集群与 kubeconfig 凭据,`Checkout branch` 阶段再动态检出实际推送的分支。**单 job 同时服务两个环境,不会串**:
|
||
|
||
- 镜像 tag 含分支与 commit(如 `dev-f0657c1abc12`),按 commit 不可变;
|
||
- 构建不并发(`disableConcurrentBuilds`),同时推送时排队执行;
|
||
- job 的 SCM 分支规格 `*/main` 只影响 Jenkinsfile 脚本本身的加载(两分支脚本内容同步),不影响实际构建内容。
|
||
|
||
> tag 推送不触发部署(GitLab 集成未启用标签事件,Jenkinsfile 也只认 dev/main),tag 仅作 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 用户名/密码内嵌进 URL,POST 到 `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 用自签 HTTPS,docker/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 无 buildx,Dockerfile 不能用 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 签名密钥)。模板默认占位值在 `configs/config.yaml`,生产必须覆盖;**换值会导致已登录 token 全部失效**,需重新登录 |
|
||
|
||
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` |
|
||
| 应用配置文件 | 节点放置 `/var/lib/kra/conf/config.yaml`(模板 [k8s/config.example.yaml](k8s/config.example.yaml)),hostPath 挂载为容器 `/data/conf`(可写),属主 `chown -R 1000:1000`(镜像固定 UID/GID=1000) |
|
||
| 数据持久化 | `/var/lib/<APP_NAME>/mysql`、`/var/lib/<APP_NAME>/redis`(节点本地目录,当前单节点集群适用) |
|
||
| 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`(即节点的 hostPath 文件),配置持久化在节点上。
|
||
4. 若需后续手工改配置:改节点文件后 `rollout restart deployment/kra-backend` 让 3 副本同步。
|
||
|
||
## 7. 首次部署清单(按顺序)
|
||
|
||
1. Harbor:建 `library` 项目 + robot 账号;证书分发到 131 宿主机与 128/129 节点。
|
||
2. RKE2 节点:`registries.yaml` 配好并重启 rke2-server;放置 `/var/lib/kra/conf/config.yaml`。
|
||
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'` 一行可直接确认本次构建部署到了哪个环境。
|
||
|
||
## 9. 排障速查
|
||
|
||
| 现象 | 排查点 |
|
||
|------|--------|
|
||
| push 后没有构建 | GitLab 集成"最近事件"(hook_logs)看响应码与请求体;确认集成启用且勾选推送 |
|
||
| 构建失败 | Jenkins 构建日志;先看 `resolved branch` 是否符合预期 |
|
||
| Pod 镜像拉取失败 | 节点 `registries.yaml`、Harbor robot 是否有效、`harbor-registry` Secret |
|
||
| 后端 503 / 初始化异常 | 节点 `/var/lib/kra/conf/config.yaml` 是否存在且属主 1000:1000;后端日志是否连上 `<APP_NAME>-mysql:3306` |
|
||
| 登录态全部失效 | 是否更换了 `kra-jwt-signing-key`(换值即失效所有 token) |
|
||
| 构建慢 | 缓存目录是否挂载成功;镜像源(goproxy/npmmirror/daocloud)偶发卡顿需重试 |
|
||
|
||
## 10. 附录:安全与维护
|
||
|
||
- 所有账号密码只存 Jenkins Credentials / 各系统自身,不写入仓库;`configs/config.yaml` 不要提交真实密钥。
|
||
- 轮换 Jenkins 密码:GitLab 集成表单改一次即可。
|
||
- 轮换 Harbor robot / MySQL / JWT key:更新 Jenkins 对应凭据 → 推送任意分支触发一次部署(kubeconfig 类凭据即时生效;JWT 轮换会使登录态失效)。
|