添加qiming-rcoder模块

This commit is contained in:
Codex
2026-06-01 13:54:52 +08:00
parent 8092c4b1f8
commit 4b1a580132
539 changed files with 151650 additions and 0 deletions

390
qiming-rcoder/k8s/README.md Normal file
View File

@@ -0,0 +1,390 @@
# RCoder K8s 部署配置
本目录提供 **三种部署方式**,按场景选择:
| 场景 | 方式 | 入口 |
|------|------|------|
| 日常开发 / 在线环境 | **Kustomize** | `deploy-dev.sh` / `deploy-prod.sh` |
| 参数化部署 / 对外交付 | **Helm** (双栈并存) | `helm install ... k8s/helm/rcoder` |
| 政企客户 / 完全断网 | **离线 Bundle** | `make k8s-offline-bundle``install.sh` |
另外还有可选的 **本地镜像加速**`register2/`),面向多节点 k3s / 频繁构建场景,详见下文"本地镜像加速"一节。
## 目录结构
```
k8s/
├── manifests/ # Kustomize manifests (日常开发 + 在线部署)
│ ├── base/ # 基础配置 (不可直接部署, 需走 overlay)
│ │ ├── storage/ # postgresql / minio / juicefs-init / juicefs-pvc
│ │ └── rcoder/ # rcoder Deployment/Service/NetworkPolicy/PDB/SA+ClusterRole
│ └── overlays/
│ ├── dev/ # 开发环境 (nuwax-rcoder-dev, NodePort 30080)
│ └── prod/ # 生产环境 (nuwax-rcoder-prod, NodePort 30081)
├── helm/ # Helm chart (对外交付 + 离线部署源)
│ └── rcoder/
│ ├── Chart.yaml
│ ├── values.yaml # 默认值 (共享)
│ ├── values-dev.yaml # dev 覆盖
│ ├── values-prod.yaml # prod 覆盖
│ ├── values-offline.yaml # 离线 registry 覆盖
│ └── templates/ # K8s 模板
├── offline/ # 离线 bundle 素材
│ ├── images.txt # 镜像清单 (单一数据源)
│ ├── install.sh # 离线安装脚本 (direct / registry 双模式)
│ ├── rewrite-registry.sh # 重打 tag + 推送私有 registry
│ └── README.md # 交付给政企客户的部署手册
├── register2/ # 本地私有镜像仓库 (docker compose)
│ ├── docker-compose.yml # registry:2 容器 + 数据卷
│ └── README.md # 作 k3s mirror / 离线 push 目标的用法
├── deploy-dev.sh # [在线] Kustomize 开发环境一键部署
├── deploy-prod.sh # [在线] Kustomize 生产环境一键部署 (含占位符密码守卫)
├── undeploy.sh # [在线] 清理部署 (ENV=dev|prod)
├── scripts/ # 辅助脚本
│ ├── deploy-juicefs.sh # 仅部署存储层 (ENV=dev|prod)
│ ├── test-chat.sh # 功能冒烟测试 (NAMESPACE 可覆盖)
│ ├── install-k3s-registry-mirrors-cn.sh # K3s 节点镜像加速配置 (支持 REGISTRY_HOST)
│ └── k3s-registries-cn.yaml # 镜像加速配置模板
└── README.md
```
dev 和 prod 可以并存于同一个集群:
- 集群级资源StorageClass / ClusterRoleBinding命名独立`juicefs-sc-dev` / `juicefs-sc-prod``rcoder-pods-crb-dev` / `rcoder-pods-crb-prod`
- NodePort 错开dev=30080 / prod=30081
- ClusterRole `rcoder-pods-clusterrole` 是唯一共享的集群级资源(两个 overlay 写入完全一致,幂等)
---
## 快速开始
### 开发环境
```bash
# 首次完整部署(含 Longhorn、JuiceFS CSI、open-iscsi 检查)
./k8s/deploy-dev.sh
# 常用
kubectl apply -k k8s/manifests/overlays/dev # 部署/更新
kubectl delete -k k8s/manifests/overlays/dev # 删除
kubectl get all -n nuwax-rcoder-dev # 查看状态
k8s/scripts/test-chat.sh # 冒烟测试
```
### 生产环境
> **重要**:首次部署前必须替换 `k8s/manifests/overlays/prod/credentials.yaml` 和 `juicefs-secret.yaml` 里的 `CHANGE-ME-BEFORE-DEPLOY` 占位符;`deploy-prod.sh` 有守卫检查,发现占位符会拒绝部署。若使用 SealedSecret / ExternalSecret 在集群外注入,设置 `FORCE_PROD_DEPLOY=1` 跳过。
```bash
# 首次完整部署
./k8s/deploy-prod.sh
# 跳过占位符检查(仅当通过外部密钥注入方案时)
FORCE_PROD_DEPLOY=1 ./k8s/deploy-prod.sh
# 常用
kubectl apply -k k8s/manifests/overlays/prod
kubectl get all -n nuwax-rcoder-prod
NAMESPACE=nuwax-rcoder-prod k8s/scripts/test-chat.sh
```
### 清理
```bash
ENV=dev ./k8s/undeploy.sh # 清理 dev
ENV=prod ./k8s/undeploy.sh # 清理 prod
```
---
## Makefile 快捷命令
在项目根目录执行:
```bash
# 镜像
make dev-build-k8s # 构建并推送 K8s 镜像 (含 k3s 本地 import + rollout restart)
# 部署/清理(默认走 overlay
make deploy-dev # kubectl apply -k overlays/dev
make deploy-prod # kubectl apply -k overlays/prod
make undeploy-dev # 清理 dev
make undeploy-prod # 清理 prod
# 开发闭环
make dev-up-k8s # 部署 dev
make dev-restart-k8s # 重新构建镜像 + 重部署 dev
make dev-down-k8s # 清理 dev
make dev-logs-k8s # 跟随 rcoder 日志
# 本地验证(不部署)
make kustomize-build # 分别 build base / dev / prod
# 离线部署 (政企内网)
make k8s-offline-bundle # 打包完整离线包 (images + helm + manifests)
make k8s-offline-import BUNDLE=<tgz> INSTALL_ARGS="--mode=direct --env=dev"
make k8s-offline-images-list # 打印所有离线依赖镜像清单
make k8s-offline-clean # 清理构建产物
```
---
## Helm 部署 (参数化 / 对外交付)
Helm chart 与 Kustomize **双栈并存、长期维护**。修改 `manifests/base/*.yaml` 时请同步更新 `helm/rcoder/templates/*` 对应模板。
```bash
# dev (本地或在线环境)
helm install rcoder-dev k8s/helm/rcoder \
--namespace nuwax-rcoder-dev --create-namespace \
-f k8s/helm/rcoder/values-dev.yaml
# 同集群已有 Kustomize 部署的话, 加 --set rcoder.clusterRole.create=false
# (避免 Helm 尝试接管 Kustomize 已创建的 ClusterRole)
helm install rcoder-helm-test k8s/helm/rcoder \
--namespace nuwax-rcoder-helm-test --create-namespace \
-f k8s/helm/rcoder/values-dev.yaml \
--set rcoder.service.nodePort=30082 \
--set juicefs.storageClass.name=juicefs-sc-helm-test \
--set rcoder.clusterRole.create=false
# prod (密码通过 --set 或 external secret 注入)
helm install rcoder-prod k8s/helm/rcoder \
--namespace nuwax-rcoder-prod --create-namespace \
-f k8s/helm/rcoder/values-prod.yaml \
--set credentials.postgresql.password=<real> \
--set credentials.minio.rootPassword=<real>
# 升级
helm upgrade rcoder-dev k8s/helm/rcoder -f k8s/helm/rcoder/values-dev.yaml
# 卸载
helm uninstall rcoder-dev --namespace nuwax-rcoder-dev
```
### 渲染对比 (开发调试)
```bash
helm template rcoder-dev k8s/helm/rcoder -f k8s/helm/rcoder/values-dev.yaml > /tmp/helm-dev.yaml
kubectl kustomize k8s/manifests/overlays/dev > /tmp/kustomize-dev.yaml
diff <(grep -E 'image:|nodePort:|storageClassName:' /tmp/helm-dev.yaml | sort -u) \
<(grep -E 'image:|nodePort:|storageClassName:' /tmp/kustomize-dev.yaml | sort -u)
```
### 集群级资源命名
Helm 为每个 release 自动生成独立的集群级资源名:
| 资源 | dev release (`rcoder-dev`) | prod release (`rcoder-prod`) |
|------|---------------------------|------------------------------|
| StorageClass | `juicefs-sc-dev` (显式 override) | `juicefs-sc-prod` (显式 override) |
| ClusterRoleBinding | `rcoder-dev-pods-crb` (自动) | `rcoder-prod-pods-crb` (自动) |
| ClusterRole | `rcoder-pods-clusterrole` (共享, `resource-policy: keep`) |
---
## 离线部署 (政企内网, 完全断网)
当客户内网无公网访问时,使用 **Bundle 模式**在有网的构建机打包所有镜像、helm charts、manifests产出单个 `tar.gz`;离线机器上解压运行 `install.sh` 完成部署。
### 构建 bundle (有网构建机)
```bash
# 拉取所有镜像 + 打包 helm charts + 下载 Longhorn/JuiceFS CSI manifest + 压缩
make k8s-offline-bundle
# 输出: dist/rcoder-offline-<version>-<arch>.tar.gz (约 1.7-2 GB, 共 27 个镜像)
ls -lh dist/rcoder-offline-*.tar.gz
# 查看镜像清单
make k8s-offline-images-list
```
### 离线机器部署
```bash
# 方式 1: 用 make 一键跑完
make k8s-offline-import BUNDLE=/path/to/rcoder-offline-xxx.tar.gz \
INSTALL_ARGS="--mode=direct --env=dev"
# 方式 2: 手工解压 + 跑 install.sh
tar xzf rcoder-offline-xxx.tar.gz -C /opt/rcoder-offline
cd /opt/rcoder-offline
sudo bash install.sh --mode=direct --env=dev
```
### 两种导入模式
| 模式 | 镜像落盘方式 | 适用场景 |
|------|------------|----------|
| `--mode=direct` | `ctr image import` 到节点 containerd | 单节点 / 小集群 / 无私有 registry |
| `--mode=registry` | `docker load` + re-tag + push | 多节点 / 已有 Harbor/Nexus / 客户自建 registry |
详见 [`offline/README.md`](./offline/README.md)(客户交付文档)。
---
## 本地镜像加速(多节点 / 频繁构建场景)
当本地 k3s 有多个节点,或者你频繁 push 测试镜像又不想每次走公网时,启用 `register2/` 作本地 registry mirror所有节点直接拉局域网镜像千兆
### 架构
```
k3s/containerd (所有节点)
├── (1) http://<你的机器>:5000 ← register2 (本目录, 私有推送)
├── (2) http://<你的机器>:5002 ← registry-cache (可选 pull-through)
├── (3) https://docker.m.daocloud.io / ... ← 公网 cn mirror 回退
└── (4) 默认源 (docker.io / registry.k8s.io) 兜底
```
containerd 按顺序尝试 endpoint命中200即返回失败404/超时)自动回退下一个。
### 启动本地 registry
```bash
cd k8s/register2
docker compose up -d
# 验证:
curl -s http://<你的机器>:5000/v2/_catalog
```
### 一键配置 k3s 节点
```bash
# 在每个 k3s 节点上执行 (REGISTRY_HOST 按实际填)
sudo REGISTRY_HOST=192.168.32.228:5000 \
k8s/scripts/install-k3s-registry-mirrors-cn.sh
# 多个 registry 串联 (比如同时有 registry2 和 pull-through cache)
sudo REGISTRY_HOST=192.168.32.228:5000,192.168.32.228:5002 \
k8s/scripts/install-k3s-registry-mirrors-cn.sh
```
脚本会:
- 备份现有 `/etc/rancher/k3s/registries.yaml`
- 写入包含本地 registry + 公网 cn mirror 回退的完整配置(含 `registry.k8s.io`/`ghcr.io`/`quay.io` 全套)
- 自动加 "自指 mirror" + `insecure_skip_verify` 允许 `crictl pull <host>/foo` 走 plain HTTP
- 自动 `systemctl restart k3s``k3s-agent`
-`crictl pull docker.io/rancher/mirrored-pause:3.6` 验证
### 本机 docker daemon 配置(允许 push 到 HTTP registry
```bash
sudo tee /etc/docker/daemon.json <<EOF
{
"insecure-registries": ["192.168.32.228:5000"]
}
EOF
sudo systemctl restart docker
```
详见 [`register2/README.md`](./register2/README.md)。
### 与离线 bundle 的联动
配好本地 registry 后,在本机就能测通 bundle 的 `registry 模式`
```bash
tar xzf dist/rcoder-offline-*.tar.gz -C /tmp/offline-test
cd /tmp/offline-test
docker load -i images/all-images.tar
bash rewrite-registry.sh \
--registry 192.168.32.228:5000/rcoder \
--thirdparty-registry 192.168.32.228:5000/thirdparty \
--images-file images/images.txt
# 之后 helm install 时 k3s 自动从 192.168.32.228:5000 拉
```
---
## 存储架构
```
┌─────────────────────────────────────────────────────────────┐
│ Kubernetes 集群 │
│ ┌──────────────────────────────────────────────────────┐ │
│ │ JuiceFS CSI Driver (kube-system) │ │
│ └──────────────────────────────────────────────────────┘ │
│ ↓ │
│ ┌────────────────┐ ┌────────────────┐ │
│ │ rcoder 主服务 │ │ Agent Runner │ │
│ │ (Deployment) │ │ (动态创建 Pod) │ │
│ └────────┬───────┘ └────────┬───────┘ │
│ └──────────┬───────────┘ │
│ ↓ │
│ ┌──────────────┐ │
│ │ JuiceFS 卷 │ ← ReadWriteMany 共享 │
│ └───────┬──────┘ │
└──────────────────────┼──────────────────────────────────────┘
┌───────────────────────────────────────────────────────────────┐
│ MinIO (S3) ← JuiceFS 数据存储per-namespace
│ PostgreSQL ← JuiceFS 元数据存储per-namespace
└───────────────────────────────────────────────────────────────┘
```
每个 namespace 独立拥有 PostgreSQL 和 MinIO 实例metadata 和 object 存储互不干扰。
---
## 环境要求
- Kubernetes 1.14+(本仓库在 K3s 1.34.x 上测试)
- `kubectl` 已配置 kubeconfig
- `helm` 3.x用于首次安装 JuiceFS CSI Driver + Helm 部署路径)
- Longhorn 存储(为 PostgreSQL / MinIO 提供 PV`deploy-*.sh` 会自动安装)
- `open-iscsi`Longhorn 依赖;`deploy-*.sh` 会自动安装)
- `docker`(仅在有网构建机 `make k8s-offline-bundle` 或本地 push 到 register2 时需要)
国内节点建议先配置 k3s 镜像加速(纯公网 cn mirror 版):
```bash
sudo k8s/scripts/install-k3s-registry-mirrors-cn.sh
```
有本地 registry 时用 `REGISTRY_HOST=...`(见 "本地镜像加速" 一节)。
---
## 故障排查
```bash
# Pod 状态
kubectl get pods -n nuwax-rcoder-dev # 或 -prod / -helm-test / <your-ns>
# 事件
kubectl get events -n nuwax-rcoder-dev --sort-by='.lastTimestamp'
# RCoder 日志
kubectl logs -n nuwax-rcoder-dev -l app=rcoder --tail=200 -f
# PVC 绑定情况
kubectl get pvc -n nuwax-rcoder-dev
kubectl describe pvc rcoder-workspace -n nuwax-rcoder-dev
# StorageClass
kubectl get sc
# 镜像加速是否生效 (与 kubelet 同链路验证, 不要用 k3s ctr images pull)
sudo crictl --runtime-endpoint unix:///run/k3s/containerd/containerd.sock \
pull docker.io/rancher/mirrored-pause:3.6
# 本地 registry 命中情况
curl -s http://192.168.32.228:5000/v2/_catalog
curl -s http://192.168.32.228:5002/v2/_catalog # pull-through 缓存
```
---
## 历史说明
此前版本曾提供 `k8s/helm/rcoder/` Helm chart 作为另一条部署路径;**2025 年后改为 Kustomize + Helm 双栈并存**
- Kustomize 用于开发和已有部署,保持轻量;
- Helm 用于参数化对外交付和离线 bundle
- 两者共享同一份 K8s 资源定义(修改时需同步)。