sync:操作rclone容器做同步备份

基于rclone的sftp同步 sync,扫描和传输都是一坨屎,改造为tarssh做传输执行+命令集合传输到远端批量执行,仍是一坨屎,扫描性能极差。整体备份设计失败。

原始需求

起因:裸 rclone sync 是黑盒同步,一次误操作就丢数据,不敢用。要的是一套可控、可审计、不怕误删的同步管理:预览先行,熔断兜底,备份可选,日志可查,运行中的任务看得到、停得掉。

  • 预览先行:先 diff 看差异与预计传输量,只读,不写任何数据。
  • 熔断:删除比超阈值直接拒绝执行,加 -f 才旁路(单向;双向用空侧/冲突 ABORT 门)。
  • 空侧拒绝:任一边清单为零直接中止(疑似挂载掉、路径错)。
  • 备份默认关闭:除非显式加 --backup,否则不预拷。
  • 日志可审计:每文件两行(预览行动作加大小、完成行结果),另有 30 秒一行全局心跳。
  • 运行可见可终止:stats 按实例列进度,stop 与 kill 能停掉失控任务。
  • 出站走宿主代理,容器内回环不等于宿主;局域网段走直连。
  • 容器 rootless 运行;GUI 只做控制台,不用它编排同步。

评估口径(用户裁定):按最坏 failure mode 评估,不按当前 workload。一个工具不能只为一个简单场景的成功而庆幸,严重缺陷决定未来灾难必然发生。

不做的事(用户裁定)

  • 不给方案加“忽略时间属性”开关:SFTP 无哈希,对不上只能人工看。
  • 不同步逻辑里默认不自动摸时间:摸时间掩盖真变更,只允许人工确认后对账(--time 显式加参即确认)。
  • 不用 --size-only:同大小真变更会被静默漏掉。
  • 不用 -L 跟软链:绝对路径软链会把系统文件卷进来。
  • 覆盖震荡不靠开关治:治本是统一拷贝方式保时间,治标是人工对账。

rclone gui docker

部署

  • rootless compose 常驻,与系统声明无关,不走 rebuild。
  • 镜像钉死稳定版本,换版只改一行再起。
  • gui 模式;GUI 端口与 RC 接口端口分开,两个都只绑回环。
  • 开账密认证(容器网络内其它容器也可达端口,不用免密;账密只存本机 compose 文件,不进本笔记)。
  • 云远端经宿主代理出站,容器内走 host-gateway;局域网段直连,不走代理。
  • 卷:配置卷持久化;业务目录写物理路径挂载,不用软链接;热插拔盘用普通绑定,新盘重启容器即可。
  • SFTP 账密与密钥两种登录;密钥文件放配置卷内,key_file 写容器内绝对路径。
  • 自定 local 别名远端,方案里两侧统一写成“名加冒号加路径”形态。

职责

  • 做:承载传输执行(sync 脚本经 exec 调它跑);远端与文件控制台(建远端、两边浏览互拷、改配置);查看传输进度。
  • 不做:同步任务编排。GUI 只有总览、远端、挂载、服务、传输、设置六页,没有新建同步任务、选左右目录、配方向与规则的向导;传输页只显示经自身接口起的任务。
  • 不做:存同步方案。方案只活在 sync 的 plan 目录里。

部署踩坑(现象 → 成因 → 处置,均为实测)

  • 现象:报挂载点非 shared,容器起不来。成因:rootless 下共享传播要求宿主挂载点是 shared,相关目录不是。处置:改普通绑定,新插盘后重启容器。
  • 现象:改完配置,GUI 刷新仍报旧错。成因:daemon 启动时把配置快照进内存,不热加载。处置:改完必须重启再验。
  • 现象:key_file 写裸文件名报找不到。成因:按工作目录相对解析。处置:写配置卷内绝对路径。

sync

脚本说明

单文件 bash 脚本,全局别名任意目录可用。plan 驱动:每个方案是一个 .conf(源、目标、方向、熔断阈值、保留数)加一个同名规则文件;源/目标可写多个空格分隔候选(左优先,开工 probe 首通赢,3s 超时);选择器批量:序号(list 第一列,从1起,动态) | 全名 | a,b,c | 前缀* | *后缀 | *中间* | *;先打名单再逐个跑(各写各的 log/state),写操作失败即停;通配加引号防 shell 展开。

预览 diff(只读)
  → 熔断与空侧检查(删除比超阈值 / 任一侧为零则停)
  → --backup 才预拷(先拷后同步)
  → 执行 rclone(无 -P,每文件完成行 + 30 秒心跳)
  → 成功写 state,顺手做日志与备份维护
双向:预览(A独有/B独有/两边不同/冲突) → 空侧/冲突>0 直接停 → --backup 预拷双边 → 执行 bisync(首跑自动建基准)
命令说明状态
sync显示帮助已接
sync list列方案、源、目标、最近成功已接
sync stats按实例列运行状态与进度,默认 2 秒刷已接
sync <方案> diff预览差异与预计传输量已接
sync <方案> left|right单向镜像(别名 push/pull/cp/copy 同效),--time 对齐同大小文件时间,--backup 预拷,-f 旁路熔断已接
sync <方案> stop终止该方案全部实例,先 TERM,5 秒不退再 KILL已接
sync <方案> kill立即 KILL 该方案全部实例已接
sync <方案> / run双向同步,裸名默认双向(MODE 须 bisync,首跑自动建基准)已接
-v / -d / logs后台、看日志未接
  • 无 -f 不触发熔断就执行;有 -f 熔断也强制执行;双向不引入 -f。
  • 备份 opt-in:默认无备份;--backup 把待删待覆盖清单先拷到备份目录,再裸同步(跨远端天然成立)。
  • 裸名默认双向:首跑自动建基准;预览的空侧/冲突门在前;双向侧 --time/-f 不适用。
  • 同方案防重跑:开工时已有实例直接拒绝,避免双开互冲。
  • 中断联动:Ctrl+C 会把容器内同方案传输一起带走再退出,不留孤儿。
  • 软链跳过不告警:执行统一加 --skip-links(跳过行为不变,只是不再逐条刷屏)。
  • 状态双检出:pidfile 加扫容器内传输命令行,手动起的任务也看得见。

过滤规则规范

  • 按路径段匹配:* 不跨分隔符,** 才跨层。
  • 行尾不写注释,会毒化整条规则;注释独占一行。
  • 旧结论作废:组合曾被误判对深层目录失效,实测是段语义问题,现以段匹配为准。

职责边界

  • 做:预览、熔断、备份、审计日志、启停管理、双向同步(裸名默认,首跑自动建基准)。
  • 不做:替双向猜冲突(冲突>0 直接 ABORT);双向侧不引入 --time/-f(原生按新赢处理时间,无熔断可旁路)。
  • 不做:时间对账默认只出候选清单;加 --time 才自动按旧对齐(旧赢、不分方向,大小不同走正常逻辑),touch 后重扫再裁决。
  • 不做:单文件耗时。完成行原生没有耗时,耗时只有全局心跳的速度与剩余时间。

风险清单(按 failure mode)

  • 双向删:建基准后一边删文件,另一边跟删。
  • 空侧灾难:一边列出零文件会被理解成对面全删,熔断与跑前两侧非空检查排第一。
  • 冲突覆盖:两边同名文件都变,先跑赢的覆盖后跑的。
  • 账本丢失自动重建:工作目录无基准按首跑重建(只传不删,删过的会被当新增传回来);已有基准乱传 --resync 直接拒绝。