AI Infra 训练营
总览
  • Day 1 · 集群起步 + CNI
  • Day 2 · 控制面 + etcd
  • Day 3 · CRD + Operator + Webhook
  • Day 4 · 存储深度
  • Day 5 · 卷扩容 + 安全
  • Day 6 · 调度 + 可观测
  • Day 7 · Harbor + ArgoCD + Mesh
  • Day 8 · AI Infra
  • Day 9 · Triton + GPU
  • Day 10 · MIG + HPA + 量化
  • Day 11 · AI Agent 端到端
  • Day 12 · 灾备
  • Day 13 · Operator + 联邦 + Mesh + RAG
  • Day 14 · CKA / CKS + 总结
  • LLM 训练手册
  • RAG + Agent 手册
  • 推理优化手册
  • 上下文工程手册
  • Agent 开发手册
  • 面试深度复盘
  • 训练 v2 深度手册
  • 心智模型
  • 看懂命令输出
  • 容器网络底层
  • K8s 网络深入
  • DNS 全套
  • 故障排查方法论
  • 心智模型
  • 容器挂载完整指南
  • K8s Volumes 大全
  • PV/PVC/CSI 深入
  • NFS 深入
  • 分布式存储概览
  • 故障排查 runbook
HiHuo 主站
GitHub
总览
  • Day 1 · 集群起步 + CNI
  • Day 2 · 控制面 + etcd
  • Day 3 · CRD + Operator + Webhook
  • Day 4 · 存储深度
  • Day 5 · 卷扩容 + 安全
  • Day 6 · 调度 + 可观测
  • Day 7 · Harbor + ArgoCD + Mesh
  • Day 8 · AI Infra
  • Day 9 · Triton + GPU
  • Day 10 · MIG + HPA + 量化
  • Day 11 · AI Agent 端到端
  • Day 12 · 灾备
  • Day 13 · Operator + 联邦 + Mesh + RAG
  • Day 14 · CKA / CKS + 总结
  • LLM 训练手册
  • RAG + Agent 手册
  • 推理优化手册
  • 上下文工程手册
  • Agent 开发手册
  • 面试深度复盘
  • 训练 v2 深度手册
  • 心智模型
  • 看懂命令输出
  • 容器网络底层
  • K8s 网络深入
  • DNS 全套
  • 故障排查方法论
  • 心智模型
  • 容器挂载完整指南
  • K8s Volumes 大全
  • PV/PVC/CSI 深入
  • NFS 深入
  • 分布式存储概览
  • 故障排查 runbook
HiHuo 主站
GitHub

scp / rsync —— 远程文件拷贝

一句话定义

两个工具都走 SSH 传文件:

  • scp —— 简单粗暴,全量复制
  • rsync —— 智能增量、断点续传、保留权限 / 时间戳

rsync 在几乎所有方面都胜过 scp——除了"我只想一次拷一个小文件"。生产 / 大文件 / 同步目录用 rsync。

OpenSSH 9.0+ 已经 deprecate scp 协议(背后改用 SFTP)。但命令本身还在、还能用。

典型场景

  • 把本机文件传到服务器:scp file user@host:/path
  • 同步整个目录:rsync -avz dir/ host:/dir/
  • 增量推 K8s manifests:每次只传变化的
  • 拉远端日志:rsync -avz host:/var/log/ ./logs/

scp 基础

# 本地 → 远端
scp file.txt user@host:/path/

# 远端 → 本地
scp user@host:/path/file.txt ./

# 远端 → 远端(中转走本地)
scp user@host1:/file user@host2:/file

# 递归目录
scp -r mydir/ user@host:/path/

# 指定端口
scp -P 2222 file user@host:/

# 用 ssh config 的 alias
scp file m1:/tmp/                          # m1 在 ~/.ssh/config 里

scp 常用 flag

flag作用
-r递归目录
-P <port>SSH 端口(大写 P,注意 ssh 是小写 -p)
-i <key>私钥
-p保留时间戳 / 权限(小写 p)
-vverbose
-C压缩传输
-qquiet
-l <kbps>限速
-3强制走本地中转(默认两台远端直接连)

scp 经典坑

scp -P 22 -p file user@host:/                       # 大小写 P 不一样
# -P = 端口
# -p = 保留时间戳

很多人混淆。rsync 没这坑——下面看。


rsync —— 现代首选

rsync -avz source/ destination/

万能套路:-avz 三个字。

flag作用
-aarchive(递归 + 保留权限 / 时间戳 / 软链等)
-vverbose
-z压缩

加起来:递归同步、保留元信息、压缩传输、可读输出。默认套路。

本地 → 远端

rsync -avz manifests/ m1:/root/manifests/

远端 → 本地

rsync -avz m1:/var/log/ ./logs/

-e 自定义 SSH 命令

rsync -avz -e "ssh -p 2222 -i ~/.ssh/special-key" file m1:/tmp/

或者让 rsync 用 ~/.ssh/config(默认就用)。


rsync 路径末尾的 / —— 经典坑

rsync -avz src dst                          # src 这个**目录**被放到 dst 下 → dst/src/
rsync -avz src/ dst                          # src 里的**内容**复制到 dst → dst/file1, dst/file2
rsync -avz src/ dst/                         # 同上

核心:

  • src 不带 / —— "拷这个目录"
  • src/ 带 / —— "拷里面的东西"
# 想把 manifests/ 里的所有内容同步到 m1:/root/manifests/
rsync -avz manifests/ m1:/root/manifests/
# ✅ 正确

rsync -avz manifests m1:/root/manifests/
# 结果:/root/manifests/manifests/...    (多了一层)

这个 / 错了 90% 人都踩过。


--delete —— 双向同步(镜像)

rsync -avz --delete src/ dst/
# dst 里"src 里没有"的文件被删
# 让 dst 真正"等于" src

GitOps 部署 manifests 经常用:

rsync -avz --delete --exclude='.git' manifests/ m1:/root/manifests/
# m1 上 manifests 和本地完全镜像、含删除已删的

--delete 是核选项——目标目录不在 src 里的文件就被干掉。先 --dry-run 看:

rsync -avzn --delete src/ dst/                      # -n = dry-run

--dry-run / -n —— 必备

rsync -avzn --delete src/ dst/
# 显示会发生什么,但不真做

所有破坏性的 rsync 操作之前先 -n。


--exclude / --include

rsync -avz --exclude='*.log' src/ dst/
rsync -avz --exclude='*.log' --exclude='node_modules' src/ dst/
rsync -avz --exclude-from=.gitignore src/ dst/        # 从文件读

--exclude='*.log' 跳过所有 .log 文件。--exclude='dir/' 跳整个目录。

rsync -avz --include='*.yaml' --exclude='*' src/ dst/
# 只同步 yaml、其它全跳
# --include 先生效、--exclude 后兜底

--progress —— 看进度

rsync -avz --progress big-file m1:/
# 显示每个文件的传输百分比 + 速度

或者 -P 等价 --partial --progress:

rsync -avzP big-file m1:/
# --partial 留下未传完的部分(断点续传)
# --progress 显示进度

大文件 / 不稳定网络永远 -avzP——网络断了下次接着传。


限速 --bwlimit

rsync -avz --bwlimit=10M src/ dst/                    # 限 10 MB/s

避免大同步把带宽吃光(K8s 节点之间 / 共享网络)。


实战场景

1. 把 manifests 同步到节点

rsync -avz --delete \
  --exclude='.git' \
  --exclude='*.bak' \
  manifests/ m1:/root/k8s/manifests/

或者写到 Makefile:

sync:
	rsync -avz --delete --exclude='.git' manifests/ m1:/root/k8s/manifests/

2. 拉远端日志做分析

rsync -avz m1:/var/log/audit/ ./audit-logs/m1/
rsync -avz m2:/var/log/audit/ ./audit-logs/m2/
# ...

# 或并行 + 多节点
for h in m1 m2 m3 m4 m5; do
  rsync -avz $h:/var/log/audit/ ./audit-logs/$h/ &
done
wait

3. 跨集群迁移数据

# 在源节点
rsync -avzP --bwlimit=50M /data/ user@new-cluster:/data/

4. 用 scp 一次性小文件

scp /tmp/cert.crt m1:/etc/ssl/
scp m1:/var/log/kubelet.log .

小文件 / 一次性场景 scp 够用。

5. 拷到多台机器

# scp 一次只能一台 → 写循环
for h in m1 m2 m3 m4 m5; do
  scp config.yaml $h:/etc/
done

# rsync 也是
for h in m1 m2 m3 m4 m5; do
  rsync -avz config.yaml $h:/etc/
done

# 并行
echo m1 m2 m3 m4 m5 | xargs -n 1 -P 5 -I {} rsync -avz config.yaml {}:/etc/

rsync 的"魔法":增量算法

rsync 不是简单全量复制——它检查文件块的哈希,只传输有变化的块。

# 第一次:全量传
rsync -avz big.bin m1:/

# 第二次:big.bin 改了一点
rsync -avz big.bin m1:/                              # 只传改了的块

对大文件 / 重复内容场景大幅省时省带宽。git 仓库 / 数据库快照 / 镜像同步等场景受益最大。


常见踩坑

坑 1:路径末尾 / 错

rsync -avz src dst                          # 多了一层

记忆:src/ = "里面的东西",src = "目录本身"。

坑 2:--delete 删了不该删的

rsync -avz --delete /tmp/myapp/ m1:/etc/myapp/
# m1 上 /etc/myapp/ 里的所有"本地 /tmp/myapp 没有的"都被删

--dry-run 先看:

rsync -avzn --delete /tmp/myapp/ m1:/etc/myapp/

坑 3:scp 端口 -P 大小写

scp -p 2222 file host:/             # ❌ 小 p = 保留时间戳,不是端口
scp -P 2222 file host:/             # ✅ 大 P

坑 4:跨主机 scp 慢

scp -3 host1:/file host2:/file       # 走本地中转
scp host1:/file host2:/file          # 默认两台直连,可能不通 / 慢

更现代:用 rsync + ssh-pipe(极少需要)。

坑 5:rsync 远端找不到

rsync -avz file m1:/path/
# rsync: bash: command not found
# rsync error: ...

远端没装 rsync。装:

ssh m1 'apt install -y rsync'

两端都要装 rsync。scp 不要求(只要 ssh + scp)。

坑 6:rsync 时遇到符号链接

rsync -avz src/ dst/                                # -a 保留 symlink(默认)
rsync -avzL src/ dst/                                # -L 跟随 symlink(拷实际文件)

-L(link)让 rsync 解引用 symlink、把目标文件拷过去。需要时再加。

坑 7:rsync 不传隐藏文件

rsync -avz src/* dst/                                # ❌ shell glob 不含 .开头
rsync -avz src/ dst/                                 # ✅ src/ 含所有(隐藏 + 普通)

src/* 是 shell 在 rsync 之前展开 → 缺隐藏。src/ 是把目录给 rsync、它处理。

坑 8:rsync 时 SELinux 让权限丢

rsync -avz src/ dst/
# 文件 owner / mode 对、但 SELinux context 没了

加 -X(保留扩展属性)+ -A(保留 ACL):

rsync -avzXA src/ dst/

K8s 节点上影响不大、SELinux / AppArmor 场景需要。

坑 9:rsync 用错了 sudo 权限

rsync file m1:/etc/                                  # m1 上写 /etc 要 root
# Permission denied
rsync -e "ssh -t" --rsync-path="sudo rsync" file m1:/etc/

--rsync-path="sudo rsync" 让远端用 sudo 跑 rsync。

坑 10:大量小文件 rsync 慢

rsync -avz lots-of-small-files/ m1:/
# 每个文件单独 metadata 同步、慢

打包后传:

tar czf - lots-of-small-files/ | ssh m1 'tar xzf - -C /'

tar + ssh 流式比 rsync 大量小文件快很多。


scp vs rsync 总结表

维度scprsync
简单✅ 简单复杂参数
增量❌ 全量✅ 只传变化
大文件中断恢复❌✅ -P
保留权限-p-a 自动
双向同步❌✅ --delete
dry-run❌✅ -n
限速-l kbps--bwlimit
跨主机-3不直接支持
进度OpenSSH 8+--progress
两端要装不要要装 rsync

90% 场景用 rsync。


关联命令

  • ssh —— scp / rsync 底层都是 SSH
  • ssh-config —— alias 让 scp / rsync 也短
  • tar —— tar + ssh 流式拷大量小文件
  • find —— find ... | rsync --files-from=- 精确选文件
  • wget / curl —— HTTP / FTP 下载
  • croc / magic-wormhole —— 端到端文件传输(避开 SSH key 管理)
在 GitHub 上编辑此页