搭建私人實體編譯服務器


有一台性能較好的台式機(以下簡稱 H(ome)),希望在離開它的幾天內依舊可以繼續在其上的工作。這台 H 沒有公網 IP,於是購買一台雲服務器(以下簡稱 C(loud)),獲得公網 IP。使用 ssh forwarding 將 H 的 ssh 22 端口映射到的 C 的 2222 端口。之后進行開發部署。

另外鏈接 C 的筆記本電腦(L(aptop))。

以下介紹部署過程,備忘。

1. 雲服務器選購

因為雲服務器只是跳板機,只需要良好的連通性,幾乎無 CPU 和內存需求。本着合(節)適(約)的原則,選擇最便宜配置的服務器,選擇阿里雲 ECS,在購買界面選擇“一鍵購買”。選擇最便宜的1 vCPU 1 GiB的機器。因為當前應用只是個人使用,網絡傳輸量小,也沒有穩定長時間的流量,所以帶寬處選擇按使用流量(固定的配置費用減少 40%)。可以調整帶寬到 100Mbps,流量價格與 1Mbps 一致,僅需¥0.800/GB

這個選擇與 H 相同的鏡像,Ubuntu 18.04。

購買成功后,第一次用密碼登錄,ssh-keygen 生成密鑰對。將 H 與 L 的公鑰放置到 C 的 ~/.ssh/authorized_keys 文件中。

同時將 C 的公鑰放置到 H 的相同位置,方便 C 登錄 H。

在 C 的 ~/.ssh/config 中配置 H 的別名,在 L 的 ~/.ssh/config 中配置 H 的別名。各種需要的別名都配置一下,方便后續配置。

~/.ssh/config 的配置如下。

Host H
Hostname localhost
Port 2222
User jingetu

2. SSH forwarding

在 H 上進行 ssh forwarding 將端口映射到 C 上。命令如下。

# 將 H 的 22 端口映射到 C 的 2222 端口
nohup ssh -NR 2222:localhost:22  -o ExitOnForwardFailure=yes -o ServerAliveInterval=10 C &

這個 forwarding 不穩定,后面命令中的 -o ExitOnForwardFailure=yes -o ServerAliveInterval=10 就是用來保活用的。

為了進一步優化,想到用 crontab 按時檢查該進程是否存在。所以寫了這么一個 python 腳本 auto_ssh.py,檢查是否有該進程,如果沒有就再執行一次啟動。

#!/usr/bin/python

import subprocess
import os

out = subprocess.check_output("ps -ef | grep NR | grep ssh", shell=True)
if "2222:localhost:22" not in out_str:
    os.system("nohup ssh -NR 2222:localhost:22 -o ExitOnForwardFailure=yes -o ServerAliveInterval=10 C &")

這個 ssh 命令應當是非 root 用戶執行的,因為是從 C 以正常用戶身份登錄 H。

crontab 實現定時運行以上腳本,以保活。以正常用戶身份輸入 crontab -e 進行編輯,添加行 * * * * * python /home/jingetu/auto_ssh.py,表示每分鍾執行一次。(關於 crontab 的語法問題,可以通過網站 https://crontab.guru/ 測試,完全不需要記憶 crontab 語法規則。)之后可以使用 crontab -l 查看當前用戶的定時任務。

crontab 還有另外一個好處,就是重啟機器,crontab 的任務設定依舊存在。所以遠程 reboot H,僅需耐心等待 1 - 2 分鍾,H 便可自動 forwarding 到 C。

對於重啟,還有一些需要設置。1. 在 Settings -> Users 中將當前用戶設置成 Automatic Login,重啟進入系統無需輸出密碼;2. H 是雙系統,安裝一個 Ubuntu 軟件 Grub Customizer,調整在 grub 時 Ubuntu 是默認選項。

現在不是很確定以上操作的穩定性。所以還有一種想法是 */30 * * * * killall ssh,每 30 分鍾自動斷開一次 forwarding,下一分鍾會有 auto_ssh.py 腳本自動啟動 forwarding。這么做犧牲體驗。

3. 開發環境配置

已知 VSCode 有服務器開發功能,可以通過 ssh 修改服務器 C 上的代碼。但實際的編譯過程應當在 H 上進行,所以就需要做一個代碼同步的工作。

3.1. 代碼同步

將 H 上的代碼整理到 C 的特定位置。安裝軟件 lsyncd 進行單方向 C -> H 的同步,只要 C 上的目錄下有任何變化就會同步到 H 上的目錄下。

配置文件 /etc/lsyncd.conf 如下:

settings {
   logfile    = "/tmp/lsyncd.log",
   statusFile = "/tmp/lsyncd.status",
   nodaemon   = true,
   statusInterval = 3
}

sync {
   default.rsync,
   source="/root/code_dir",
   target="H:/home/jingetu/code_dir",
   delay=1,
   exclude={'*.swp', '*.swx', '*~'},
   rsync = {
     archive = true,
     compress = false,
     _extra   = {"--omit-dir-times","-e ssh -i /root/.ssh/id_rsa"}
   }
}

delay=1 表示每隔 1 秒同步一次。C 上的代碼目錄是 /root/code_dir,H 上的代碼目錄是 /home/jingetu/code_dir

執行 lsyncd -nodaemon /etc/lsyncd.conf 就可以開啟同步。

3.2. VSCode 遠程開發

在 L 上,安裝 vscode,參考 https://code.visualstudio.com/docs/remote/ssh ,進行配置。也就是安裝 vscode 的 extension Remote Development

按操作鏈接 C,會打開一個新的窗口,按指示打開 C 上的目錄 /root/code_dir

然后在 vscode 的底部開啟兩個 terminal(C 的 terminal).第一個 terminal 執行 lsyncd -nodaemon /etc/lsyncd.conf,前台運行,可以查看 C 到 H 的同步日志。第二個 terminal,執行 ssh H,登錄到 H,進行正常的代碼修改后的編譯、運行工作。

注意,不要在 lsyncd 沒有啟動的時候,修改服務器上的代碼。因為同步是按事件觸發的,修改的事件沒有被 lsyncd 記錄下來,沒有同步會造成兩處代碼不同步。

執行完以上操作就可以開始在 L 的 vscode 窗口寫代碼。

4. 保活

H 上設置以下腳本 crontab,自動連接 WiFi。第二次檢查 ifconfig,如果沒有鏈接上,有可能是網卡沒有掛載上,重啟一般能掛載上。

#!/usr/bin/python3

import subprocess
import os

out = subprocess.check_output("ifconfig", shell=True)
out_str = out.decode('utf-8')
if "wlo1" not in out_str:
    os.system("nmcli c up id WiFi_NAME_XXX")

out = subprocess.check_output("ifconfig", shell=True)
out_str = out.decode('utf-8')
if "wlo1" not in out_str:
    os.system("sudo /sbin/shutdown --reboot now")

有些時候可以將 H 進入到睡眠狀態,在睡眠狀態無 WiFi 鏈接,所以 C 就不能控制 H 從睡眠狀態中恢復回來。可以在睡眠之前先設定恢復時間,這個恢復由 BIOS 控制,所以時間是 BIOS 時鍾(Real Time Clock)的時間。以下是睡眠 3600 秒之后恢復。

sudo rtcwake -m disk -s 3600

睡眠命令如下。(記得這個命令需要謹慎使用,不要一睡不醒,可以可以查看一下 rtcwake 每天固定時間恢復,這樣就可以保證最多睡 24 小時。)

systemctl suspend

在 C 上清理使用 2222 端口的進程(有些時候會重復鏈接)。

kill $(lsof -t -i tcp:2222)

以上的代碼同步並不是一個很好的方法,可以直接用 sshfs 在 C 上掛載 H 的目錄。再從 L 上掛載 C 的目錄。(macOS 安裝 sshfs 有點問題,所以對於代碼目錄,可以直接掛載在 C 上,再從 L 上選擇 VSCode 遠程開發
。)

mkdir ~workspace && sshfs -o allow_other,default_permissions H:workspace ~/workspace


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM