服务器:10.1.20.154 ~ 155,RHEL 5.4
puppet服务器端:10.1.20.154 test_1.com
puppet客户端:10.1.20.155 test_2.com
一、概况
Puppet基于C/S架构,服务器端保存着客户端的所有配置代码,称为manifest,客户端下载manifest后,根据其内容对本机进行配置,如软件的安装、文件的管理、用户的管理等。
Uinux/Linux里的软件、用户、文件以及crontab等,在puppet里统一称之为“资源”,每种资源都有其对应的属性,如文件资源的权限属性,一些资源的共有属性称为元属性。manifest里的代码主要由这些资源和资源的属性构成。
从puppet 2.6.0开始,puppet简化了可执行命令,使用puppet + subcommand的方式来完成所有的操作。如:puppetmasterd用puppet master替代,puppetd用puppet agent替代等等,这样一来,命令的作用非常明确,从字面意思就可以看出来。可使用命令puppet help查看详细用法。
这种变化也反应到了puppet配置文件puppet.conf中,如:关于master的配置被写入[master]配置段中,关于agent的配置被写入[agent]配置段中等等。
puppet配置文件目录默认是/etc/puppet,文件名为puppet.conf,文件中包含多个配置段,配置段中包含一系列缩进过的 setting = value行。
配置段包括:
[main]:始终生效,但是其中的设置可以被后面配置段中相同的设置覆盖掉
[agent]:对puppet agent生效
[master]:对puppet master和puppet cert生效
[user]:仅对puppet aply模式生效,一般可能用不到
生成默认配置文件:
puppet master --genconfig >puppet.conf
puppet agent --genconfig >puppet.conf
二、Puppet组件:
Puppet:主程序,依赖软件Ruby、Facter;
Facter:主机资料收集器,把收集到的主机资料发送给puppet master;
Dashboard: Puppet图形管理界面,可选组件,要求Ruby 1.8.7;
MCollective:Puppet调度器,可选组件,解决多个agent同时向master请求时造成的性能下降问题,需要中间件的支持,可选择rabbitmq或activemq。
三、安装:
Puppet版本:2.7.19,Facter版本:1.6.13,Ruby版本:1.9.3;
这里忍不住要说一下,最开始看官方网站,只说puppet dashboard要求ruby >1.8.6,后来等到我准备安装dashbaord时,仔细看了一下manual,才发现它要求ruby版本是1.8.7,而使用ruby 1.9.x会有问题,这也太他妈坑爹了。但我也懒得重新搞,所以放弃了dashboard。
ruby 1.8.7是08年放出的,到现在都4年了,生命周期即将终结,ruby开发团队已经停止对该版本的维护了。但很多ruby的周边软件要么是08年发布的,到现在没有更新过,要么是跟ruby 1.9.x有冲突。这方面的例子不单单只有dashboard和mongrel。我对ruby的印象非常的不好,每月的编程语言排行榜上,ruby基本上每次都是前十名垫底,这不是没有道理的。
根据puppet的README.md,ruby 1.8.5、1.8.7和1.9.2经过了puppet官方测试,其它版本要自行承担风险。但由于1.9.3修复了之前版本的很多漏洞,我还是决定使用ruby最新版本。
因为虚拟机不能连网,只能使用源码安装的方式,所有软件先下载到本地然后上传到服务器。
大致过程:修改主机名,时间同步,添加防火墙,添加puppet用户,安装依赖,安装puppet。
客户端与服务器端执行相同的操作。
时间同步:略,SSL认证时需要。
修改主机名及host表:略, Puppet证书需要。
注: Puppet证书使用的主机名必须是FQDN(完全合格域名/全称域名),即主机名+域名的格式。
用户名添加:useradd -M -s /sbin/nologin puppet
依赖安装: ruby、facter,ruby需要YAML库的支持。
yaml安装:
yaml是一种语言,而libyaml库是yaml的C语言实现。参考:http://zh.wikipedia.org/zh-cn/YAML和http://pyyaml.org/wiki/LibYAML
-
tar -xf yaml-0.1.4.tar.gz && cd yaml-0.1.4
-
./configure && make && make install
-
-
echo '/usr/local/yaml/lib' >/etc/ld.so.conf.d/libyaml.conf
-
ldconfig
注:configure时没有指定--prefix,因为如果指定,在安装完ruby,使用gem时,如gem -v或使用gem安装软件时会提示错误:
/usr/local/ruby-1.9/lib/ruby/1.9.1/yaml.rb:56:in `<top (required)>':
It seems your ruby installation is missing psych (for YAML output).
To eliminate this warning, please install libyaml and reinstall your ruby。
openssl安装:
-
tar -xf openssl-1.0.1c.tar.gz && cd openssl-1.0.1c
-
./config --prefix=/usr/local/openssl-1.0.1 -fPIC
-
make && make install
ruby安装:
-
tar -xf ruby-1.9.3-p286.tar.gz && cd ruby-*
-
./configure --prefix=/usr/local/ruby-1.9
-
make && make install
-
echo 'export PATH=$PATH:/usr/local/ruby-1.9/bin:/usr/local/ruby-1.9/sbin/' >>/etc/profile
-
source /etc/profile
facter安装:
-
tar –xf facter-1.6.13.tar.gz && cd facter-*
-
ruby install.rb
Could not load openssl Ruby library; cannot install
解决办法:进入ruby的源码目录下的ext/openssl,执行ruby extconf.rb命令。具体如下:
-
cd ruby-1.9.3-p286/ext/openssl
-
ruby extconf.rb --with-openssl-lib=/usr/local/openssl-1.0.1/lib/ --with-openssl-include=/usr/local/openssl-1.0.1/include/
-
make && make install
puppet开源版安装,可以选择官方网站下载,也可以到github下载,两个地址如下:
http://puppetlabs.com/misc/download-options/
https://github.com/puppetlabs/puppet
-
tar -xf puppet-2.7.19.tar.gz && cd puppet-*
-
ruby install.rb
-
cp conf/redhat/* /etc/puppet
四、服务器端配置:
添加防火墙,客户端默认使用 tcp 8140端口向服务器端请求文件:
iptables -A INPUT -p tcp --dport 8140 -j ACCEPT
生成配置文件:
puppet master --genconfig >/etc/puppet/puppet.conf
vim /etc/puppet/puppet.conf,修改如下行:
-
server = test_1.com
注释掉如下行:
-
ca_server =
-
pluginsource =
-
factsource =
-
reportserver =
-
report_server =
-
inventory_server =
-
archive_file_server =
测试启动:puppet master --no-daemonize --verbose
启动:puppet master
这里就不要生成system V脚本了,因为生产环境中一般会有nginx或apache放在前端处理客户端连接,然后由nginx或apache调用puppet master,puppet master不需要作为一个独立进程来运行。
五、客户端配置及申请证书:
生成配置文件:
puppet agent --genconfig >/etc/puppet/puppet.conf
vim /etc/puppet/puppet.conf,修改如下行:
-
server = test_1.com
注释掉如下行:
-
ca_server =
-
pluginsource =
-
factsource =
-
reportserver =
-
report_server =
-
inventory_server =
-
archive_file_server =
生成system V脚本:
-
cp /etc/puppet/client.init /etc/init.d/puppetclient
vim /etc/init.d/puppetclient,修改如下行:
-
PATH=/usr/bin:/sbin:/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin
-
puppetd=${PUPPETD-/usr/local/ruby-1.9/sbin/puppetd}
-
lockfile=${LOCKFILE-/var/lib/puppet/state/puppetdlock} //根据puppet.conf中的配置进行修改
-
pidfile=${PIDFILE-/var/lib/puppet/run/agent.pid} //根据puppet.conf中的配置进行修改
-
chmod 755 /etc/init.d/ puppetclient
-
chkconfig --add puppetclient
-
chkconfig puppetclient on
-
service puppetclient start
客户端申请证书:puppet agent --test,首次运行,可能有报错,不管。
服务器端批准证书:puppet cert -s test_2.com 或 puppetca -s -a //给所有请求进行签名
服务器端查看已批准证书:puppet cert-a -l,如果出现’+ ServerName’,说明指定Server已签名
六、测试
服务器端/etc/puppet/manifests目录下添加文件site.pp,内容如下:
-
node default {
-
file { 'test2':
-
name => '/tmp/test2.txt',
-
content => "hello,agent!\n"; }
-
}
客户端执行puppet agent --test,然后可以看到/tmp目录下创建出一个test1.txt的文件。
七、扩展puppet master的处理能力
puppet master默认使用ruby的webrick作为服务器,这个轻量级的服务器处理请求的能力有限,所以大多数的正式环境中会用apache或nginx替换它。apache或nginx作为web前端来处理SSL连接,这样后端可以起多个puppet master实例,做成一个master负载均衡集群。
也有人用Mongrel,但感觉ruby不怎么重视mongrel,对它的支持很不给力,1.1.5版本是08年放出来的,10年放出了一个1.2.0 pre2,此后就没什么消息了。mong 1.1.5与ruby 1.9.x不兼容,即使mongrel 1.2.0 pre2也不能很好的在ruby 1.9.x上工作。
passenger全称是Phusion Passenger,原本的名字叫mod_rails,是apache和nginx的一个扩展模块,目的是为了能够方便地在apache或nginx上部署rail或rack应用程序,如puppet就是一个标准的rack应用。Phusion Passenger官方网站有一个图片,很形象地说明了passenger的用途:

puppet master负载均衡集群是一个比较复杂的工程,这里仅调通nginx + passenger,不做集群。安装配置过程可以借签puppet官方wiki:http://docs.puppetlabs.com/guides/passenger.html,和http://projects.puppetlabs.com/projects/puppet/wiki/Using_Passenger。
在我的虚拟环境中,passenger、nginx和puppet master安装到同一台机器上:test_1.com。
安装rubygem:
gem是ruby的一个辅助工具,ruby的一些库和工具都是依靠gem来安装的,包括passenger、rake、rack等,都可以通过gem install的方式安装。其实,gem已经集成到了ruby 1.9.x中,不用再安装。
安装rack:
下载地址:http://rubygems.org/gems/rack
-
gem install rack-1.4.1.gem
安装passenger:
下载地址:https://www.phusionpassenger.com/download,在页面的最下方有一个栏目ALTERNATIVE DOWNLOADS,我选择了下载source tarball。
这里有两种安装方式,推荐的方式是passenger的交互式安装。
1)交互式安装:
tar -xf passenger-3.0.17.tar.gz && cd passenger-3.0.17 && bin/passenger-install-nginx-module
交互式安装需要联网,但非常的方便简单,需要哪些依赖,安装过程会有提示,包括nginx。也可以首先下载并解压nginx,在安装过程中指定源码目录即可。
2)把passenger编译进nginx:
虚拟机不能联网,我采用的是把passenger编译进nginx的方式。
下载并解压pcre,不要安装:
tar -xf pcre-8.31.tar.gz
下载并解压passenger:
tar -xf passenger-3.0.17.tar.gz -C /usr/local
下载并安装nginx,把passenger作为模块编译进nginx:
-
tar -xf nginx-1.2.5.tar.gz && cd nginx-1.2.5
-
./configure --prefix=/usr/local/nginx --with-pcre=/root/packages/pcre-8.31 --with-http_ssl_module --with-http_gzip_static_module --add-module='/usr/local/passenger-3.0.17/ext/nginx'
-
make && make install
注:上述的--with-pcre和--with-openssl都是源码解压后的目录,而不是安装后的目录!
vim /usr/local/nginx/conf/nginx.conf,修改HTTP模块配置,添加如下行:
-
passenger_root /usr/local/passenger-3.0.17;
-
#passenger_max_pool_size 15; //属于调优项,根据实际进行调整
更加详细的配置,参考passenger官方文档:http://www.modrails.com/documentation/Users%20guide%20Nginx.html。
配置rack:
-
mkdir -p /etc/puppet/rack/public
-
cp /root/packages/puppet-2.7.19/ext/rack/files/config.ru /etc/puppet/rack/
-
chown -R puppet:puppet /etc/puppet/rack //官方wiki特地强调了config.ru的属主问题
vim /usr/local/nginx/conf/nginx.conf,添加rack server(即puppet)配置:
-
server {
-
listen 8140 ssl;
-
server_name test_1.com;
-
-
passenger_enabled on;
-
passenger_set_cgi_param HTTP_X_CLIENT_DN $ssl_client_s_dn;
-
passenger_set_cgi_param HTTP_X_CLIENT_VERIFY $ssl_client_verify;
-
-
-
root /etc/puppet/rack/public;
-
access_log logs/puppet_access.log;
-
error_log logs/puppet_error.log;
-
-
ssl_certificate /etc/puppet/ssl/certs/test_1.com.pem;
-
ssl_certificate_key /etc/puppet/ssl/private_keys/test_1.com.pem;
-
ssl_crl /etc/puppet/ssl/ca/ca_crl.pem;
-
ssl_client_certificate /etc/puppet/ssl/certs/ca.pem;
-
ssl_prefer_server_ciphers on;
-
ssl_verify_client optional;
-
ssl_session_cache shared:SSL:128m;
-
ssl_session_timeout 5m;
-
}
开机启动nginx,网上找到了一个脚本:
-
#!/bin/bash
-
# nginx Startup script for the Nginx HTTP Server
-
# it is v.0.0.2 version.
-
# chkconfig: - 85 15
-
# description: Nginx is a high-performance web and proxy server.
-
# It has a lot of features, but it's not for everyone.
-
# processname: nginx
-
# pidfile: /var/run/nginx.pid
-
# config: /usr/local/nginx/conf/nginx.conf
-
nginxd=/usr/local/nginx/sbin/nginx
-
nginx_config=/usr/local/nginx/conf/nginx.conf
-
nginx_pid=/usr/local/nginx/logs/nginx.pid
-
RETVAL=0
-
prog="nginx"
-
# Source function library.
-
. /etc/rc.d/init.d/functions
-
# Source networking configuration.
-
. /etc/sysconfig/network
-
# Check that networking is up.
-
[ ${NETWORKING} = "no" ] && exit 0
-
[ -x $nginxd ] || exit 0
-
# Start nginx daemons functions.
-
start() {
-
if [ -e $nginx_pid ];then
-
echo "nginx already running...."
-
exit 1
-
fi
-
echo -n $"Starting $prog: "
-
daemon $nginxd -c ${nginx_config}
-
RETVAL=$?
-
echo
-
[ $RETVAL = 0 ] && touch /var/lock/subsys/nginx
-
return $RETVAL
-
}
-
# Stop nginx daemons functions.
-
stop() {
-
echo -n $"Stopping $prog: "
-
killproc $nginxd
-
RETVAL=$?
-
echo
-
[ $RETVAL = 0 ] && rm -f $nginx_pid
-
}
-
-
reload() {
-
echo -n $"Reloading $prog: "
-
#kill -HUP `cat ${nginx_pid}`
-
killproc $nginxd -HUP
-
RETVAL=$?
-
echo
-
}
-
# See how we were called.
-
case "$1" in
-
start)
-
start
-
;;
-
stop)
-
stop
-
;;
-
reload)
-
reload
-
;;
-
restart)
-
stop
-
start
-
;;
-
status)
-
status $prog
-
RETVAL=$?
-
;;
-
*)
-
echo $"Usage: $prog {start|stop|restart|reload|status|help}"
-
exit 1
-
esac
-
exit $RETVAL
-
chmod 755 /etc/init.d/nginx
-
chkconfig --add nginx
-
chconfig nginx on
添加nginx用户:
-
useradd -M -s /sbin/nologin nginx
测试配置文件:
-
/usr/local/nginx/sbin/nginx -t -c /usr/local/nginx/conf/nginx.conf
启动:
service nginx start
客户端运行如下命令进行测试:
-
puppet agent --onetime --no-daemonize --verbose --noop

本文转自 li_qinshan 51CTO博客,原文链接:http://blog.51cto.com/share/1100497