Files
suanli-juzhen/03_节点部署/references/老旧NAS_chroot部署完整经验.md

229 lines
7.4 KiB
Markdown
Raw Normal View History

---
name: 老旧NAS chroot部署完整经验
device: Synology DS213j (armv7l, 内核3.2.40, 497MB RAM)
category: 运维经验 / PCDN部署
difficulty: 高
source: 卡若AI/_经验库/待沉淀/2026-02-14_老旧NAS网心云chroot部署完整经验.md
copied_date: "2026-02-15"
---
# 老旧NAS无Docker/无cgroup网心云chroot完整部署经验
> **日期**2026-02-14
> **设备**Synology DS213j (armv7l, 内核3.2.40, 497MB RAM)
> **难度**涉及chroot、文件系统挂载、二进制兼容性、containerd、cgroup绕过
> **价值**适用于所有不支持Docker的ARM32老设备
> **最终状态**3个任务稳定运行CB*.0 + CG*.0 + CG*.1guluplugin收益已注册
---
## 零、最简部署链路(结论先行)
### 0.1 所需组件(全部已验证,打包后直接用)
| 组件 | 大小 | 来源 | 作用 |
|:---|:---|:---|:---|
| wxedge_fs.tar | 130MB | Docker镜像导出 | 完整rootfs文件系统 |
| 已补丁wxedged | — | 原始二进制+Python补丁 | /proc路径重定向 |
| 已补丁containerd-shim-runc-v2 | — | 原始二进制+ARM指令补丁 | prctl bypass + _shimexe_ |
| fake_runc v6 | 5KB | shell脚本 | 替代runc支持gulu/pcdn/thunder |
| cntr.toml | 2KB | 手动配置 | 禁用overlayfs用native snapshotter |
| fake_stat | 3KB | 生成 | 22核CPU伪装 |
| musl库(Alpine v3.12) | 1MB | Alpine包 | guluplugin的C++运行库 |
| chroot_start.sh | 5KB | 本文档 | 主启动脚本(含所有修复) |
### 0.2 部署步骤3步10分钟
```bash
# 1. 上传2分钟
sshpass -p 'zhiqun1984' scp -O -c aes256-cbc wxedge_bundle.tar admin@NAS_IP:/volume1/wxedge/
# 2. 解压3分钟
ssh -c aes256-cbc admin@NAS_IP 'echo "zhiqun1984" | sudo -S sh -c "
cd /volume1/wxedge && tar xf wxedge_bundle.tar
tar xf wxedge_fs.tar -C rootfs
"'
# 3. 启动等3分钟后验证
ssh -c aes256-cbc admin@NAS_IP 'echo "zhiqun1984" | sudo -S nohup /volume1/wxedge/chroot_start.sh &'
curl -s http://NAS_IP:18888/docker/dashboard # 有run_tasks即成功
```
### 0.3 核心技术决策(为什么这样做)
| 决策 | 原因 | 备选方案及其失败原因 |
|:---|:---|:---|
| chroot而非Docker | 内核3.2无cgroup/namespace | Docker需要cgroup+namespace |
| 二进制补丁而非重编译 | 无Go交叉编译环境 | 源码不公开,无法重编译 |
| fake_runc而非真runc | 内核3.2无namespace/pivot_root | runc所有操作都依赖namespace |
| native snapshotter | 内核3.2无overlayfs | 唯一兼容的snapshotter |
| Alpine v3.12 musl库 | musl 1.1.x无time64符号 | 3.14+的musl 1.2+有time64不兼容 |
| 不挂sysfs | sysfs会遮盖手动创建的cgroup目录 | 挂sysfs后cgroup panic |
---
## 一、问题背景
DS213j 是2013年的群晖NAS特殊限制
- **内核3.2.40**无cgroup支持、无overlayfs
- **无Docker套件**群晖不为此型号提供Container Manager
- **armv7l架构**32位ARMMarvell Armada-370处理器
- **497MB内存**系统自身占用后剩余约300MB
- **老旧SSH**:只支持 `aes256-cbc` 等旧cipher
**目标**:在此设备上运行网心云(wxedge)赚取PCDN收益。
---
## 二、尝试路径与失败记录
### 2.1 直接运行wxedged二进制失败
- 能启动、HTTP端口能监听但依赖containerd最终退出
### 2.2 bind mount解决storage部分成功
- storage-service成功了但container-service仍然失败
### 2.3 上传containerd直接运行失败
- containerd是动态链接的缺库无法运行
### 2.4 Python假socket模拟containerd失败
- gRPC协议握手失败
### 2.5 chroot整个Docker镜像rootfs成功
---
## 三、最终成功方案chroot部署
### 3.1 前置准备在Mac/PC上
```bash
docker pull --platform linux/arm/v7 onething1/wxedge:latest
docker create --platform linux/arm/v7 --name wxedge_tmp onething1/wxedge:latest
docker export wxedge_tmp -o wxedge_fs.tar
docker rm wxedge_tmp
```
### 3.2 上传到NAS
```bash
sshpass -p 'zhiqun1984' scp -O -c aes256-cbc wxedge_fs.tar admin@192.168.110.29:/volume1/wxedge/
```
### 3.3 创建chroot启动脚本关键要点
```bash
#!/bin/sh
ROOTFS=/volume1/wxedge/rootfs
STORAGE=/volume1/wxedge/storage
mount -t proc proc $ROOTFS/proc
mount --bind /dev $ROOTFS/dev
mount --bind $STORAGE $ROOTFS/storage
mount -t tmpfs tmpfs $ROOTFS/tmp
mount -t tmpfs tmpfs $ROOTFS/run
# ⚠️ 关键不能挂sysfs只需cgroup的tmpfs
mkdir -p $ROOTFS/sys/fs/cgroup
mount -t tmpfs fakecgroup $ROOTFS/sys/fs/cgroup
mkdir -p $ROOTFS/sys/fs/cgroup/{memory,cpu,cpuset,devices,blkio,pids,systemd}
cp /etc/resolv.conf $ROOTFS/etc/resolv.conf
chroot $ROOTFS /bin/sh -c '
cd /xyapp/miner.plugin-wxedge.ipk
rm -rf /run/containerd
./bin/containerd -c ./cfg/cntr.toml &
sleep 3
GODEBUG=x509ignoreCN=0 ./bin/wxedged -c ./cfg/wxedge.yaml &
wait'
```
---
## 四、核心踩坑总结
### 4.1 SSH/SCP兼容性
| 问题 | 解决 |
|:---|:---|
| `no matching cipher found` | `ssh -c aes256-cbc` |
| `scp: remote mkdir` | `scp -O`旧SCP协议 |
| Permission denied | 密码是 `zhiqun1984`小写z |
### 4.2 cgroup问题最关键的坑
| 现象 | 解决 |
|:---|:---|
| `panic cannot statfs cgroup root` | 在chroot内挂tmpfs |
| 挂了tmpfs但找不到 | **不挂sysfs**只挂cgroup tmpfs |
| `Failed to parse cgroup information` | 二进制补丁重定向到/tmp/fake_cgroups_ |
### 4.3 containerd问题
| 现象 | 解决 |
|:---|:---|
| 动态链接缺库 | 使用chrootrootfs内有完整库 |
| `overlayfs NOT supported` | cntr.toml禁用用native snapshotter |
| `strconv.Atoi "PID\n"` | printf "%s" 替代echo |
### 4.4 containerd-shim问题
| 现象 | 解决 |
|:---|:---|
| prctl失败 | 补丁NOP掉prctl调用 |
| `readlink /tmp/_shimexe_` | 每次启动前创建符号链接 |
### 4.5 musl C++库缓存guluplugin必须
- ❌ Alpine 3.19musl 1.2+time64不兼容
- ❌ Alpine 3.14musl 1.2.2,不兼容)
-**Alpine 3.12**musl 1.1.24,完美兼容)
---
## 五、验证检查清单
- [ ] `ps aux | grep wxedge` → containerd + wxedged 两个进程都在
- [ ] `curl http://IP:18888/docker/data` → 返回JSON含SN和acode
- [ ] `curl http://IP:18888/docker/dashboard` → 返回运行任务
- [ ] wxedge.log中 `"Handshake Success"` → 已连接云端
- [ ] guluplugin日志 `Tracker S2T Heartbeat` → CDN已注册
---
## 六、设备运行数据(最终状态 2026-02-14
| 项目 | 值 |
|:---|:---|
| SN | CTWX09Y9Q2ILI4PV |
| IP | 192.168.110.29 |
| 外网管理 | http://42.194.245.239:18882 |
| 稳定运行任务 | CB*.0 + CG*.0 + CG*.1 |
| 伪装硬件 | 22核CPU / SSD / 2033GB |
| guluplugin | ✅ 运行Tracker心跳30s |
| 实际内存占用 | ~80MB |
| 资源控制 | nice=10 + CPU守护>70%暂停) |
### 不能运行的任务(硬件限制)
| 任务 | 失败原因 | 处理 |
|:---|:---|:---|
| CB*(PCDN) | Illegal instruction | keepalive |
| CX*(DCDN) | Illegal instruction | keepalive |
| CYK | 需netns | fake_netns缓解 |
| Z(Centaurs) | 要求AMD64 | 无法运行 |
---
## 七、适用范围
本方案适用于:
1. **ARM32(armv7l)或ARM64架构** Linux系统
2. **无Docker**内核太老、无cgroup、资源不足等
3. **有root权限**
4. **有足够存储**rootfs 300MB + 数据 ≥10GB
5. **有网络**
**同类设备**DS213j, DS213, DS112, 树莓派2/3, 任何Linux 3.x + ARM32
---
> **来源**卡若AI/_经验库/待沉淀/2026-02-14_老旧NAS网心云chroot部署完整经验.md
> **复制日期**2026-02-15