庖丁解puppet之高级篇
(组织结构设计

 

前言:
    我们经过puppet之初级入门puppet之中级进阶后,可以说你也可以用puppet管理上100台linux服务器了,但管理服务器越多,在site.pp里要设置的东西就越多,如真有上千台服务器要管理,1千个节点的配置文档都作到site.pp里,势必它将变得很复杂并很难去管理,因此puppet组织结构研究就出来了,我们可把配置文件存储在多个文件夹和文件中。我们把Site.pp文件看作一个金字塔的顶点,其它所有文件及文件夹由它引用即可。

一、常见结构整理
   看了网上无数资料,通过亿图画出了以下三种结构,红色的表示根目录,桔色的表示目录,蓝色的表示文件。因为我处于探索puppet中,所以不好说谁好谁坏,根据我目前个人的理解,我觉得图二比较适合我公司用,linux服务器不多,只有70台左右,其它几百台服务器都是windows,用不上puppet。图一,太过于简单,如果节点服务器一多,结构势必会有点乱,图三,过于精细化,对上千台服务器的规模有用。


(1)、编写base.pp
功能说明:安装cron包并启动服务

#vim base.pp
class cron::base {
package { cron:
name => $operatingsystem ?
{#facter 获取客户端操作系统确定包的名称
ubuntu => "cron",
debian => "cron",
redhat => "vixie-cron",
centos => "vixie-cron", },
ensure => present,
}
service { crond:
name => $operatingsystem ? { #确定启动cron的名称
ubuntu => "cron",
debian => "cron",
redhat => "crond",
centos => "crond", },
ensure => running,
enable => true,
pattern => cron,
require => Package["cron"], #依赖关系
}
}
(2)、编写crontabs.pp
功能说明:安装crontabs包

#vim crontabs.pp
class cron::crontabs {
package { crontabs:
name => $operatingsystem ? {
redhat => "crontabs",
centos => "crontabs",
},
ensure => present,
}
}

(3)、编写addcron.pp
功能说明:添加crontab定时任务(定时同步时间服务器每4个小时同步的第1分钟同步)

#vim addcron.pp
class cron::addcron {
cron { ntpdate:
command => "/usr/sbin/ntpdate time-b.timefreq.bldrdoc.gov",
user => root,
hour => '*/4',
minute => '1'
}
}

(4)、编写init.pp
功能说明:初始化文件

#vim init.php
class cron {
case $operatingsystem {
centos: {
include cron::base
include cron::crontabs
}
redhat: {
include cron::base
include cron::crontabs
include cron::addcron #这三行实现安装添加cron功能
}
debian: { include cron::base }
ubuntu: { include cron::base }
freebsd: { }
}
}

(5)、编写主manifests文件实现让客户端安装cron和添加一条crontab作业。

#cd /etc/puppet/manifests
#vim modules.pp #加载cron模块
import "cron"
#vim nodes.pp #客户端节点管理文件
node 'client.puppet.com'{
include cron
}
#vim site.pp #加载modules.pp 和nodes.pp
import "modules.pp"
import "nodes.pp"

重启服务端服务
# /etc/init.d/puppetmaster start

客户端
执行同步
# puppetd --server server.puppet.com --test


manifests/
|– modules.pp #模块导入接口,使用import systembase(模块名)方式导入
|– node.pp #节点文件,在节文件里面include 模块
|– site.pp #puppet主要入口

modules/
|– systembase #模块的名称
|—templates #模板目录
|– files #文件目录
|– hosts
|– vimrc
|– manifests #模块主入口
|– init.pp #这个文件是必须存在的

#cat modules.pp
Import “systembase”
#cat node.pp
Node ‘node.xxxx.com’{ #node.xxxx.com 是客户端的hostname
Include systembase #如果同时导入多个模块用逗号隔开
}
#cat site.pp
Import “node.pp” #导入节点文件
Import “modules.pp” #导入模块文件
Node default { #默认节点测试内容
File { “/tmp/lightest.txt”:
Content => “powerlgh is test puppet”,
}
}
#cat host
Ha ,ha
# cat init.pp
##systembase class modules
Class systembase {
#system files
File { “/opt/host”: #一个语句的开始用冒号
Mode => 0644, #语句中间用逗号
Source => “puppet://$fileserver/systembase/host”; #一个语句结束后使用分号
}
}

 

1所有的配置文件最后都要被主site.pp引用。
主线是:1 class目录下的类.pp=>服务的主配置文件init.pp=>引用模块的mudule.pp
2 node文件夹下服务器分组node节点.pp(例如C.pp)=>node文件夹下site.pp
3主配置site.pp把1的mudule.pp 和2的node文件夹下site.pp 去“ import”。
2但是site.pp,不是唯一的,我们可以建无数的site.pp,需要在/etc/puppet/manifests目录下
3 维护方法:
3.1增加服务为模块,在/etc/puppet/module目录下新建文件夹。
3.2只需要维护此模块下的class下的文件,配置文件全部引用变量,在对应的node里面“ include”类,并且申明变量值。

其中重要文件配置(我这里主要是ice的升级和回滚):
#cat manifests/node/site.pp
import “java.pp”
import “c.pp”
#cat modules/revfsserver/manifests/init.pp
import “class/*.pp”

#cat manifests/node/c.pp
node ‘client.dongwm.com’ {
$group=”dongwm”
$owner=”dongwm”
$tar=”X.tar.gz”
$homedir=”/opt/newfs/bin”
$tardir=”/opt/src”
$path=”/usr/bin:/usr/sbin:/bin”
include ice::base
include ice::update
include ice::rollback

}

# cat manifests/site.pp
import “node/site.pp”
import “node/module.pp ”

#cat manifests/module.pp
import “ice”

二、实例操作
目的:
通过模块化编写,实现两台web客户机更新web站点

2.1搭建结构

2.2结构解说:
    所有的PP,最后都是site.pp里进行引用,modules下面根据业务建立文件夹,每个文件夹就是一个模块。这里的案例是更新java和puppet的两个web服务器,所以取名为java-web,puppet-web。所有的模块,都在node.pp和modules.pp里引用,注意node.pp里引用,用的关键词是include,不是import。每个模块下,必须有个init.pp。
[root@testsns manifests]# more site.pp

import "node.pp"
import "modules.pp"
node default {
file {
"/tmp/lghtest.txt":
content => "powerlgh is test puppet",
}
}
[root@testsns manifests]# more node.pp

node 'nfstest' {
include java-web
}
node 'kaifa' {
include puppet-web
}

[root@testsns manifests]# more modules.pp

import "java-web"
import "puppet-web"
[root@testsns manifests]# more init.pp
##java-web class modules

class java-web {
file
{ "/opt/java-web-update-file/java.war":
source => "puppet://$puppetserver/java-web/java.war",
notify => Exec["exec-java-web-update"],
}
exec
{ "exec-java-web-update":
cwd => "/root/scripts",
command => "sh /root/scripts/update_java_web.sh",
user => "root",
path => "/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin",
}

}

init.pp
[root@testsns manifests]# more init.pp
##puppet-web class modules

class puppet-web {
file
{ "/opt/puppet-web-update-file/puppet.war":
source => "puppet://$puppetserver/puppet-web/puppet.war",
notify => Exec["exec-puppet-web-update"],
}
exec
{ "exec-puppet-web-update":
cwd => "/root/scripts",
command => "sh /root/scripts/update_Puppet_web.sh",
user => "root",
path => "/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin",
}

}

2.3服务器端执行:
[root@testsns manifests]# puppetrun nfstest kaifa

2.4客户端查看日志:
[root@nfstest opt]# tail -f /var/log/messages

[root@kaifa puppet]# tail -f /var/log/messages

2.5打开网站,再次验证:


嗯,达到效果了。
三、总结:
   把开发部送过来的包,丢到modules目录下的files文件里,然后执行puppetrun host1 host2 host… 就行了,不过实验中发现,客户端默认是每半小时去连接一次puppet服务器端,不管有没有更新,sh更新脚本还是执行了,这是个严重问题,解决办法有两个,一是把客户端的间隔时间延长,但能延多长,网上的资料没说,二是不起puppet客户端,登录到客户端手工执行,这种方式,在我公司不多的服务器上还是可取的,本身每次更新的程序,谁都无法保证能正常更新在生产环境中,即时通过测试环境通过了,所以每次我在更新程序时,先看catalila.out日志,有没有报错,有错,程序一定有问题,没错,再打开页面访问一下,是否正常。
本博文参考了以下博文:
http://www.issacy.com/archives/587.html
http://dongwm.blog.51cto.com/2621371/471163
http://my.oschina.net/duxuefeng/blog/36201

四、后记:
   因个人精力有限,加上我公司的linux服务器不到100台,所以用puppet来作统一管理,真是浪费了puppet,我会在网站war更新中应用它,也就是应用它的file传输及shell命令执行两个功能,至于更深入的erb文件编写,就不去研究了,通过初级篇,中级进阶篇,到本文的高级篇,管理1000台以下的服务器,是可行的了。