最近有個需求為開機的時候服務(wù)器自動執(zhí)行一次puppet agent -t
命令,如何利用puppet管理這一個動作呢盆驹,想到了以下三個方案:
- 寫一個sysv風(fēng)格的shell script放在/etc/init.d/目錄下银择,然后用puppet的官方常用類型資源
service
來定制開機啟動此腳本低斋,譬如,腳本為/etc/init.d/runppagent.sh查库,puppet的語法如下
file { '/etc/init.d/runppagent':
ensure => 'present',
owner => 'root',
group => 'root',
mode => '0755',
source => "puppet:///modules/項目代號/runppagent",
}
service { 'runppagent': #這里要注意的是此資源一定要在/etc/init.d/目錄下
enable => true,
}
- 利用puppet統(tǒng)一管理文件/etc/rc.local文件,把
puppet agent -t
這一操作寫在/etc/rc.local文件里面周瞎,開機的時候會執(zhí)行這個文件的命令 - 利用puppet 的cron @reboot功能來實現(xiàn)苗缩,puppet語法如下
# 開機執(zhí)行puppet agent -t操作
cron { 'excute the puppet agent':
ensure => present,
command => '/usr/local/bin/puppet agent -t',
user => 'root',
special => 'reboot',
}
經(jīng)過考慮,第一個方式不太可靠声诸,因為放在/etc/init.d下的腳本執(zhí)行有一定的順序酱讶,如果提前執(zhí)行了puppet agent -t這個命令會出事的,so第一個方式去除双絮;第二個方式浴麻,因為之前線上的/etc/rc.local文件有好幾個版本得问,現(xiàn)在要統(tǒng)一管理起來的風(fēng)險也挺大囤攀,so 也去除;那么就很開心的使用了第三張方式
重點就要說說第三種方式宫纬,有個特別的地方就是利用了cron的一個特性@reboot焚挠,來判斷是否要執(zhí)行這一操作。這時候我就有個疑問漓骚,cron是如何判斷服務(wù)器是否reboot了? 我又想了下是否有以下可能
- cron這個daemon重啟了就認為服務(wù)器已經(jīng)重啟蝌衔?
- cron根據(jù)uptime信息來判斷服務(wù)器是否重啟?
- 捕捉run level的狀態(tài)來判斷服務(wù)器是否重啟蝌蹂?
作為一名it人員當然就是噩斟,寫一個cron條目來測試上述條件是否成立,最后發(fā)現(xiàn)都不能觸發(fā)@reboot這個操作孤个,那么我們就來看看源代碼吧剃允,因為the code will tell u everything,(雖然自己寫代碼很菜
#ifdef DEBIAN
#define REBOOT_FILE "/var/run/crond.reboot"
/* Run on actual reboot, rather than cron restart */
if (access(REBOOT_FILE, F_OK) == 0) {
/* File exists, return */
log_it("CRON", getpid(),"INFO",
"Skipping @reboot jobs -- not system startup");
return;
}
/* Create the file */
if ((rbfd = creat(REBOOT_FILE, S_IRUSR&S_IWUSR)) < 0) {
/* Bad news, bail out */
log_it("CRON",getpid(),"DEATH","Can't create reboot check file");
exit(0);
} else {
close(rbfd);
log_it("CRON", getpid(),"INFO", "Running @reboot jobs");
}
Debug(DMISC, ("[%d], Debian running reboot jobs\n",getpid()));
#endif
Debug(DMISC, ("[%d], vixie running reboot jobs\n", getpid()));
for (u = db->head; u != NULL; u = u->next) {
for (e = u->crontab; e != NULL; e = e->next) {
if (e->flags & WHEN_REBOOT) {
job_add(e, u);
}
}
}
這小段代碼你能看出是依據(jù)REBOOT_FILE /var/run/crond.reboot
來判斷服務(wù)器是否重啟齐鲤,我們再看/var/run這個目錄的官方說法斥废,抽我
This directory contains system information data describing the system since it was booted. Files under this directory must be cleared (removed or truncated as appropriate) at the beginning of the boot process. Programs may have a subdirectory of /var/run
上面一寸英文的解釋就是說,開機的時候這個目錄下的文件都要被清除给郊,因此再結(jié)合cron節(jié)選的c代碼我們可以得知是根據(jù)/var/run/crond.reboot此文件的存在與否牡肉。
最后經(jīng)過測試,先把文件/var/run/crond.reboot刪除淆九,再restart cron统锤,則觸發(fā)@reboot操作,有興趣的朋友可以嘗試一下炭庙。
題外話饲窿,debian到底是在哪個步驟來清除/var/run這個目錄的的呢,首先我們可以看到/var/run這個目錄煤搜,是鏈接到/run下面的免绿,再用df命令來看到/run是一個tmpfs(臨時文件系統(tǒng))
這是debian手冊給出的解釋
After mounting all the filesystems, temporary files in "/tmp", "/var/lock", and "/var/run" are cleaned for each boot up.
root@cc-unknown23344:/etc/init.d# ls -l /var/run
lrwxrwxrwx 1 root root 4 4月 16 2013 /var/run -> /run
root@cc-unknown23344:/etc/init.d# df -h /run
Filesystem Size Used Avail Use% Mounted on
tmpfs 26G 180K 26G 1% /run