2016
May
23

Hudson, Jenkins, Gulp, Grunt 這些都是用來寫自動化的工具,網路已經有很多相關的教學,使用這些工具的公司更是不勝枚舉,而就算沒有這些工具,我們仍然可以用 Linux Command 來做自動化的工作,用起來也不會輸給那些工具,反而省去了復雜的設定,還更簡單維護。

檢查多台機器的 Log

在寫自動化程式前,我先來說明如果遠端呼叫 Linux 機器做事。

如果我有個線上機器 hostname 是 www.puritys.me,當線上機器發生問題時,我會需要檢查 /var/log/messages 檔案內的 Log 訊息,但是我不用真的登入線上機器,我只要使用 ssh host "command" 這個指令,就可以遠端呼叫線上機器把 log 印出來看。

ssh command
  1. [www]$ ssh www.puritys.me "tail -n 5 /var/log/messages"
  2.  
  3. May 23 12:30:01 localhost systemd: Starting Session 5094 of user root.
  4. May 23 12:30:01 localhost systemd: Started Session 5094 of user root.
  5. May 23 12:38:04 localhost systemd: Starting Session 5095 of user www.
  6. May 23 12:38:04 localhost systemd: Started Session 5095 of user www.
  7. May 23 12:38:04 localhost systemd-logind: New session 5095 of user www.

上面這個範例是當線上機器只有一台的時候,但若我們線上機器不只一台,例如 www1.puritys.me ~ www4.puritys.me 共四台機器,那麼單單靠上面這個指令,就得執行四次 。

這裡我要用 shell script 的 forloop 語法,一次執行呼叫四台機器印出我要的 Log 。

Example
  1. [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" ,先印出機器名稱。

Example
  1. [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;
  2.  
  3. In www1.puritys.me:
  4. Warning: Permanently added 'www1.puritys.me' (RSA) to the list of known hosts.
  5. May 29 20:01:55 website systemd-logind: New session 30270 of user www.
  6. In www2.puritys.me:
  7. Warning: Permanently added 'www2.puritys.me' (RSA) to the list of known hosts.
  8. May 29 20:01:55 website systemd-logind: New session 30270 of user www.
  9. In www3.puritys.me:
  10. Warning: Permanently added 'www3.puritys.me' (RSA) to the list of known hosts.
  11. May 29 20:01:55 website systemd-logind: New session 30270 of user www.
  12. In www4.puritys.me:
  13. Warning: Permanently added 'www4.puritys.me' (RSA) to the list of known hosts.
  14. May 29 20:01:55 website systemd-logind: New session 30270 of user www.

如何使用 Makefile

剛剛的指令太長了,如果每次都要手動輸入的話就太累了,我們可以用 Linux 內建的 Gnu Make ,將指令寫在 Makefile 裡面,然後再用簡短的 command 來呼叫。

我建一個檔案檔名為 Makefile ,然後寫入我們要的指令:

  • 注意每一行前面的空白必須是一個 tab
  • Makefile 中如果要在使用有 $ 字串的指令,必須使用兩個 $ ,因為一個 $ 代表讀取某一個變數 。

Makefile
  1. log:
  2. 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 ,執行我剛寫入的指令。

另外有可能我們的機器名稱沒有一定的規則,那麼我們可以先把機器名稱寫入一個檔案:

hosts
  1. www1.puritys.me
  2. www2.puritys.me
  3. kkk.jjjj.com.tw

再使用 `cat hosts` 跟 forloop ,來對每一台機器傳送指令。

Makefile
  1. log:
  2. 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 來安裝。

Makefile
  1. release:
  2. for host in `cat hosts`; \
  3. do \
  4. scp test-1.0-1.x86_64.rpm $$host:~/ \
  5. && ssh $$host "sudo rpm -ivh test-1.0-1.x86_64.rpm"; \
  6. done

寫好指令後,以後我只要輸入 make release 就可以快速的將程式 release 出去。

Example
  1. [www]$ make release
  2. for host in `cat hosts`; \
  3. do \
  4. scp test-1.0-1.x86_64.rpm $host:~/ \
  5. && ssh $host "sudo rpm -ivh test-1.0-1.x86_64.rpm"; \
  6. done
  7. test-1.0-1.x86_64.rpm 100% 1508 1.5KB/s 00:00
  8. Preparing... ########################################
  9. Updating / installing...
  10. test-1.0-1 ########################################

回應 (Leave a comment)