puppet 是一个配置管理工具, 典型的, puppet 是一个 C/S 结构, 当然,这里的 C 可以有很多,因
此,也可以说是一个星型结构. 所有的 puppet 客户端同一个服务器端的 puppet 通讯. 每个
puppet 客户端每半小时(可以设置)连接一次服务器端, 下载最新的配置文件,并且严格按照配
置文件来配置服务器. 配置完成以后,puppet 客户端可以反馈给服务器端一个消息. 如果出错,
也会给服务器端反馈一个消息. 下图展示了一个典型的 puppet 配置的数据流动情况.
puppet 的细节和原理
puppet 的目的是让你只集中于你要管理的目标,而忽略实现的细节,例如命令名,参数或者文件
格式. puppet 把系统里面的用户,软件包,服务看作是"资源", puppet 的作用就是管理这些资源
以及资源之间的相互联系.
Puppet 采用了非常简单的 C/S 架构,所有数据的交互都通过 SSL 进行,以保证安全。它的工作
1. 客户端 Puppetd 向 Master 发起认证请求,或使用带签名的证书。
2. Master 告诉 Client 你是合法的。
3. 客户端 Puppetd 调用 Facter,Facter 探测出主机的一些变量,例如主机名、内存大小、IP 地址
等。Puppetd 将这些信息通过 SSL 连接发送到服务器端。
4. 服务器端的 Puppet Master 检测客户端的主机名,然后找到 manifest 对应的 node 配置,并对该
部分内容进行解析。Facter 送过来的信息可以作为变量处 理,node 牵涉到的代码才解析,其他
没牵涉的代码不解析。解析分为几个阶段,首先是语法检查,如果语法错误就报错;如果语法
没错,就继续解析,解析的结 果生成一个中间的“伪代码”(catelog),然后把伪代码发给客
户端。
5. 客户端接收到“伪代码”,并且执行。
6. 客户端在执行时判断有没有 File 文件,如果有,则向 fileserver 发起请求。
7. 客户端判断有没有配置 Report,如果已配置,则把执行结果发送给服务器。
8. 服务器端把客户端的执行结果写入日志,并发送给报告系统
现在我们开始配置:
环境:rhel6.3 selinux and iptables disabled
master:192.168.1.41 cluster1.example.com
client : 192.168.1.42 cluster2.example.com
192.168.1.43 cluster3.example.com
master 与所有的client之间需要解析,以及时间的同步,不然会失败。 //时间同步大家可以参见我的
ntp时间同步http://my.oschina.net/zhangxc73912/blog/207197
master端:
首先.yum仓库添加如下:
[root@cluster1~]#vim/etc/yum.repos.d/rhel-source.repo [puppet] name=puppet baseurl=http://yum.puppetlabs.com/el/6Server/products/x86_64/ gpgcheck=0 [ruby] name=ruby baseurl=http://yum.puppetlabs.com/el/6Server/dependencies/x86_64/ gpgcheck=0 [optioal] name=optional baseurl=ftp://192.168.1.233/pub/puppet/optional gpgcheck=0
//optional 包大家可以下载我的,包里面有所需要的资源
http://yunpan.cn/QIf54dLXyJwhB
安装puppet-server
[root@cluster1~]#yuminstallpuppet-server
配置
[root@cluster1~]#cd/etc/puppet/manifests/ [root@cluster1manifests]#touchsite.pp//puppet的第一个执行的代码是在/etc/puppet/manifest/site.pp, 因此这个文件必须存在,而且其他的代码也要通过该文件来调用。也就是说没有此文件puppetmaster无法启动,配置后面再定义
启动
[root@cluster1manifests]#/etc/init.d/puppetmasterstart [root@cluster1manifests]#netstat-anltp tcp000.0.0.0:81400.0.0.0:*LISTEN1335/ruby
clinet端:
yum配置和master相同
[root@cluster2~]#yuminstallpuppet-y
我们首先不要开启pppute,即让服务在前端跑,且不要打入后端。
首先做的是测试,测试成功,再将其打入后端
[root@cluster2~]#puppetagent--servercluster1.example.com--no-daemonize--verbose Info:CreatinganewSSLkeyforcluster2.example.com Info:Cachingcertificateforca Info:csr_attributesfileloadingfrom/etc/puppet/csr_attributes.yaml Info:CreatinganewSSLcertificaterequestforcluster2.example.com Info:CertificateRequestfingerprint(SHA256): 74:A1:FC:A7:BB:E1:9E:5B:F3:89:BB:0D:41:5B:10:59:76:D3:DF:2D:25:F4:6B:ED:78:14:9F:0C:87:76:02:B7 Info:Cachingcertificateforca
client 向 master 发出证书验证请求,然后等待 master 签名并返回证书。
参数--server 指定了需要连接的 puppet master 的名字或是地址,默认连接名为“puppet”的主机
如要修改默认连接主机可以修改/etc/sysconfig/puppet 文件中的 PUPPET_SERVER=puppet 选项
参数--no-daemonize 是 puppet 客户端运行在前台
参数--verbose 使客户端输出详细的日志
在 master端
[root@cluster1~]#puppetcertlist//显示等待签名的证书 "cluster2.example.com"(SHA256)74:A1:FC:A7:BB:E1:9E:5B:F3:89:BB:0D:41:5B:10:59:76:D3:DF:2D:25:F4:6B:ED:78:14:9F:0C:87:76:02:B7 [root@cluster1~]#puppetcertsigncluster2.example.com//签名证书 Notice:Signedcertificaterequestforcluster2.example.com Notice:RemovingfilePuppet::SSL::CertificateRequestcluster2.example.comat\'/var/lib/puppet/ssl/ca/requests/cluster2.example.com.pem\'
如果需要同时签名所有证书,则
[root@cluster1~]#puppetcertsign--all
如果要删除证书则
[root@cluster1~]#puppetcertcleancluster2.example.com
在签署完成之后(等待一段时间)在client端,会有如下输出:
Info:Cachingcertificate_revocation_listforca Info:Retrievingplugin Info:Cachingcatalogforcluster2.example.com Info:Applyingconfigurationversion\'1395006768\' Info:Creatingstatefile/var/lib/puppet/state/state.yaml
当然了,在实际当中,我们则需要它自动签署:
master端:
[root@cluster1~]#vi/etc/puppet/puppet.conf [main] autosign=true//允许所有客户认证 [root@cluster1~]#touch/etc/puppet/autosign.conf [root@cluster1~]#vi/etc/puppet/autosign.conf .example.com//允许该域的主机,当然我们还可以再添见域,另起一行书写 [root@cluster1~]#/etc/init.d/puppetmasterreload
client端:
[root@cluster3~]#puppetagent--servercluster1.example.com--no-daemonize--verbose//他就会自动被签署了
在实际中有时会修改 client 端的主机名,这样就需要重新生成证书:
1)在 server 端执行:
[root@cluster1~]#puppetcert--cleancluster2.example.com//删除原有的client端主机名,ssl Notice:Revokedcertificatewithserial3 Notice:RemovingfilePuppet::SSL::Certificatecluster2.example.comat\'/var/lib/puppet/ssl/ca/signed/cluster2.example.com.pem\' Notice:RemovingfilePuppet::SSL::Certificatecluster2.example.comat\'/var/lib/puppet/ssl/certs/cluster2.example.com.pem\'
2)在 client 端执行:rm -fr /var/lib/puppet/ssl/*
[root@cluster2~]#rm-rf/var/lib/puppet/ssl/* [root@cluster2~]#puppetagent--servercluster1.example.com--no-daemonize--verbose
puppet 资源定义
以下资源均定义在/etc/puppet/manifest/site.pp 文件中,在没有指定节点的情况下,对所有
已经经过验证的 client 都生效
<1-7 摘子讲义>
1. 创建文件
file{"/var/www/html/index.html":content=>"www.example.com"} mkdir/etc/puppet/files echowww.westos.org>/etc/puppet/files/index.html vi/etc/puppet/fileserver.conf [files] path/etc/puppet/files allow*.example.com servicepuppetmasterreload file{"/var/www/html/index.html": source=>"puppet:///files/index.html", }
2. 软件包定义
package{“httpd”:ensure=>present; “vsftpd”:ensure=>absent }
3. 服务定义
service{"httpd":ensure=>running; “vsftpd”:ensure=>stopped }
4. 组定义
group{"wxh":gid=>600}
5. 用户定义
user{"wxh": uid=>600, gid=>600, home=>"/home/wxh", shell=>"/bin/bash", password=>westos } file{"/home/wxh": owner=>wxh, group=>wxh, mode=>700, ensure=>directory } file{"/home/wxh/.bash_logout": source=>"/etc/skel/.bash_logout", owner=>wxh, group=>wxh } file{"/home/wxh/.bash_profile": source=>"/etc/skel/.bash_profile", owner=>wxh, group=>wxh } file{"/home/wxh/.bashrc": source=>"/etc/skel/.bashrc", owner=>wxh, group=>wxh } user{"test":uid=>900, home=>"/home/test", shell=>"/bin/bash", provider=>useradd, managehome=>true, ensure=>absent } exec{"echowestos|passwd--stdintest": path=>"/usr/bin:/usr/sbin:/bin", onlyif=>"idtest" }
6. 文件系统挂载
file{"/public": ensure=>directory } mount{"/public": device=>"192.168.0.254:/var/ftp/pub", fstype=>"nfs", options=>"defaults", ensure=>mounted }
7. crontab 任务
cron{echo: command=>"/bin/echo`/bin/date`>>/tmp/echo", user=>root, hour=>[\'2-4\'], minute=>\'*/10\' }
下面我举个例子,(后面我会给大家介绍模块的思想)
[root@cluster1puppet]#vi/etc/puppet/fileserver.conf [files] path/etc/puppet/files allow* [root@cluster1puppet]#mkdir/etc/puppet/files [root@cluster1puppet]#/etc/init.d/puppetmasterrestart
例1:(文件)
master端:
[root@cluster1files]#cp/etc/passwd/etc/puppet/files/passwd [root@cluster1files]#vim/etc/puppet/manifests/site.pp file{"/tmp/zhang_1": source=>"puppet:///files/index.html", mode=>600 }
client端:
[root@cluster3tmp]#puppetagent--servercluster1.example.com--no-daemonize--verbose [root@cluster3tmp]#cat/tmp/zhang_1//成功建立 zhangxc1
例2:(安装服务,卸载服务,启动服务)
master端:
[root@cluster1puppet]#vimanifests/site.pp package{["vim-enhanced","httpd"]: ensure=>present; ["vsftpd"]: ensure=>absent; } service{"httpd": ensure=>"running"//stopped为停止服务 }
clientd端:
[root@cluster3~]#puppetagent--servercluster1.example.com--no-daemonize--verbose ... Notice:/Stage[main]/Main/Service[httpd]/ensure:ensurechanged\'stopped\'to\'running\' ...
当然在批量部署的时候,我们会选择主机,进行部署不同的服务:做法如下:(nodes.pp为指定节点,site.pp为全部节点)
master端:
[root@cluster1manifests]#visite.pp import"nodes.pp" [root@cluster1manifests]#vinodes.pp node\'cluster2.example.com\'{ file{"/tmp/zhangxc-cluster2": source=>"puppet:///files/passwd", mode=>600 } } node\'cluster3.example.com\'{ file{"/tmp/zhangxc-cluster3": source=>"puppet:///files/index.html", mode=>600 } }
client端:
[root@cluster2~]#puppetagent--servercluster1.example.com--no-daemonize--verbose [root@cluster2tmp]#ls zhangxc-cluster2 [root@cluster3~]#puppetagent--servercluster1.example.com--no-daemonize--verbose [root@cluster3tmp]#ls zhangxc-cluster3
当然在生产环境当中我们不能这样一步一步做,所以在这里我将经给大家介绍模块,当你需要对一个服务进行操作我们则可做成模块供各个节点使用。
大家可以举一反三,在这里我以在apache做虚拟主机为例:
master端:
[root@cluster1~]#cd/etc/puppet/modules/ [root@cluster1modules]#mkdirhttpd/ [root@cluster1httpd]#mkdirfilesmanifests [root@cluster1httpd]#cdmanifests/ [root@cluster1manifests]#ls config.ppinit.ppinstall.ppservice.pp [root@cluster1manifests]#ls../files/ httpd.conf [root@cluster1manifests]#catinstall.pp classhttpd::install{ package{"httpd": ensure=>present } } [root@cluster1manifests]#catservice.pp classhttpd::service{ service{"httpd": ensure=>running, require=>Class["httpd::install","httpd::config"] } } [root@cluster1manifests]#catconfig.pp classhttpd::config{ file{"/etc/httpd/conf/httpd.conf": ensure=>present, source=>"puppet:///modules/httpd/httpd.conf", require=>Class["httpd::install"], notify=>Class["httpd::service"] } } [root@cluster1manifests]#catinit.pp classhttpd{ includehttpd::install,httpd::config,httpd::service } [root@cluster1manifests]#vi../files/httpd.conf ... ServerName192.168.1.43:80 ...
client端:
[root@cluster3~]#puppetagent--servercluster1.example.com--no-daemonize--verbose
当让我clients端:
[root@cluster2~]#/etc/init.d/puppetstart//当我们配置没有问题时,就可以启动该服务。(注意开头那些话)
这样就ok了,大家可以在这基础上扩展!