puppet_003,svn,hook;自助更新部署
http://os.51cto.com/art/201012/240992.htm
【51CTO独家特稿】一直关注51CTO系统频道的读者们可能已经都知道了puppet这个工具。Puppet用于实现配置管理工作的自动化(详见2010年系统管理员日当天的外电头条),既可以减轻系统管理员的工作量,更主要的是减少人为造成的失误。在开始阅读本文有关puppet的实例讲解之前,推荐大家先阅读stone的这篇puppet入门教程。
作者简介:刘晗昭,网名蚊子(博客),某通信业国企系统工程师,熟悉各种主流开源软件的使用,部署和组合应用,以及主流网站架构。目前关注puppet线上应用与分布式缓存清除系统。
一直想写点关于puppet的文章,但通过学习发现,puppet更多的是参数配置上的东西,写理论性的内容无非就是翻译一下官方文档,不利于新人对于puppet的理解上手。于是觉得,还是应该结合实际应用写些关于puppet使用方面的东西更贴近大众。
首先简单介绍一下puppet。puppet是一种Linux、Unix平台的集中配置管理系统,使用自有的puppet描述语言,可管理配置文件、用户、cron任务、软件包、系统服务等。puppet把这些系统实体称之为资源,其设计目标是简化对这些资源的管理以及妥善处理资源间的依赖关系。
puppet采用C/S星状的结构,所有的客户端和一个或几个服务器交互。每个puppet客户端每半小时(可以设置)连接一次服务器端,下载最新的配置文件,并且严格按照配置文件来配置服务器,保证和该配置信息同步。配置完成以后,puppet客户端可以反馈给服务器端一个消息。如果出错,也会给服务器端反馈一个消息。
情景描述
在开始介绍实现方法之前,先介绍一下我们的业务情况。我们企业有不少项目是交给外包做的,相关的项目负责人或开发者有新的或更改过的项目文件会上传到我们的SVN服务器上,再由我们的系统管理员执行SVN update更新页面。一直以来我们的做法都是,项目负责人或开发者上传了新文件之后,去找到SA,SA再登录服务器手动执行svn up。每次都要SA动手实在很麻烦,所以前些日子看到puppet这个东西的时候,觉得这就是能够将项目负责人、开发者和SA从这个工作中解放出来的利器~
这个SVN自助更新系统的实现思路如下:
一、开发平台
- apache+perl-cgi
- puppet
二、功能介绍
系统管理员/项目执行者/开发人员通过web的get对应的url,然后触发更新puppet-master中的一个文件,puppet-client在同步时间到来的时候(默认半小时,可改),判断master上对应的项目文件的md5值是否有变化,如果有变化,触发puppet配置中对应的svn更新的程序,完成此项目的更新。
三、系统架构
四、实施步骤及相关说明解释
1、puppet配置
此处puppet的安装方法我就不写了,有需要的自行去网上查找。我这边是CentOS 5.4(服务器端)和CentOS 5.5(客户端),采用yum安装。
A、puppet-master配置
a) 首先是创建autosign.conf文件,此文件用于自动验证。
*.wenzizone.cn
这样所有这个域名过来的请求会自动验证。
b) 修改puppet.conf文件。如果是通过rpm或yum安装,此文件内容可以基本保持不变
[main]
logdir = /var/log/puppet
rundir = /var/run/puppet
ssldir = $vardir/ssl
bindaddress = 192.168.192.199
[puppetd]
classfile = $vardir/classes.txt
localconfig = $vardir/localconfig
此文件主要是定义了一些文件路径,我在这里添加了bindaddress = 192.168.192.199这条,绑定在了内网的ip上,因为我并不想让我的puppet-master被外网访问到,这个可以因个人环境而定。如果需要看详细的puppet.conf内容可以执行puppet --genconfig。
c) 修改fileserver.conf,增加如下内容
[system] path /etc/puppet/modules/system/files allow *.wenzizone.cn allow 192.168.192.0/24 [svnup] path /etc/puppet/modules/svn/files allow *.wenzizone.cn allow 192.168.192.0/24
此文件可以创建一个文件系统,有点类似rsync的配置,后面我会继续介绍。这个意思就是所有wenzizone.cn或者192.168.192.0网段的机器可以访问/etc/puppet/modules/svn/files下的文件。
注:以上三个文件都是放至在/etc/puppet目录下的
d) puppet功能配置
首先看下puppet的目录结构,
/etc/puppet/ |-- auth.conf |-- autosign.conf |-- fileserver.conf |-- manifests | |-- huodong_web.pp | `-- site.pp |-- modules | |-- svn | | |-- files | | | |-- hd_zf_up_file | | `-- manifests | | |-- hd_zf_up.pp | | |-- init.pp | `-- system | |-- files | | |-- puppet.client.conf | `-- manifests | |-- init.pp | |-- puppet_client.pp `-- puppet.conf
根下的manifests目录放置主配置文件,modules下面是各种的模块,在这里我设置了两个模块,system和svn,其中system用来给我的puppet-client同步puppet.conf文件,svn就是我这次介绍的重点了。
这里插个题外话:puppet的模块都是遵从
| |-- svn | | |-- files | | `-- manifests | | |-- init.pp
这种结构的,包含模块名字:svn目录,files目录,manifests目录,此目录下包含init.pp文件。
下面先看svn的这个模块
files目录:用来存放触发svn更新的文件的,我们可以在此目录下touch任何一个名字的文件,更新的工作由perl-cgi来控制,我这里使用的名字是:hd_zf_up_file
manifests目录:用来存放puppet的脚本文件的,必须包含init.pp文件,通常情况下可以把脚本都写入到这个一个文件中,但为了便于管理,最好是按照功能或者项目分开存放。我这里的hd_zf_up.pp就是我为公司线上的一个项目建立的。内容如下:
1class hd_zf_up 2{ 3 file { 4 "hd_zf_up": 5 group => 'root', 6 mode => '600', 7 owner => 'root', 8 path => "/tmp/hd_zf_up_file", 9 source => "puppet:///svnup/hd_zf_up_file", 10 } 11 12 exec { 13 "svn up": 14 cwd => "/var/www/html/www.51cto.com/zf", 15 path => "/usr/bin:/usr/sbin:/bin", 16 subscribe => File["hd_zf_up"], 17 refreshonly => true, 18 } 19}
下面详细解释一下:
1行定义了一个类,类似php里的类,用于将相应的方法整合。
3行是puppet的file方法,网上的介绍file是一种资源,我这里认为当作方法比较合适,这样就可以跟php的类相似了,file后面大括号里的都是file这个方法的属性。属性用来赋值,方法用来调用。当然怎样理解因人而异。
4行给这个file方法定义了一个方便使用的别名
5行定义此文件的属组是root
6行定义此文件的访问模式是只有属主用户可读可写
7行定义文件的属主也是root
8行定义此文件在puppet-client端的放置位置及文件名
9行定义了从puppet-master的什么文件拿到那个文件。这里就用到了前fileserver.conf定义的内容,可以看到svnup是预定义的别名,它实际对应的路径是/etc/puppet/modules/svn/files,这样后面跟的文件就会到这个路径下去取。整个svn这部分的配置理解就是:puppet-client要从source定义的路径拿到hd_zf_up_file文件放到client的/tmp目录下并将文件所以权给root用户和组,访问模式是600。
12行定义了puppet的exec方法,这个方法是使puppet执行系统命令或脚本用的。
13行是定义了exec要执行的命令,在这里是要求puppet执行svn up这个命令。也就是更新项目的命令
14行定义了上面的svn up命令要在什么目录下执行
15行定义了path的变量,用于系统可以找到svn对应的命令。
16行定义了一个依存关系,我们这里和17行联合起来解释,当file方法定义里的那个文件的md5值发生变化的时候,此exec方法触发,即当上面source里面定义的文件md5值发生改变了,就执行svn up这个命令。
题外话:起先我这里并没有想到要和一个文件进行联立,但结果发现,puppet会在每次触发的时候都执行exec这个方法,这会造成网络资源的消耗,因为svn里的数据并不是每次都有更新的,所以没必要每次都执行。
到此svn up这部分的配置就完成了。接下来看看init.pp里面的内容
class svn { import "hd_zf_up.pp" }
可以看到,init.pp的内容还是很简单的,只是引入了我们定义好的pp文件。
下面来介绍system那个模块的内容,这部分内容我主要讲同步puppet-client端配置文件的这个功能,这样方便我们一次性配置好client端的puppet。
files目录下:放置的是puppet.client.conf文件,主要内容如下
[main] logdir = /var/log/puppet rundir = /var/run/puppet ssldir = $vardir/ssl [puppetd] classfile = $vardir/classes.txt localconfig = $vardir/localconfig server = app-21-199.wenzizone.cn runinterval = 300 show_diff=true
从内容上看,基本上和master上一样,主要区别是后三行,server用于指明master的名字,可以是ip可以是对应的主机名(前提是你已经有了对应的解析)。runinterval用于指定puppet-client每次执行的间隔,单位是秒,最后一行是当文件被替换的时候是否显示不一样的地方。
manifests目录下同样放置了init.pp文件,同时我还自定义了一个puppet_client.pp,内容如下:
1 class puppet_client 2 { 3 file 4 {
5 "puppet_conf":
6 path => "/etc/puppet/puppet.conf",
7 source => "puppet:///system/puppet.client.conf",
8 }
9 exec
10 {
11 "reload-puppet-client":
12 command => "/etc/init.d/puppet force-reload",
13 require => Service["puppet_client"],
14 refreshonly => true,
15 }
16 service 17 { 18 "puppet_client": 19 name => "puppet", 20 enable => true, 21 ensure => running, 22 hasrestart => true, 23 hasstatus => true, 24 subscribe =>File["puppet_conf"], 25 } 26 }
相同的内容就不重复介绍了。这里exec部分的11行并不是直接写的要执行的命令,而是定义了富有含义的名字,比较直观,然后在12行通过command定义了要执行的命令。
13行表明exec能不能执行是依赖于service这个方法的,后面详细介绍。
16行开始定义了一个新的方法service。顾名思义就是服务类的方法。
18行同样定义了一个富有含义的名称。
19行定义这个服务的名字,这里的名字必须和/etc/init.d下对应的名字一样
20行表示此服务在开机时是否启动,true是启动
21行表示是否运行此服务,running表示运行。
22行指出管理脚本是否支持restart参数,如果不支持,就用stop和start实现restart效果. 可以设置的值是true 或 false
23行指出管理脚本是否支持status参数,puppet用status参数来判断服务是否已经在运行了,如果不支持status参数,puppet利用查找运行进程列表里面是否有服务名来判断服务是否在运行. 可以设置的值是true或false
24行表示,此服务运行依赖file这个方法,同时exec又require了service,这样当file里定义的配置文件有变化及文件md5值不一样的时候,exec就执行force-reload的命令。
再来看init.pp内容
1 class system 2 { 3 import "puppet_client.pp" 4 }
此内容很简单,主要是定义了一个system的类,然后导入puppet_client.pp的内容。
到此puppet上自定义的两大功能就介绍完成了,下面看看puppet如何加载。
回到/etc/puppet/manifests目录下,主要文件就两个,site.pp和huodong_web.pp。site.pp是主文件,huodong_web.pp是我为我需要svn更新的web服务器做的。内容如下
1 node "app198-vhost-192-55" { 2 #系统初始化工具 3 include system 4 include puppet_client 5 #祝福活动页面更新 6 include svn 7 include hd_zf_up 8 }
1行定义了一个主机名,此处可以是主机名可以是ip地址
3加载system类,这个类是在system模块下的init.pp中定义的
4在system类加载后就来加载puppet_client的类,这个累是在system模块下的puppet_client.pp定义的。
6,7行同样是加载svn模块中定义好的类。
接下来看site.pp的内容
1 node default 2 { 3 import "huodong_web.pp" 4 }
这个主文件的内容也很简单,首先定义了一个默认node,然后加载了huodong_web.pp文件。
到此master上puppte部分的配置就全部完毕了。接下来看client端上的配置
B、puppet-client上的配置
a) 登录到app198-vhost-192-55这台主机上,yum安装puppet,然后在命令行执行
puppetd --server app-21-199.wenzizone.cn –test
由于我们是做的自动签名,并且在服务器上配置了puppet-client的配置文件,所以执行完过后puppet自动会以守护进程的方式启动
b) 配置svn更新主目录,及web页面项目的主目录,在我这个案例中的主目录是/var/www/html/www.51cto.com/zf,进入到这里使用svn co svn_source ./将初始的项目导入出来。这样就为了svn up命令执行做好了对应的环境。
通过简单的两步,就已经把puppet-client上的准备工作都完成了,是不是很简单。
那么下面就是perl-cgi部分了。
C、部署svn自助更新web脚本
这里可以将脚本部署在和puppet-master同一台主机上,当然也可以考虑分布式的,那样就需要调整这个脚本。现在先以同一台机器为例。
a)安装apache,配置cgi目录
因为我们的访问量不会很大,我直接用yum安装了。所以cgi目录使用的是默认的cgi-bin目录。
b)编写对应的脚本pjupdate.cgi
#! /bin/env perl use CGI; my $query = CGI->new(); #初始化cgi实例 my $file_name = $query->param('pjname'); #将url中pjname的值赋给$file_name变量 my $up_time = `date +%s`; #获得从1970-01-01 00:00:00 UTC到现在的秒数
my $dst_dir = "/etc/puppet/modules/svn/files/"; #目标文件的目录
my $success = open FH,">".$dst_dir.$file_name; #开的目标文件,即触发svn的文件
if(!$success) {
print "Content-type:text/html\n\n";
print "不能更新此项目,请联系管理员!"; #如果打开不成功进行提示,通常是权限问题,文件属主改成apache执行用户 } else { print FH"$up_time"; #更新文件内容,为了达到变更此文件md5值的效果 print "Content-type:text/html\n\n"; print "更新已经开始,请5~10分钟后查看页面"; } close(FH);
五、测试
使用方法:通过
http://test.wenzizone.cn/cgi-bin/pjupdate.cgi?pjname=hd_zf_up_file
触发更新。
可以看到,pjname的值实际上就是磁盘上我定义的那个文件的名字。这样只要使用不同的文件,再配置不同的puppet的pp文件,就能实现多个项目自助更新了。同样,因为puppet是分布式的c/s模式,所以在同一时间,也可以实现对多台服务器的更新。
到此,这个自助svn更新系统就介绍完毕了。有几点需要注意的:
- 请确认部署环境中有对应的主机名到ip地址的解析环境,本文所在环境已存在内部dns,所以全部使用主机名。
- 所有puppet主机时间要保持一致。
- 注意防火墙对puppet端口的限制,如果非必要,可以关闭防火墙。
心得总结
puppet确实是一个功能很强大的统一管理系统。在学习初期,对于文件模块之间的关系着实有些混乱,不过通过自己的摸索和尝试,在参考了网上的一些资料后,大概了解了puppet结构之间的联系,逐渐的实现了自己的一些想法,同时也为了给新学puppet的人理清各文件间关系吧。此文只为抛砖,因为这套系统目前来看还很简陋,还有很多需要完善的地方。如何更合理的利用puppet以及如何能更简化puppet的认为干预配置,值得我去思考并逐步去实现的。
#######################################################################
http://zhengdl126.iteye.com/blog/1541820
Puppet使用方法总结 http://dongxicheng.org/cluster-managemant/puppet/
如何使用 Example42 的 Puppet 模块 http://www.vpsee.com/2012/05/using-puppet-modules-from-example42/
puppet是一种Linux、Unix平台的集中配置管理系统,使用自有的puppet描述语言,可管理配置文件、用户、cron任务、软件包、系统服务等。puppet把这些系统实体称之为资源,puppet的设计目标是简化对这些资源的管理以及妥善处理资源间的依赖关系。
puppet官方网站:http://www.puppetlabs.com/
puppet中文wiki:http://puppet.chinaec2.com/
puppet中文博客:http://www.comeonsa.com
puppet采用C/S星状的结构,所有的客户端和一个或几个服务器交互。每个客户端周期的(默认半个小时)向服务器发送请求,获得其最新的配置信息,保证和该配置信息同步。每个puppet客户端每半小时(可以设置)连接一次服务器端, 下载最新的配置文件,并且严格按照配置文件来配置服务器. 配置完成以后,puppet客户端可以反馈给服务器端一个消息. 如果出错,也会给服务器端反馈一个消息.
执行配置
puppetd --server server.cbcv.net --test
查看执行频率
# puppet agent --configprint runinterval
10
显示执行过程
puppet agent --test --noop
=================================== 1 编译安装
请在所有操作前,先设置好你的hostname!ssl文件的生成是依赖这个参数的
在网上找了很多相关puppet的,有很多用yum安装,安装虽然成功了。但是有客户端相关过来请求,还是会有问题。最佳的还是源码安装。
一、下载地址:
puppet下载地址:
http://downloads.puppetlabs.com/puppet/puppet-2.7.13.tar.gz
facter下载地址:
http://downloads.puppetlabs.com/facter/facter-1.6.7.tar.gz
ruby下载地址:
http://ftp.ruby-lang.org/pub/ruby/1.8/ruby-1.8.7.tar.gz
二、环境准备:
1、时间必须一致:
crontab -e
*/2 * * * * /usr/sbin/ntpdate clock.nc.fukuoka-u.ac.jp >/dev/null 2>&1
2、首先gcc相关可用yum安装
yum install gcc-c++
yum install openssl*
3、服务器及客户端名字:
[root@server bin]# vim /etc/hosts
# Do not remove the following line, or various programs
# that require network functionality will fail.
#127.0.0.1 localhost.localdomain localhost
::1 localhost6.localdomain6 localhost6
192.168.1.231 server.cbcv.net server
192.168.1.232 client.cbcv.net client
[root@server bin]# vim /etc/sysconfig/network
NETWORKING=yes
NETWORKING_IPV6=no
HOSTNAME=server.cbcv.net
客户端为:HOSTNAME=client.cbcv.net
<客户端也是类似一样,略......>
三、安装应用软件
1、首先安装ruby
tar -zxvf ruby-1.8.7.tar.gz
cd ruby-1.8.7
./configure --prefix=/usr/local/ruby
make
make install
操作系统PATH路径:
vi /etc/profile
export PATH=/usr/local/ruby/bin:$PATH
查看ruby --version版本
2、安装facter
tar -zxvf facter-1.6.7.tar.gz
cd facter-1.6.7
ruby install.rb
3、安装puppet
tar -zxvf puppet-2.7.13.tar.gz
cd puppet-2.7.13/
ruby install.rb
# cp conf/auth.conf /etc/puppet/
# cp conf/namespaceauth.conf /etc/puppet/
# cp conf/redhat/puppet.conf /etc/puppet/
# cp conf/redhat/server.init /etc/init.d/puppetmaster
# chmod +x /etc/init.d/puppetmaster
# /etc/init.d/puppetmaster start
Starting puppetmaster: /bin/bash: /usr/sbin/puppetmasterd: No such file or directory
[FAILED]
# cp sbin/puppetmasterd /usr/sbin/
# chmod -R 777 /usr/sbin/puppetmasterd
# cp sbin/puppetmasterd /bin/puppetmasterd
# chmod -R 777 /bin/puppetmasterd
# /etc/init.d/puppetmaster start
Starting puppetmaster: /usr/bin/env: ruby: No such file or directory
[FAILED]
# ln -s /usr/local/ruby/bin/
erb filebucket pi puppetdoc rdoc ruby
facter irb puppet ralsh ri testrb
# ln -s /usr/local/ruby/bin/ruby /usr/bin/
# /etc/init.d/puppetmaster start
Starting puppetmaster: Could not prepare for execution: Got 6 failure(s) while initializing: change from absent to directory failed: Could not set 'directory on ensure: Could not find group puppet; change from absent to directory failed: Could not set 'directory on ensure: Could not find group puppet; change from absent to directory failed: Could not set 'directory on ensure: Could not find group puppet; change from absent to directory failed: Could not set 'directory on ensure: Could not find group puppet; change from absent to directory failed: Could not set 'directory on ensure: Could not find group puppet; change from absent to directory failed: Could not set 'directory on ensure: Could not find group puppet
[FAILED]
# useradd puppet
# /etc/init.d/puppetmaster start
Starting puppetmaster: [ OK ]
[root@server sbin]# pwd
/usr/local/src/puppet-2.7.9/sbin
cp -r * /usr/sbin/
[root@server manifests]# chkconfig --add puppetmaster
[root@server manifests]# chkconfig puppetmaster on
客户端其它安装和服务器安装相同,除了用cp conf/redhat/client.init /etc/init.d/puppet
tar -zxvf puppet-2.7.13.tar.gz
cd puppet-2.7.13/
ruby install.rb
# cp conf/auth.conf /etc/puppet/
# cp conf/namespaceauth.conf /etc/puppet/
# cp conf/redhat/puppet.conf /etc/puppet/
# cp conf/redhat/client.init /etc/init.d/puppet
# chmod +x /etc/init.d/puppet
# service puppet start
Starting puppet: /bin/bash: /usr/sbin/puppetd: No such file or directory
[FAILED]
# cp sbin/puppetd /usr/sbin/puppetd
# service puppet start
Starting puppet: /usr/bin/env: ruby: No such file or directory
[FAILED]
# chmod +x /usr/sbin/puppetd
# service puppet start
Starting puppet: /usr/bin/env: ruby: No such file or directory
[FAILED]
# ln -s /usr/local/ruby/bin/ruby /usr/bin/
# /etc/init.d/puppet start
Starting puppet: [ OK ]
=================================== 2 安装完毕后进行测试:
在服务器端执行:
#puppetca --list
应该是无
在客户端执行 #puppetd --server server.cbcv.net --test
再到服务器端执行:
#puppetca –s client.cbcv.net
clinet.cbcv.net (BF:5D:58:D0:F2:06:8C:FB:5C:AA:08:80:87:DC:92:20)
如果看到了客户端的证书请求,
针对客户端请求为
#puppetca -s client.cbcv.net
也可以用下面的命令对所有证书请求签名:
#puppetca -s -a
在主服务器上:
#vim /etc/puppet/manifests/site.pp
node default{
file { "/tmp/test.txt":
content=> "hello, Test";
}
}
再重启一下服务器service puppetmaster restart 和客户端service puppet restart
在客户端执行puppetd --server server.cbcv.net --test
看/tmp下面是不是有test.txt文件了
----------------
增加多个site.pp
可以先在site.pp中增加
import "test.pp"
然后再在里面执行需要操作的内容。
可用puppetd --server server.cbcv.net --test进行测试。
如果有报错:notice: Ignoring --listen on onetime run
notice: Skipping run of Puppet configuration client; administratively disabled; use 'puppet Puppet configuration client --enable' to re-enable.
那么需要在客户端执行puppet agent --enable即可。
puppet agent --disable为关闭。
记得重启puppetmaster和puppet
--------------------------- 多个node
在服务器端
#vim /etc/puppet/manifests/site.pp
node 'client'{
file { "/tmp/test.txt":
content=> "site1, Test";
}
}
node 'client2'{
file { "/tmp/test.txt":
content=> "site2, Test";
}
}
#service puppetmaster restart
客户端:
#service puppet restart
#puppetd --server server.cbcv.net --test
---------------
以下为参考内容,感觉非常不错:
默认时间vim /etc/puppet/puppet.con
runinterval =1800 ###默认是30分钟,可以修改此处的值,单位为秒
有的时间修改了这个没有用,是什么原因呢:
我也曾修改过多次,没效果,后在客户端的配置文件再加了一句server = server.cbcv.net
然后重启
在客户端修改即可!最好重启一下server puppet restart
puppet 如何全客户端自动签名
a.vim /etc/puppet/puppet.conf
[puppetmaster]
autosign=true #增加这两行
autosing=/etc/puppet/autosign.conf
#增加这两行添加
* 表示所有,或者添加域名,IP或者网段。举例:
b.再编辑 /etc/puppet/autosign.conf**.test.com192.168.0.1/24
错误总结<此错误是因为用了yum去安装。看到别人写的OK......>:
第一次认证的时候报下边的错误:
[root@client ~]# puppetd --server server.cbcv.net --test
err: Could not retrieve catalog from remote server: certificate verify failed
我做测试发现的原因有三种:
第一:是hostname没有设置好,在安装前一定要把hostname设置好,设置好之后尽量重启机器。实在不行就删了重新安装。
第二:时间不同步,时间不同步也会报认证失败的错误,可以用date设置时间,只要不是差得太多就没事。
第三:是ssl的问题,在你用的这个客户端puppet已经做过其他的机器的客户端的情况下,因为已经生成的有证书,可能会和现在的冲突,把/var/lib/puppet/ssl这个文件夹删掉之后就行了。
1.3配置c/s模式的puppet的实验环境
Puppet的的客户端和服务端是靠ssl链接的,在服务端有一个自签名的根证书,在安装软件的时候自动生成。每个客户端的证书要经过根证书签名才能和服务器连接。所以首先要在客户端执行下面的命令来请求服务器签名证书。
puppetd --server server.cbcv.net --test
------------------------------问题:
err: Could not retrieve catalog from remote server: SSL_connect returned=1 errno=0 state=SSLv3 read server certificate B: certificate verify failed. This is often because the time is out of sync on the server or client
这个:问题才是真正因为时间不同步导致的,出现这个问题:可以先删除/var/lib/puppet/ssl/目录下的文件之后,利用ntpdate time.nist.gov 命令进行时间同步后,再分别启动服务器和客户端,请注意,客户端和服务器都需要删除,重启服务后自动生成ssl目录下的文件。
一切正常后,会在/var/lib/puppet/ssl/certs/hostname.pem 文件
所以,请在所有操作前,先设置好你的hostname!ssl文件的生成是依赖这个参数的
=================================== 3 使用方法
4. 配置脚本编写
本节介绍puppet的配置脚本编写方法,主要是指puppet的manifest编写方法。puppet把需要管理的内容抽象成为资源,每种资源有不同的属性,因此puppet语言就是描述这些资源的属性以及资源之间关系的语言。
为了便于管理,puppet将资源模块化,即每个功能模块的manifest单独放在一个目录下。每个模块包含一个主要的manifest文件(init.pp,它是模块的入口,类似于C语言中的main函数),里面包含若干个class对该模块的资源进行封装,常见的资源有file,package,service等,每种资源由自己的属性,如file有属性name,owner,mode等。
本节主要介绍puppet中manifest的编写方法,将依次介绍资源属性,资源,节点管理,函数和模块的编写方法。
4.1 资源属性
资源属性有两种,一种是资源专属属性,另一种是资源共同属性,对于资源专属属性,将在下一节介绍;而资源共同属性是所有资源共有的属性,主要有:
before
用于控制不同对象(资源)的执行顺序关系,表示某个对象(资源)在另一个对象之后发生(require与之相反,它表示之前发生)。如:
file { “/var/nagios/configuration”:
source => “…”,
recurse => true,
before => Exec["nagios-rebuid"]
}
exec { “nagios-rebuild”:
command => “/usr/bin/make”,
cwd => “/var/nagios/configuration”
}
这段代码保证用make编译之前,所有代码都是最新的。也可以before多个资源,如:
before => [ File["/usr/local"], File["/usr/local/scripts"] ]
subscribe
检测某个资源,当它发生变化时,该资源会重新加载,如:
class nagios {
file { “/etc/nagios/nagios.conf”:
source => “puppet://server/module/nagios.conf”,
alias => nagconf # just to make things easier for me
}
service { nagios:
ensure => running,
subscribe => File[nagconf]
}
}
当检测到文件nagconf被修改时,服务nagios会相应的更新。需要注意的是,目前支持subscribe的资源只有exec,service和mount。
更多资料,参见:http://docs.puppetlabs.com/references/latest/metaparameter.html
4.2 资源
常用的资源主要有以下几个:
file:文件管理
package:软件包管理
service:系统服务管理
cron:配置定期任务
exec:运行shell命令
(1) file资源
更详细资料,可参见:http://puppet.wikidot.com/file
(2) package资源
更详细资料,可参见:http://puppet.wikidot.com/package
(3) service资源
更详细资料,可参见:http://puppet.wikidot.com/srv
(4) exec资源
更详细资料,可参见:http://puppet.wikidot.com/exec
(5) cron资源
更详细资料,可参见:http://puppet.wikidot.com/cron
4.3 节点管理
puppet如何区分不同的客户端,并且给不同的服务端分配manifest呢?puppet使用node资源做这件事情,node 后面跟客户端的主机名,例如:
node ‘ slave00 ‘ {
include ssh
}
node ‘ slave11 ‘ {
$networktype=”tele”
$nagioscheckport=”80,22,3306″
include apache, mysql, php
}
资源node中可使用变量,也可直接通过include把其他manifest包含进来。
更详细资料,可参见:http://docs.puppetlabs.com/references/latest/type.html
4.4 类和函数
类可以把多个相关的资源定义在一起,组成一个类。类可以继承,具体参见:http://docs.puppetlabs.com/guides/language_guide.html#resource-collections
函数(在puppet中称为“defination”)可以把多个资源包装成一个资源,或者把一个资源包装成一个模型,便于使用。例如,在debian里面管理一个apache虚拟机非常简单,把一个虚拟主机的配置文件放到/etc/sites-available/里面,然后做一个符号链接到/etc/sites-enabled目录。 你可以为你每个虚拟主机复制同样的配置代码,但是如果你使用下面的代码就会更好和更简单:
define virtual_host($docroot, $ip, $order = 500, $ensure = “enabled”) {
$file = “/etc/sites-available/$name.conf”
# The template fills in the docroot, ip, and name.
file { $file:
content => template(“virtual_host.erb”),
notify => Service[apache]
}
file { “/etc/sites-enabled/$order-$name.conf”:
ensure => $ensure ? {
enabled => $file,
disabled => absent
}
}
}
然后,你就可以使用这个定义来管理一个apache虚拟主机,如下面代码所示:
virtual_host { “reductivelabs.com”:
order => 100,
ip => “192.168.0.100″,
docroot => “/var/www/reductivelabs.com/htdocs”
}
4.5 模块
一个模块就是一个/etc/puppet/modules目录下面的一个目录和它的子目录,在puppet的主文件site.pp里面用import modulename可以插入模块。新版本的puppet可以自动插入/etc/puppet/modules目录下的模块。引入模块,可以结构化代码,便于分享和管理。例如关于apache的所有配置都写到apache模块下面。一个模块目录下面通常包括三个目录:files,manifests,templates。manifests 里面必须要包括一个init.pp的文件,这是该模块的初始(入口)文件,导入一个模块的时候,会从init.pp开始执行。可以把所有的代码都写到init.pp里面,也可以分成多个pp文件,init 再去包含其他文件。files目录是该模块的文件发布目录,puppet提供一个文件分发机制,类似rsync的模块。templates 目录包含erb模型文件,这个和file资源的template属性有关。
puppet安装好以后,modules目录是没有的,自己建立一个就行,然后在里面可以新增加你的模块。
5. 编程实例
5.1 Hello World
本节介绍了一个非常简单的编程实例:一个slave从master中获取其manifest,该maniftest要求slave依次做以下工作:安装gcc,创建文件夹/home/dxc/test,下载文件hello.c程序,编译hello.c。
(1) 代码结构组织
Master上代码的目录结构如下:
|– auth.conf
|– fileserver.conf #puppet文件服务器配置文件
|– manifests #puppet主文件所在目录
| |– modules.pp #puppet各个模块汇总
| |– nodes #各个slave要处理的模块
| | `– execHello.pp #hello模块对应由那些slave处理
| `– site.pp #puppet主文件(入口文件)
|– modules #puppet的各个模块所在文件
| `– hello #hello模块
| |– files #该模块对应的文件资源,可能是要发送给slave的配置文件等
| | `– hello.c
| `– manifests #模块的manifest文件
| `– init.pp #模块入口文件
`– ssl #puppet的证书文件目录
(2) 程序执行流程
代码调用顺序是:
Slave发起连接请求 à site.pp à nodes àmodules à init.pp
首先,slave向发起master连接请求,进行证书验证;
接着,证书验证通过后,master会直接找到入口文件manifests目录下的site.pp文件,该文件可能包含一些全局变量,参数缺省值(当各个模块没有设置这些参数时,它们的缺省值)以及其它pp文件的调用(在该例子中,会调用modules.pp和nodes下的各个pp文件);
然后,master通过nodes下的各个pp文件定位到该slave要执行的模块(init.pp是各个模块的入口),汇总这些模块代码返回给slave;
最后,slave根据master发过来的manifest,配置信息。
(3) 代码解释
直接在此处下载代码。
5.2 一个更复杂的实例
本节介绍了一个更为复杂的某个公司正在使用实例,puppet代码布局与上一个实例一致,只不过该实例涉及到更多模块,更复杂的依赖管理。代码具体内容本节就不解释了,具体参见代码。
6. 可能遇到的问题
Q: puppet的证书机制
A: puppet证书问题是初学者最容易遇到的问题,这里讲一下怎么处理。puppet服务器端在安装或者首次启动的时候,会自动生产一个根证书和服务器证书,证书和主机名相关,因此如果证书生成后友改了主机名,那就会出问题。 puppet客户端在首次启动的时候,也会自动生成证书;但是这个证书需要得到puppet服务器端的签名才行,因此;puppet客户端第一次连接服务器的时候,会发送一个证书请求;服务器端需要对这个证书进行签名。puppet客户端在下次连接服务器的时候就会下载签名好的证书。
Q:Ubuntu下面的证书出错,怎么解决?
A:本方法是提供给初学者的测试环境,生成环境不建议这么做。首先在puppetmaster(服务器端)删除/var/lib/puppet/ssl目录;然后启动puppetmasterd;然后在客户端也删除/var/lib/puppet/ssl目录。把puppetmaster机器的主机名和对应的ip地址写入客户端机器的/etc/hosts。
然后执行:puppetd –test –server server.example.com. 把server.example.com替
换成你自己的服务器主机名。 执行这个命令,会有提示信息,不用理会。
然后登录到puppetmaster服务器机器,执行puppetca –list 命令,看看是否有客户端的证书请求;如果没有,请检查前面的步骤是执行正确,以及网络连接是否正常。 如果puppetca –list 能看到请求,那么执行puppetca -s -a 命令;对所有的证书请求签名。最后回到puppet客户端机器,执行
puppetd –test –server server.example.com.
就能建立连接了,如果你的site.pp写好了.就可以测试puppet了。
补充:如果客户端和服务器端的时间不一致也会导致证书认证失败,因此出现证书问题的时候需要检查两台机器的时间是否一致,如果不一致用date命令或者ntpdate命令让两台机器的时间一致。
Q:出现错误[Puppet Users] err: Could not retrieve catalog; skipping run
A:可能是由于安装了两个版本的ruby或者facter的原因,解决方案见:
https://projects.puppetlabs.com/issues/5279
7. 总结
随着服务器集群规模越来越大,自动化配置和部署这些服务器能够使管理变得非常容易并大大减小管理部署成本,因而得到IT公司的高度重视。
本文档介绍了puppet,一种新型的软件自动化配置和部署工具。本文主要内容涉及puppet的架构,安装和使用方法,并给出了两个使用实例。
在大规模的生成环境中,如果只有一台puppetmaster会忙不过来的,因为puppet是用ruby写的,ruby是解析型语言,每个客户端来访问,都要解析一次,当客户端多了就忙不过来,所以需要扩展成一个服务器组。puppetmaster可以看作一个web服务器,实际上也是由ruby提供的web服务器模块来做的。因此可以利用web代理软件来配合puppetmaster做集群设置,具体参见:http://puppet.wikidot.com/puppetnginx 。
===============================puppet自动认证
首先我们先来看一个问题,新服务器可以通过kickstart自动安装完,并且自动安装完puppet相关包,安装完后客户端会请求证书,然后服务器会给客户端颁发证书,如果手动颁发很麻烦,如下配置可以让服务器自动验证。
前提是配置好hosts:
Master 192-168-0-130.APP.com
Client 192-168-0-131.APP.com
在服务器端的puppet.conf配置文件里面[main]下方加上autosign = true,重启puppetmaster服务即可!
这样在客户端执行puppetd --server=192-168-0-130.APP.com --test 服务器端会自动认证!
==============================重新生成证书
很多时候由于更换主机名,我们需要重新配置认证:
(1)、首先在客户端删除 rm -rf /var/lib/puppet/ssl/文件夹
(2)、然后在服务器端删除客户端的证书:puppetca --clean 192-168-0-131.APP.com 【 192-168-0-131.APP.com 客户端的主机名】
(3)、然后再在客户端执行puppetd --server=192-168-0-130.APP.com --test 即可!
===================================================
http://book.douban.com/reading/18182671/
http://blog.sina.com.cn/s/blog_61c07ac50101addq.html
大家给了我很多的建议,现在我在把我如何的对监控系统做版本控制与自动化部署来给大家描述一下,希望对大家有益。
在描述之前,先把流程图给大家,希望能使大家清楚流程:
下面是是svn与puppet部分的详细说明
- rpm -Uvh http://download.fedora.redhat.com/pub/epel/5/i386/epel-release-5-4.noarch.rpm
- wget http://dl.fedoraproject.org/pub/epel/5/x86_64/epel-release-5-4.noarch.rpm
- rpm -ivh epel-release-5-4.noarch.rpm
- yum -y install puppet-server openssl*
(2)开启puppet服务端的服务
- service puppetmaster start
(3)添加到开机启动
- chkconfig --level 345 puppet on
- chkconfig --level 345 puppetmaster on
(4)在hosts里添加包含本身以及需要自动化的客户端机器主机名与ip地址
(5)接下来需要去客户端安装puppet、启动服务与进行认证了
2、在客户端
- yum -y install puppet openssl*
- service puppet start
- chkconfig --level 345 puppet on
然后在与服务端进行认证
- puppetd --server master --test
3、接下来在服务端进行允许认证
- puppetca -s -a
这样就完成了认证,之后就可以在puppet的client里进行获取服务端的配置,并自动的在本机更新了。
下面是我的配置,提供给大家参考(我已经贵州的puppet为例)
贵州的puppet结构为:
贵州备用为puppetmaster服务端
贵州web、贵州引擎、贵州引擎、贵州备用为客户端(主要贵州备用既为服务端与客户端是没有问题)
先看一下我的puppet服务端贵州备用的文件结构
- [root@beiyong /]# tree /etc/puppet/
- /etc/puppet/
- |-- auth.conf
- |-- fileserver.conf #puppet文件服务器配置文件
- |-- manifests #puppet主文件所在目录
- | |-- guizhou_beiyong.pp #该模块对应的文件资源,可能是要发送给slave的配置文件等
- | |-- guizhou_jiaohuan.pp
- | |-- guizhou_web.pp
- | |-- guizhou_yinqing.pp
- | `-- site.pp #puppet主文件(入口文件)
- `-- puppet.conf
- 1 directory, 8 files
客户端连接的顺序:site.pp=》*.pp
比如贵州web的接收顺序为:site.pp=》guizhou_web.pp
首先,slave向发起master连接请求,进行证书验证;
接着,证书验证通过后,master会直接找到入口文件manifests目录下的site.pp文件,该文件可能包含一些全局变量,参数缺省值(当各个模块没有设置这些参数时,它们的缺省值)以及其它pp文件的调用(在该例子中,会调用manifests下的各个pp文件);
然后,master通过manifests下的各个pp文件定位到该slave要执行的模块(site.pp是各个模块的入口),汇总这些模块代码返回给slave;
最后,slave根据master发过来的manifest,配置信息。
注意:在配置之前一定要求的服务端与客户端的时间一致,并且hosts里都加入了对方的ip与主机名,并且能互相ping通,最好在改好hosts文件后重启服务器,同时selinux与iptables关闭。
4、先看一下我fileserver的设置
- [root@beiyong /]# cat /etc/puppet/fileserver.conf
- # This file consists of arbitrarily named sections/modules
- # defining where files are served from and to whom
- # Define a section 'files'
- # Adapt the allow/deny settings to your needs. Order
- # for allow/deny does not matter, allow always takes precedence
- # over deny
- # [files]
- # path /var/lib/puppet/files
- # allow *.example.com
- # deny *.evil.example.com
- # allow 192.168.0.0/24
- [puppet]
- path /usr/local/monitor/shell
- allow 172.16.6.0/24
这个path就是puppet master的配置文件里从哪里获得需要给客户端传输程序的地址,同时也是svn的hook里post-commit更新的地址。
allow后面的网段是我服务器网卡的ip段,也就是需要我这个网段的ip能从这个path里或者程序。
5、贵州web的配置
- [root@beiyong /]# cat /etc/puppet/manifests/guizhou_web.pp
- node web {
- file { "/usr/local/monitor/shell/GuiZhou_alter80.sh":
- source=>"puppet:///puppet/GuiZhou_web/GuiZhou_web_alter80.sh",
- mode=>755,
- }
- file { "/usr/local/monitor/shell/GuiZhou_alter90.sh":
- source=>"puppet:///puppet/GuiZhou_web/GuiZhou_web_alter90.sh",
- mode=>755,
- }
- file { "/usr/local/monitor/shell/GuiZhou_web_check.sh":
- source=>"puppet:///puppet/GuiZhou_web/GuiZhou_web_check.sh",
- mode=>755,
- }
- file { "/usr/local/monitor/shell/web_tomcat.sh":
- source=>"puppet:///puppet/GuiZhou_web/web_tomcat.sh",
- mode=>755,
- owner=>"lbs",
- group=>"lbs",
- }
- file { "/usr/local/monitor/shell/web_yz_tomcat.sh":
- source=>"puppet:///puppet/GuiZhou_web/web_yz_tomcat.sh",
- mode=>755,
- owner=>"lbs",
- group=>"lbs",
- }
- cron { GuiZhou_web_alert80_check:
- command=>"/usr/local/monitor/shell/GuiZhou_web_alter80.sh",
- hour=>'*/6',
- minute=>0,
- }
- cron { GuiZhou_web_alert90_check:
- command=>"/usr/local/monitor/shell/GuiZhou_web_alter90.sh",
- hour=>'*/1',
- minute=>0,
- }
- cron { GuiZhou_web_check:
- command=>"/usr/local/monitor/shell/GuiZhou_web_check.sh",
- minute=>'*/3',
- }
- cron { GuiZhou_web_sendmail_restart:
- command=>"/etc/init.d/sendmail restart",
- hour=>'23',
- minute=>'00',
- }
- }
6、贵州交换的配置
- [root@beiyong /]# cat /etc/puppet/manifests/guizhou_jiaohuan.pp
- node jiaohuan {
- file { "/usr/local/monitor/shell/GuiZhou_jiaohuan_alter80.sh":
- source=>"puppet:///puppet/GuiZhou_jiaohuan/GuiZhou_jiaohuan_alter80.sh",
- mode=>755,
- }
- file { "/usr/local/monitor/shell/GuiZhou_jiaohuan_alter90.sh":
- source=>"puppet:///puppet/GuiZhou_jiaohuan/GuiZhou_jiaohuan_alter90.sh",
- mode=>755,
- }
- file { "/usr/local/monitor/shell/GuiZhou_jiaohuan_check.sh":
- source=>"puppet:///puppet/GuiZhou_jiaohuan/GuiZhou_jiaohuan_check.sh",
- mode=>755,
- }
- file { "/usr/local/monitor/shell/GuiZhou_jiaohuan_ping.sh":
- source=>"puppet:///puppet/GuiZhou_jiaohuan/GuiZhou_jiaohuan_ping.sh",
- mode=>755,
- }
- cron { GuiZhou_jiaohuan_alert80_check:
- command=>"/usr/local/monitor/shell/GuiZhou_jiaohuan_alter80.sh",
- hour=>'*/6',
- minute=>0,
- }
- cron { GuiZhou_jiaohuan_alert90_check:
- command=>"/usr/local/monitor/shell/GuiZhou_jiaohuan_alter90.sh",
- hour=>'*/1',
- minute=>0,
- }
- cron { GuiZhou_jiaohuan_check:
- command=>"/usr/local/monitor/shell/GuiZhou_jiaohuan_check.sh",
- minute=>'*/3',
- }
- cron { GuiZhou_jiaohuan_ping:
- command=>"/usr/local/monitor/shell/GuiZhou_jiaohuan_ping.sh",
- minute=>'*/15',
- }
- cron { GuiZhou_jiaohuan_sendmail_restart:
- command=>"/etc/init.d/sendmail restart",
- hour=>'23',
- minute=>'00',
- }
- }
7、贵州引擎的配置
- [root@beiyong /]# cat /etc/puppet/manifests/guizhou_yinqing.pp
- node savecenter {
- file { "/usr/local/monitor/shell/GuiZhou_yinqing_alter80.sh":
- source=>"puppet:///puppet/GuiZhou_yinqing/GuiZhou_yinqing_alter80.sh",
- mode=>755,
- }
- file { "/usr/local/monitor/shell/GuiZhou_yinqing_alter90.sh":
- source=>"puppet:///puppet/GuiZhou_yinqing/GuiZhou_yinqing_alter90.sh",
- mode=>755,
- }
- file { "/usr/local/monitor/shell/GuiZhou_yinqing_check.sh":
- source=>"puppet:///puppet/GuiZhou_yinqing/GuiZhou_yinqing_check.sh",
- mode=>755,
- owner=>lbs,
- group=>lbs,
- }
- cron { GuiZhou_yinqing_alert80_check:
- command=>"/usr/local/monitor/shell/GuiZhou_yinqing_alter80.sh",
- hour=>'*/6',
- minute=>0,
- }
- cron { GuiZhou_yinqing_alert90_check:
- command=>"/usr/local/monitor/shell/GuiZhou_yinqing_alter90.sh",
- hour=>'*/1',
- minute=>0,
- }
- cron { GuiZhou_yinqing_check:
- command=>"/usr/local/monitor/shell/GuiZhou_yinqing_check.sh",
- user=>lbs,
- minute=>'*/3',
- }
- cron { GuiZhou_yinqing_sendmail_restart:
- command=>"/etc/init.d/sendmail restart",
- hour=>'23',
- minute=>'00',
- }
- }
8、贵州备用的配置
- [root@beiyong /]# cat /etc/puppet/manifests/guizhou_beiyong.pp
- node beiyong {
- file { "/usr/local/monitor/shell/GuiZhou_beiyong_alter80.sh":
- source=>"puppet:///puppet/GuiZhou_beiyong/GuiZhou_beiyong_alter80.sh",
- mode=>755,
- }
- file { "/usr/local/monitor/shell/GuiZhou_beiyong_alter90.sh":
- source=>"puppet:///puppet/GuiZhou_beiyong/GuiZhou_beiyong_alter90.sh",
- mode=>755,
- }
- file { "/usr/local/monitor/shell/GuiZhou_beiyong_check.sh":
- source=>"puppet:///puppet/GuiZhou_beiyong/GuiZhou_beiyong_check.sh",
- mode=>755,
- }
- cron { GuiZhou_beiyong_alert80_check:
- command=>"/usr/local/monitor/shell/GuiZhou_beiyong_alter80.sh",
- hour=>'*/6',
- minute=>0,
- }
- cron { GuiZhou_beiyong_alert90_check:
- command=>"/usr/local/monitor/shell/GuiZhou_beiyong_alter90.sh",
- hour=>'*/1',
- minute=>0,
- }
- cron { GuiZhou_beiyong_check:
- command=>"/usr/local/monitor/shell/GuiZhou_beiyong_check.sh",
- minute=>'*/3',
- }
- cron { GuiZhou_beiyong_sendmail_restart:
- command=>"/etc/init.d/sendmail restart",
- hour=>'23',
- minute=>'00',
- }
- }
9、在查看一个site.pp的配置
- [root@beiyong /]# cat /etc/puppet/manifests/site.pp
- import "guizhou_web.pp"
- import "guizhou_jiaohuan.pp"
- import "guizhou_yinqing.pp"
- import "guizhou_beiyong.pp"
现在服务端的配置已经展现完成,在去客户端查看一下配置是否生效
1、贵州web
- [root@web puppet]# crontab -l
- # HEADER: This file was autogenerated at Fri Oct 12 15:59:14 +0800 2012 by puppet.
- # HEADER: While it can still be managed manually, it is definitely not recommended.
- # HEADER: Note particularly that the comments starting with 'Puppet Name' should
- # HEADER: not be deleted, as doing so could cause duplicate cron jobs.
- # Puppet Name: GuiZhou_web_sendmail_restart
- 0 23 * * * /etc/init.d/sendmail restart
- # Puppet Name: GuiZhou_web_alert90_check
- 0 */1 * * * /usr/local/monitor/shell/GuiZhou_web_alter90.sh
- # Puppet Name: GuiZhou_web_alert80_check
- #0 */6 * * * /usr/local/monitor/shell/GuiZhou_web_alter80.sh
- # Puppet Name: GuiZhou_web_check
- */3 * * * * /usr/local/monitor/shell/GuiZhou_web_check.sh
2、贵州交换
- [root@jiaohuan ~]# crontab -l
- # HEADER: This file was autogenerated at Fri Oct 12 16:03:24 +0800 2012 by puppet.
- # HEADER: While it can still be managed manually, it is definitely not recommended.
- # HEADER: Note particularly that the comments starting with 'Puppet Name' should
- # HEADER: not be deleted, as doing so could cause duplicate cron jobs.
- # Puppet Name: GuiZhou_jiaohuan_sendmail_restart
- 0 23 * * * /etc/init.d/sendmail restart
- # Puppet Name: GuiZhou_jiaohuan_alert80_check
- 0 */6 * * * /usr/local/monitor/shell/GuiZhou_jiaohuan_alter80.sh
- # Puppet Name: GuiZhou_jiaohuan_alert90_check
- 0 */1 * * * /usr/local/monitor/shell/GuiZhou_jiaohuan_alter90.sh
- # Puppet Name: GuiZhou_jiaohuan_ping
- #*/15 * * * * /usr/local/monitor/shell/GuiZhou_jiaohuan_ping.sh
- # Puppet Name: GuiZhou_jiaohuan_check
- */3 * * * * /usr/local/monitor/shell/GuiZhou_jiaohuan_check.sh
3、贵州引擎
由于贵州引擎有root账号与lbs用户的配置,所以我们先查看root用户的
- [root@savecenter ~]# crontab -l
- # HEADER: This file was autogenerated at Fri Oct 12 16:16:41 +0800 2012 by puppet.
- # HEADER: While it can still be managed manually, it is definitely not recommended.
- # HEADER: Note particularly that the comments starting with 'Puppet Name' should
- # HEADER: not be deleted, as doing so could cause duplicate cron jobs.
- # Puppet Name: GuiZhou_yinqing_sendmail_restart
- 0 23 * * * /etc/init.d/sendmail restart
- # Puppet Name: GuiZhou_yinqing_alert80_check
- 0 */6 * * * /usr/local/monitor/shell/GuiZhou_yinqing_alter80.sh
- # Puppet Name: GuiZhou_yinqing_alert90_check
- 0 */1 * * * /usr/local/monitor/shell/GuiZhou_yinqing_alter90.sh
在查看lbs用户的
- [root@savecenter ~]# crontab -u lbs -l
- # HEADER: This file was autogenerated at Fri Oct 12 16:16:41 +0800 2012 by puppet.
- # HEADER: While it can still be managed manually, it is definitely not recommended.
- # HEADER: Note particularly that the comments starting with 'Puppet Name' should
- # HEADER: not be deleted, as doing so could cause duplicate cron jobs.
- #MIN HOUR DAY MONTH DAYOFWEEK COMMAND
- # Puppet Name: GuiZhou_yinqing_check
- */3 * * * * /usr/local/monitor/shell/GuiZhou_yinqing_check.sh
4、贵州备用
- [root@beiyong /]# crontab -l
- # HEADER: This file was autogenerated at Fri Oct 12 16:03:37 +0800 2012 by puppet.
- # HEADER: While it can still be managed manually, it is definitely not recommended.
- # HEADER: Note particularly that the comments starting with 'Puppet Name' should
- # HEADER: not be deleted, as doing so could cause duplicate cron jobs.
- # Puppet Name: GuiZhou_beiyong_check
- */3 * * * * /usr/local/monitor/shell/GuiZhou_beiyong_check.sh
- # Puppet Name: GuiZhou_beiyong_sendmail_restart
- 0 23 * * * /etc/init.d/sendmail restart
- # Puppet Name: GuiZhou_beiyong_alert90_check
- 0 */1 * * * /usr/local/monitor/shell/GuiZhou_beiyong_alter90.sh
- # Puppet Name: GuiZhou_beiyong_alert80_check
- 0 */6 * * * /usr/local/monitor/shell/GuiZhou_beiyong_alter80.sh
现在puppet的配置已经完成,当前的配置已经在我们的生产服务器里部署。
如果大家想要在客户端的puppe设置一个时间来连接puppetmaster获取文件?
可以再客户端里的/etc/puppet/puppet.conf文件里加上:
- runinterval =1800
puppet默认没有使用版本控制。可以在puppet.conf文件中添加一下一行: config_version = /usr/local/bin/return_version
其中“/usr/local/bin/return_version” 是我自定义的脚本:
[ccine_perl height=”100%” width=”99%”]#!/bin/bash
date +%Y%m%d%H[/ccine_perl]
so 简单 ^.^
puppet的这个版本号是用于与client端通信的信息,可以使用tagmail或者puppet的report功能,在基于webUI的dashboard或者foreman方便查阅自动化情况,通过时间判断是一个不错的办法。
svn的版本控制主要是对puppet部署的配置文件的控制,对于传送文件,使用exec执行客户端命令等操作不能进行回滚操作,需要自定义回滚方法(svn只负责svn服务器本地版本库内的文件系统)
1 安装svn
我使用yum安装:
#yum install subversion mod_dav_svn mod_auth_mysql –y
2 确认是否已安装一下安装包:
openssl-XXX
openssl-devel-XXX
mod_ssl-XXX
mod_auth_mysql-XXX
subversion-XXX
mod_dav_svn-XXX
3 确认模块:
在/etc/httpd/modules(根据你的apache安装目录)
mod_authz_svn.so
mod_dav_svn.so
mod_auth_mysql.so
4 建立并创建svn版本库
#mkdir –p /opt/svn/puppet
#svnadmin create /opt/svn/puppet
5 修改SVN配置文件
#vi /opt/svn/puppet/conf/svnserve.conf(操作权限文件指定)
[ccine_perl height=”100%” width=”99%”][general]
auth-access = write
password-db = passwd
authz-db = authz
realm = puppet[/ccine_perl]
#vi /opt/svn/puppet/conf/password(容许访问SVN的用户及密码)
[ccine_perl height=”100%” width=”99%”][users]
puppet = testpassword[/ccine_perl]
#vi /opt/svn/puppet/conf/authz(用户对某目录及自动目录的访问权限,下面表示admin组对svn所有目录都有读写权限)
[ccine_perl height=”100%” width=”99%”][groups]
admin = puppet
[/]
@admin = rw[/ccine_perl]
6 启动svn
#svnserve -d –r /opt/svn/
7向版本库提交资源,我设置的路径是puppet模块的主目录(原因见下面的说明,默认为/etc/puppet,我指定到了其他路径,puppet.conf中指定)
#svn import –m “test” /usr/share/svn/modules file:///opt/svn/puppet
8 svn还是需要系统学习的,这里只是一个开端,,为了让大家尽快懂得svn,下面介绍一些会用到的命令包括:
svn add * (将新修改的配置以及新添加的文件纳入版本控制,这是在修改量大的情况下,最简单快速的办法)
svn commit -m “一些更新信息” (将新修改的配置提交到版本库)
svn co file:///home/okooo/apps/svn/puppet tmp(将版本库的内容拷贝一个副本到这次操作的目录下的tmp目录-这个都可以定义,默认就是版本库的名字,本例中是puppet)
svn up (下载一份完整的版本库内容到操作的目录下)
svn cleanup (有些时候在别人修改时候文件被锁定等原因,运行这个命令可以解除锁定)
svn del manifests/node/java.pp(将版本库的某些内容删除,这里是删除java.pp,然后svn commit就会成功删除)
svn diff manifests/node/java.pp (将修改后的java.pp文件和版本库的同名文件对比不同的内容)
svn log (查看更新内容的日志,这个log显示出来的就是上面执行“svn commit -m” 后的内容)
….
因为我们不涉及开发维护,所以svn不需要太熟,但是还是建议掌握所有内容
SVN的hooks
钩子的功能其实我也迷糊了很久,我的理解就是在版本库出现修改时被触发的自定义脚本,这样可以确定很多属性:比如Pre-Commit钩子的作用是代码提交前是否有写messages,是否有tab,是否有不允许上传的文件,是否有超过限制大小的文件等等,这样可以控制一些不合适的提交。
以下是一个Pre-Commit钩子,用于检查语法错误:
检查puppet的.pp配置文件是否有问题,也可以执行:
puppet -v 你的主要配置文件site.pp [ccine_perl height=”100%” width=”99%”]#!/bin/sh # SVN pre-commit hook to check Puppet syntax for .pp files # Modified from http://mail.madstop.com/pipermail/puppet-users/2007-March/002034.html REPOS="$1" TXN="$2" tmpfile=`mktemp` export HOME=/ SVNLOOK=/usr/bin/svnlook $SVNLOOK changed -t "$TXN" "$REPOS" | awk '/^[^D].*\.pp$/ {print $2}' | while read line do $SVNLOOK cat -t "$TXN" "$REPOS" "$line" > $tmpfile if [ $? -ne 0 ] then echo "Warning: Failed to checkout $line" >&2 fi puppet --color=false --confdir=/etc/puppet --vardir=/var/lib/puppet --parseonly --ignoreimport $tmpfile >&2 if [ $? -ne 0 ] then echo "Puppet syntax error in $line." >&2 exit 2 fi done res=$? rm -f $tmpfile if [ $res -ne 0 ] then exit $res fi
[/ccine_perl]
http://www.w3ccollege.org/svn/the-use-of-svn-hook-to-automatically-export-web-application-deployment.html
应用场景:
开发团队3-5人,用svn做版本控制,测试环境和数据库在测试服务器上,一般情况下先在本地测试完成,然后传到服务器测试,这样显得有点麻烦,集中规定将代码上传到服务器进行测试,这里就涉及到一个应用自动部署的问题,有两种思路,一种服务器写一个crontab,编写一个shell脚本,实时监听服务器,将最新版本检出到web根目录;第二种思路,利用svn的钩子实现版本的实时导出。第一种方法比较简单,直接写一个导出版本的shell脚本即可,第二种方法其实使用起来更加便利。
首先简单介绍一下svn hooks,通常在创建svn版本库之后我们会在版本库的文件目录下找到一个叫做hooks的目录,这里存放的就是svn所谓的钩子了,他的主要用途在于在subversion执行一个操作时,会触发相应的钩子程序(前提当然是钩子存在),钩子程序就是一些shell脚本,执行相应的操作。
- ll hooks
如下图,列出的是一些钩子的模板案例,将后面的tmpl后缀名去掉,就变成了相应的钩子程序了。
post-commit
在提交完成,成功创建版本之后执行该钩子,提交已经完成,不可更改,因此本脚本的返回值被忽略。
post-lock
对文件进行加锁操作之后执行该脚本
post-revprop-change
在修改 revision 属性之后,执行该脚本。因为修改稿已经完成,不可更改,因此本脚本的返回值被忽略(不过实际上的实现似乎是该脚本的正确执行与否影响属性修改)
post-unlock
对文件进行解锁操作之后执行该脚本
pre-commit
在 Subversion transaction 完毕之后,在提交之前,执行该脚本
pre-lock
对文件进行加锁操作之前执行该脚本
pre-revprop-change
在修改 revision 属性之前,执行该脚本
pre-unlock
对文件进行解锁操作之前执行该脚本
start-commit
在客户端还没有向服务器提交数据之前,即还没有建立 Subversion transaction(缩写为 txn) 之前,执行执行该脚本
具体到我们的应用场景,我们要实现一个同步的测试服务器,我们只需要在一个用户执行完毕一个commit提交操作之后,让钩子程序去自动更新测试服务器的文件即可
。通过这个思路,我们需要作的就是建立一个post-commit的钩子。
- #!/bin/sh
- cd /usr/local/www/coolphp
- SVN=/usr/local/bin/svn
- export LANG=en_US.UTF-8
- $SVN update –username kokko –password 111111 –no-auth-cache
注意相关权限的设置…
参考:
http://svnbook.red-bean.com/en/1.1/ch05s02.html
http://www.worldhello.net/doc/svn_hooks/svn_hooks.mm.htm