scpとrsyncとsftp、いつ何を
一言でいうと
3つのツールはどれもSSHチャネルの上で動きます。違いは、一度にすべて送るか(scp)、差分だけを送るか(rsync)、対話するようにやり取りするか(sftp)です。
なぜ必要なのか
ファイル1つを移すのにツールが3つもあるのには、理由があります。100MBのファイル1つを初めて送るときと、10GBのディレクトリを毎日同期するときと、サーバー上のファイル一覧を見ながら選んで取得するときとでは、必要な性質が違います。
どう動くのか
scp: 単純なコピー
scp -P 2222 -i ~/.ssh/id_ed25519 ./app.tar.gz root@127.0.0.1:/tmp/
scp -r ./dist root@host:/srv/app/
scp -p ./config.yaml root@host:/etc/app/ # mtime/권한 보존
scp root@host:/var/log/app.log ./ # 내려받기
注意点が2つあります。
- ポートのオプションは大文字の
-Pです。小文字の-pは「タイムスタンプの保持」なので、意味がまったく違います。sshは小文字の-pがポートなので、混同するのにうってつけです。 - 最近のOpenSSHの
scpは、内部でSFTPプロトコルを使います。そのため、過去に通用していた一部のパス展開(リモートシェルがグロブを処理していた動作)が変わりました。古い動作が必要なら、-Oでレガシープロトコルを強制できます。
scpは再開できません。90%で切れたら、最初からやり直しです。そのため、大きな転送には向きません。
rsync: 差分だけを送る
rsync -aHAX --numeric-ids --delete --dry-run /srv/data/ backup@host:/backup/data/
rsync -avz -e 'ssh -p 2222 -i ~/.ssh/id_labhub' ./dist/ root@127.0.0.1:/srv/app/
オプションの正確な意味を知っておく必要があります。
-a(archive)は-rlptgoDと同じです。再帰・シンボリックリンク・権限・時刻・グループ・所有者・特殊ファイル。-aに含まれないものがあります。ACL(-A)、拡張属性(-X)、ハードリンク(-H)は、別に指定する必要があります。これを知らないと、復元後の権限が微妙に違ってきます。--numeric-idsは、名前の代わりに数値のUID/GIDを使います。別のシステムに復元するとき、所有者が見当違いにマッピングされるのを防ぎます。-n(--dry-run)と-i(--itemize-changes)は、常に一緒に使う習慣を身につけるとよいです。
そして、末尾のスラッシュの規則。これがrsyncで最も間違えやすいところです。
rsync -a /srv/data /backup/ # /backup/data/... 가 만들어진다
rsync -a /srv/data/ /backup/ # /backup/... 에 내용이 바로 들어간다
元のパスの末尾のスラッシュは「このディレクトリの内容をコピーする」、ない場合は「このディレクトリ自体をコピーする」という意味です。
--deleteは破壊的です。元が空だったり、マウントが外れた状態で実行されたりすると、対象のデータをすべて消します。実務で実際によく起きる事故です。スクリプトには、必ずガードを入れます。
set -euo pipefail
[ "$(ls -A "$SRC" | wc -l)" -gt 0 ] || { echo "source empty, abort" >&2; exit 1; }
rsync -aHAX --numeric-ids --delete "$SRC/" "$DST"
世代バックアップは、ハードリンクで安く作れます。
rsync -aHAX --delete --link-dest=/backup/daily.1 /srv/data/ /backup/daily.0/
--link-destは、変更されていないファイルをコピーする代わりに、指定したディレクトリのファイルへハードリンクを張ります。各世代が完全なスナップショットのように見えますが、ディスクは変更分だけを占めます。
sftp: 対話型/バッチ
sftp -P 2222 -i ~/.ssh/id_labhub root@127.0.0.1
sftp -b /root/batch.txt -P 2222 root@127.0.0.1
バッチファイルにcd、put、get、ls、mkdirを書いておくと、非対話で実行されます。パートナー企業とファイルをやり取りする自動化では、今でも多く使われています。ChrootDirectory + ForceCommand internal-sftpの組み合わせで、シェルのない転送専用アカウントを作れることも、sftpの強みです。
現場での姿
世代バックアップを、ハードリンクを知らないツールでコピーして、容量が3倍になる事故。--link-destで節約した領域が、1回のコピーで吹き飛びます。-Hは-aに含まれないので、必ず別に指定する必要があります。
帯域を使い果たして、サービスを妨げるバックアップ。--bwlimit=50Mとionice -c 3 nice -n 19の組み合わせで、優先度を下げます。バックアップが運用を妨げなければ、かえって周期を短くする余裕が生まれます。
次のラボですること
2つのラボを続けて行います。まず、scpとsftpでファイルを往復させて、チェックサムで完全性を確認します。そのあと、rsyncで末尾のスラッシュの違い・--deleteのガード・--link-destの世代バックアップを自分で作ります。