Hudson, Jenkins, Gulp, Grunt 這些都是用來寫自動化的工具,網路已經有很多相關的教學,使用這些工具的公司更是不勝枚舉,而就算沒有這些工具,我們仍然可以用 Linux Command 來做自動化的工作,用起來也不會輸給那些工具,反而省去了復雜的設定,還更簡單維護。
檢查多台機器的 Log
在寫自動化程式前,我先來說明如果遠端呼叫 Linux 機器做事。
如果我有個線上機器 hostname 是 www.puritys.me,當線上機器發生問題時,我會需要檢查 /var/log/messages 檔案內的 Log 訊息,但是我不用真的登入線上機器,我只要使用 ssh host "command" 這個指令,就可以遠端呼叫線上機器把 log 印出來看。
- [www]$ ssh www.puritys.me "tail -n 5 /var/log/messages"
- May 23 12:30:01 localhost systemd: Starting Session 5094 of user root.
- May 23 12:30:01 localhost systemd: Started Session 5094 of user root.
- May 23 12:38:04 localhost systemd: Starting Session 5095 of user www.
- May 23 12:38:04 localhost systemd: Started Session 5095 of user www.
- May 23 12:38:04 localhost systemd-logind: New session 5095 of user www.
上面這個範例是當線上機器只有一台的時候,但若我們線上機器不只一台,例如 www1.puritys.me ~ www4.puritys.me 共四台機器,那麼單單靠上面這個指令,就得執行四次 。
這裡我要用 shell script 的 forloop 語法,一次執行呼叫四台機器印出我要的 Log 。
- [www]$ for i in $(seq 1 4); do ssh www$i.puritys.me "tail -n 1 /var/log/messages"; done;
為了更清楚呈現 每一台機器的 Log ,我們可以在 shell script 中加入 echo "in $host" ,先印出機器名稱。
- [www]$ for i in $(seq 1 4); do host=www$i.puritys.me ; echo "In $host:"; ssh $host "tail -n 1 /var/log/messages"; done;
- In www1.puritys.me:
- Warning: Permanently added 'www1.puritys.me' (RSA) to the list of known hosts.
- May 29 20:01:55 website systemd-logind: New session 30270 of user www.
- In www2.puritys.me:
- Warning: Permanently added 'www2.puritys.me' (RSA) to the list of known hosts.
- May 29 20:01:55 website systemd-logind: New session 30270 of user www.
- In www3.puritys.me:
- Warning: Permanently added 'www3.puritys.me' (RSA) to the list of known hosts.
- May 29 20:01:55 website systemd-logind: New session 30270 of user www.
- In www4.puritys.me:
- Warning: Permanently added 'www4.puritys.me' (RSA) to the list of known hosts.
- May 29 20:01:55 website systemd-logind: New session 30270 of user www.
如何使用 Makefile
剛剛的指令太長了,如果每次都要手動輸入的話就太累了,我們可以用 Linux 內建的 Gnu Make ,將指令寫在 Makefile 裡面,然後再用簡短的 command 來呼叫。
我建一個檔案檔名為 Makefile ,然後寫入我們要的指令:
- 注意每一行前面的空白必須是一個 tab
- Makefile 中如果要在使用有 $ 字串的指令,必須使用兩個 $ ,因為一個 $ 代表讀取某一個變數 。
- log:
- for i in $$(seq 1 4); do host=www$$i.puritys.me ; echo "In $$host:"; ssh $$host "tail -n 1 /var/log/messages"; done;
這個檔案建好之後,我就可以輸入 make log
,執行我剛寫入的指令。
另外有可能我們的機器名稱沒有一定的規則,那麼我們可以先把機器名稱寫入一個檔案:
- www1.puritys.me
- www2.puritys.me
- kkk.jjjj.com.tw
再使用 `cat hosts` 跟 forloop ,來對每一台機器傳送指令。
- log:
- for host in `cat hosts`; do echo "In $$host:"; ssh $$host "tail -n 1 /var/log/messages"; done;
線上機器 Release
如何快速的將新版程式,安裝到線上的所有機器呢? 這裡用 rpm package 來示範,首先用上面教的方式,讀取 hosts 內的所有機器 hostname ,再用 scp 指令,將 rpm 檔傳送到線上機器,最後再用 rpm -ivh 來安裝。
- release:
- for host in `cat hosts`; \
- do \
- scp test-1.0-1.x86_64.rpm $$host:~/ \
- && ssh $$host "sudo rpm -ivh test-1.0-1.x86_64.rpm"; \
- done
寫好指令後,以後我只要輸入 make release 就可以快速的將程式 release 出去。
- [www]$ make release
- for host in `cat hosts`; \
- do \
- scp test-1.0-1.x86_64.rpm $host:~/ \
- && ssh $host "sudo rpm -ivh test-1.0-1.x86_64.rpm"; \
- done
- test-1.0-1.x86_64.rpm 100% 1508 1.5KB/s 00:00
- Preparing... ########################################
- Updating / installing...
- test-1.0-1 ########################################