遠(yuǎn)程工作的需求無非兩個(gè):
- 遠(yuǎn)程執(zhí)行命令。
- 在遠(yuǎn)程與本地之間進(jìn)行文件的雙向傳輸。
所有的遠(yuǎn)程工作流都需要考慮如何提高這兩個(gè)操作的效率。
1. 一般遠(yuǎn)程工作流
對(duì)于一般的遠(yuǎn)程機(jī)器,我們可以通過 ssh 進(jìn)行連接和操作,并使用 scp 命令或 SFTP 客戶端實(shí)現(xiàn)雙向文件交換:
# 登錄開發(fā)機(jī)
ssh dest_host
# 上傳文件
scp path/to/local_file dest_host:path/to/remote_file
# 下載文件
scp dest_host:path/to/remote_file path/to/local_file
有很多可視化的 SFTP 工具能夠代替 scp 命令完成文件雙向傳輸,非常方便,例如 WinSCP、Xmanager 等。
主流的文本編輯器也都提供了對(duì) SFTP 的插件支持,例如:
可以很方便地上傳、下載、刪除、編輯遠(yuǎn)程文件。
2. 中繼機(jī)下的遠(yuǎn)程工作流
考慮到安全原因,公司常常會(huì)對(duì)遠(yuǎn)程開發(fā)機(jī)的入口做限制,想要連接開發(fā)機(jī)必須以一個(gè)中繼機(jī)器作為中介。這時(shí)候我們需要兩次 ssh 連接:首先連接到中繼機(jī),然后從中繼機(jī)連接到開發(fā)機(jī)。
# 登錄到中繼機(jī)
ssh relay_host
# 現(xiàn)在我們已經(jīng)在中繼機(jī)上…
# 登錄開發(fā)機(jī)
ssh dest_host
中繼機(jī)的存在除了造成登錄更復(fù)雜之外,也使得文件傳輸更難實(shí)現(xiàn),因?yàn)榻^大多數(shù) SFTP 工具都沒有中繼功能,在這種情況下無法使用。
按照傳統(tǒng)的方案,我們需要兩次 scp 命令來完成一次文件上傳操作:首先從本地上傳到中繼機(jī),然后從中繼機(jī)上傳到開發(fā)機(jī)。但是這種方式顯然太復(fù)雜了,而且大部分中繼機(jī)對(duì)安全的要求非??量?,只允許使用 ssh 命令,導(dǎo)致 scp 方式失效。
此時(shí)我們有以下三種方案來實(shí)現(xiàn)文件傳輸功能:
2.1 SSH 隧道
為了避免重復(fù)性的中繼命令,我們可以借助 ssh 提供的“隧道”功能。該功能可以透過任意數(shù)量的中繼機(jī),在本地機(jī)器與目標(biāo)機(jī)器之間建立一條“隧道”。因此,文件的上傳、下載依然可以通過本地機(jī)器上的一條命令完成。
同時(shí),SSH 隧道有一個(gè)巨大的好處:所有的 SFTP 工具依然可用,因?yàn)樗淼缹?duì)外部是透明的。
關(guān)于隧道功能,可以查看
ssh幫助手冊(cè)中的-ProxyJump、-ProxyCommand、-R、-L等參數(shù)的用法。
不過使用該方案有兩個(gè)前提:
- ssh 版本必須足夠新,以支持隧道功能(OpenSSH 7.3 +)。
- 中繼機(jī)必須允許 TCP 轉(zhuǎn)發(fā)。
但不幸的是,很多中繼機(jī)對(duì)安全的要求非??量?,不允許 TCP 轉(zhuǎn)發(fā)。在這種情況下,該方案無法工作。
2.2 szrz 工具
szrz 是一個(gè)輕量、便捷的解決方案,其內(nèi)部采用的 ZModem 協(xié)議非常底層,對(duì)中繼機(jī)是透明的。因此 szrz 是中繼機(jī)環(huán)境下文件傳輸問題的天然解決方案。
szrz 容易使用,配置完成后,在開發(fā)機(jī)的控制臺(tái)中使用 sz 命令下載文件,rz 命令上傳文件,同樣可以透過任意數(shù)量的中繼機(jī)。
但 szrz 有兩個(gè)嚴(yán)重弊端:
- 不支持大文件傳輸(超過 30MB 的文件就會(huì)把控制臺(tái)卡死)。
- 喪失了 SSH 協(xié)議的一切好處,比如安全性、豐富的 SFTP 工具等。
2.3 不使用 SSH,而是借助 FTP、HTTP 等其他協(xié)議
既然 SSH 協(xié)議被中繼機(jī)限制了,那我們不如另立門戶,借助 FTP、HTTP 等其他協(xié)議來實(shí)現(xiàn)文件傳輸??紤]到 FTP 天然適合靜態(tài)文件服務(wù),比 HTTP 高效很多,所以我們一般選擇搭建 FTP 服務(wù)。
FTP、HTTP 服務(wù)器是非常成熟、穩(wěn)定的技術(shù),基本上隨意挑選一款工具都可以滿足我們的需求。我們以 pyftpdlib 為例:
- 在開發(fā)機(jī)上安裝 FTP 工具:
pip install pyftpdlib
- 啟動(dòng) FTP 服務(wù)
python -m pyftpdlib # and many other options ...
我們實(shí)際在用的啟動(dòng)命令:
# 考慮安全因素,可設(shè)置用戶名和密碼
python -m pyftpdlib --directory /home/work/ --port 8888 -r 8000-9000 --user username --password ****** --write
FTP 服務(wù)非常穩(wěn)定,極少出錯(cuò),因此你可以把上述命令放到后臺(tái)執(zhí)行,并且丟棄其日志:
nohup python -m pyftpdlib ...blahblah... >/dev/null 2>&1 &
開發(fā)機(jī)配置完成之后,我們就可以在本地進(jìn)行文件上傳、下載操作了:
# 下載文件
curl ftp://dest_host:8888/tmp/test.tar.gz -o test.tar.gz -u username:******
# 上傳文件
curl -T test.tar.gz ftp://dest_host:8888/tmp/test.tar.gz -u username:******
FTP 解決方案的優(yōu)勢(shì)如下:
- 支持大文件,并且傳輸速度是三種方案中最快的。
- 天然支持可視化,可直接把 ftp 地址輸入瀏覽器查看、下載文件。
- 安全性:比 SSH 稍弱,但考慮到開發(fā)機(jī)僅公司內(nèi)網(wǎng)可見,因此并不需要過度擔(dān)憂。
- FTP 與 SFTP 一樣,有著豐富的第三方工具可用。
3. 終極遠(yuǎn)程工作流:實(shí)現(xiàn)遠(yuǎn)程實(shí)時(shí)編輯
文件的上傳下載其實(shí)是個(gè)低頻需求,遠(yuǎn)程實(shí)時(shí)編輯開發(fā)機(jī)上的文件才是真正的痛點(diǎn),這樣就實(shí)現(xiàn)了遠(yuǎn)程工作空間(remote workspace)。在這個(gè)需求上,SSH 隧道和 FTP 解決方案更能充分提現(xiàn)其優(yōu)越性。
目前主流的文本編輯器都支持 SFTP、FTP 等插件,比如:
這些插件可以在本地目錄和遠(yuǎn)程 SFTP/FTP 目錄之間建立映射,從而實(shí)現(xiàn)遠(yuǎn)程實(shí)時(shí)編輯開發(fā)機(jī)上的代碼(以下圖片引自 Sublime Text SFTP):

當(dāng)然,你也可以不做實(shí)時(shí)映射,而是使用手動(dòng)方式同步本地和遠(yuǎn)程的代碼:

在這種工作流下,編輯遠(yuǎn)程機(jī)器上的代碼與編輯本地代碼沒有任何差別。
相比如下兩種工作流:
- 本地編輯代碼->上傳到開發(fā)機(jī)->發(fā)現(xiàn)問題->重復(fù)以上三步(或使用 vim 做簡單修改)
- 登錄開發(fā)機(jī)->使用 vim 編輯代碼(這種方式的弊端是不夠工程化,大代碼量難以管控)
remote workspace 工作流有著可視化編輯器的加成,在實(shí)踐中可以大大提高開發(fā)效率。