想運行一個比較大的任務,需要很強的CPU和內存,自己老筆記本跑不動。在阿里雲上租一個Ubuntu服務器,但是希望任務結束后服務器實例自動刪除,要不半夜時分任務跑完了,第二天早上再回收...... 心疼 :)
做了些嘗試,初步達成目的,記錄如下,有些踩過的坑供借鑒。
環境
- 管理服務器:已經有了一個雲服務器(Ubuntu),1 CPU 2G RAM 免費半年的那種,根本不能跑我的任務,但是可以用做控制台。我下面的操作都是在這台機器上發出的。
- 工作服務器:真正干活的雲服務器(4核CPU, 16G RAM, 80G HD) 是手工申請的。應該可以自動申請(aliyuncli ecs CreateInstance),但這不是我的需求重點,我關心的是自動stop, delete. 以后也許有機會把創建也自動化。
- OSS 網盤: 90+G 的數據存在 OSS上,需要從工作服務器上讀取,處理后的結果也會保存在這里,因為工作服務器會被銷毀。
步驟
- 在管理服務器上安裝 Aliyun 命令行工具 和 SDK。基本安裝比較簡單,按照文檔做就可以,但是特別注意,在Ubuntu下最后要手工把安裝包copy到系統位置,否則aliyuncli 找不到可用命令。這是我折騰幾個小時,提交工單后得到答案。 在管理服務器上安裝,測試 ossfs。目的是把oss 上的大文件mount 成為工作服務器上的某個目錄。
- ossfs 掛載命令是 ossfs bucket_name /mnt_point -ourl=http://oss_region.
- 這里要注意url,我開始總是mount不上, 第一不能包括bucket name; 第二,對於在VPC中的雲服務器,url 需要特殊寫法,比如vpc100-oss-cn-hangzhou.aliyuncs.com,內網的url 是不通的,外網的也不穩定。詳細的region 列表在這里。
- 另外,我遇到過多次ossfs 命令 hang在那里不返回,其實開另外一個ssh窗口發現命令已經成功,可以訪問掛載的內容,但ossfs 就是不返回。可以在ossfs 命令最后加上 -f -d 看調試輸出。
- 因為我的oss有很大空間,我試過 ossfs 一個bucket 到 /tmp。但是一旦這么做,在/tmp做一點操作就會hang住,gunzip, df -h, lsof, 甚至ls /tmp 都不行,說明oss 不適合頻繁密集讀寫。(想掛載/tmp 因為gunzip 會占用大量 /tmp空間,直到把系統盤40G撐滿了,這個時候du 查不到,df -h 發現空間沒了,lsof |grep deleted 發現都在 /tmp 下面,沒有釋放)。
- 最后使用了兩個 shell 腳本完成了任務。第一個腳本總控(provision 工作服務器,最后kill it),第二個腳本發送到工作服務器,在上面運行做那個費力的任務。
- 控制腳本。
- 整個腳本只需要輸入一次遠程服務器密碼,scp 的幾個文件是給ossfs 用的
# local shell export ESC_ID=i-xxxxxxxxx export set ESC_NAME=ali_ecs cat /root/.ssh/id_rsa.pub | ssh root@$ESC_NAME 'mkdir -p .ssh; cat >> .ssh/authorized_keys'
# config for osscmd
# scp /root/.osscredentials root@$ESC_NAME:/root
# config for ossfs
scp /etc/passwd-ossfs root@$ESC_NAME:/etc
# worker shell
scp /root/remoteAction.sh root@$ESC_NAME:/root echo $(hostname) echo ------------------------- ssh root@$ESC_NAME 'chmod +x /root/remoteAction.sh; /root/remoteAction.sh' echo ------------------------- aliyuncli ecs StopInstance --InstanceId $ESC_ID sleep 30 aliyuncli ecs DeleteInstance --InstanceId $ESC_ID sleep 10 aliyuncli ecs DescribeInstanceAttribute --InstanceId $ESC_ID
worker shell. remoteAction.sh
apt-get update cd /root # --------------------- # install osscmd # wget -O osscmd.zip https://docs-aliyun.cn-hangzhou.oss.aliyun-inc.com/internal/oss/0.0.4/assets/sdk/OSS_Python_API_20160419.zip?spm=5176.doc32171.2.2.cRTWFj&file=OSS_Python_API_20160419.zip # apt-get -y install unzip # unzip osscmd.zip # rm *.zip # --------------------- # install ossfs wget -O ossfs.deb http://docs-aliyun.cn-hangzhou.oss.aliyun-inc.com/assets/attach/32196/cn_zh/1481699531936/ossfs_1.80.0_ubuntu14.04_amd64.deb?spm=5176.doc32196.2.1.kxKrKX&file=ossfs_1.80.0_ubuntu14.04_amd64.deb # -y assume yes apt-get -y install gdebi-core # -n --non-interactive gdebi -n ossfs.deb mkdir /mnt/gene ossfs bob-backup /mnt/gene -ourl=http://vpc100-oss-cn-beijing.aliyuncs.com # --------------------- # run my big job # 命令行中 - 作為參數占位符。比如下面的命令 b.sh 要讀2個參數,第二個參數 用- 代替,表示內容是 a.sh 的標准輸出。
./a.sh r1.csv r2.csv \
| ./b.sh ref.csv - 2> out.log \
| ./c.sh convert - > out.dat;
總結
除了以上步驟,還有其他的自動化的方法值得嘗試:
- docker machine + ESC driver. 一旦做好鏡像, commit之后就不用每次安裝ossfs了,雖然安裝也很快。但是在現有的雲服務器上運行 curl下載docker machine 總超時,懶得折騰,先放下了。
- Airflow, celery worker。 如果任務非常復雜,值得去嘗試。
- 我只有一台機器要管理,ansible 給適合多任意多台機器重復管理步驟,所以就沒用。以后也許可以寫playbook 代替shell 腳本完做這件事。