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)