前言
Puppet这个词实际上包括了两层含义:它既代表编写这种代码的语言,也代表对基础设施进行管理的平台。做运维总是靠流程驱动和事故驱动,无论是生产还是测试环境配置上的不统一使得团队的整体效率大打折扣。能够在开发者的笔记本或是在QA环境下正常工作的代码,往往在部署到生产环境后就会出现问题,最糟糕的是没人知道问题的根源在哪里。而Puppet是一个优秀的基础设施管理平台,可以让每个系统管理员更高效地完成工作,Puppet能够为共享的代码库提供一种强力的粘合剂,以统一不同团队的工作。Puppet可以帮助处于各种不同状况的团队增强协作能力,以进行软件开发和发布的——这种工作方式的演变通常被称做DevOps。
Puppet是最佳的集中配置管理系统之一
更新记录
2016年03月25日 - 初稿
阅读原文 - http://wsgzao.github.io/post/puppet/
扩展阅读
Puppet Labs Documentation - https://docs.puppetlabs.com/
Puppet Forge - https://forge.puppetlabs.com/
工作原理
Puppet采用了非常简单的C/S架构,所有数据的交互都通过SSL进行,以保证安全
客户端Puppetd向Master发起认证请求,或使用带签名的证书。
Master告诉Client你是合法的。
客户端Puppetd调用Facter,Facter探测出主机的一些变量,例如主机名、内存大小、IP地址等。Puppetd将这些信息通过SSL连接发送到服务器端。
服务器端的Puppet Master检测客户端的主机名,然后找到manifest对应的node配置,并对该部分内容进行解析。Facter送过来的信息可以作为变量处 理,node牵涉到的代码才解析,其他没牵涉的代码不解析。解析分为几个阶段,首先是语法检查,如果语法错误就报错;如果语法没错,就继续解析,解析的结 果生成一个中间的“伪代码”(catelog),然后把伪代码发给客户端。
客户端接收到“伪代码”,并且执行。
客户端在执行时判断有没有File文件,如果有,则向fileserver发起请求。
客户端判断有没有配置Report,如果已配置,则把执行结果发送给服务器。
服务器端把客户端的执行结果写入日志,并发送给报告系统。
这就是puppet的工作流程,最重要的莫过于puppet-master来管理node的配置文件。
准备工作
以rhel6.3为例,前期核心在于配置yum,更多技巧可以参考以下文章
RHEL(Red Hat Enterprise Linux)配置yum源 - http://wsgzao.github.io/post/yum/
#关闭iptables
/etc/init.d/iptables stop
chkconfig iptables off
#关闭selinux
setenforce 0
sed -i 's/SELINUX=enforcing/SELINUX=disabled/' /etc/selinux/config
#NTP同步
ntpdate 0.rhel.pool.ntp.org
crontab -e
0 0 * * * /usr/sbin/ntpdate 0.rhel.pool.ntp.org;/usr/sbin/hwclock -w
#添加hosts
vi /etc/hosts
192.168.1.10 master
192.168.1.11 client
#puppet
http://downloads.puppetlabs.com/puppet/
#facter
http://downloads.puppetlabs.com/facter/
#ruby
https://www.ruby-lang.org/zh_cn/downloads/
#配置CentOS YUM源
cd /etc/yum.repos.d/
cp rhel-source.repo rhel-source.repo.bak
vi rhel-source.repo
[base]
name=CentOS-$releasever-Base
baseurl=http://centos.ustc.edu.cn/centos/6/os/x86_64/
gpgcheck=1
gpgkey=http://mirrors.163.com/centos/RPM-GPG-KEY-CentOS-6
[updates]
name=CentOS-$releasever-Updates
baseurl=http://centos.ustc.edu.cn/centos/6/os/x86_64/
gpgcheck=1
gpgkey=http://mirrors.163.com/centos/RPM-GPG-KEY-CentOS-6
[extras]
name=CentOS-$releasever-Extras
baseurl=http://centos.ustc.edu.cn/centos/6/os/x86_64/
gpgcheck=1
gpgkey=http://mirrors.163.com/centos/RPM-GPG-KEY-CentOS-6
[centosplus]
name=CentOS-$releasever-Plus
baseurl=http://centos.ustc.edu.cn/centos/6/os/x86_64/
gpgcheck=1
yum clean all
yum makecache
yum repolist
Puppet Server
如果可以访问外网并配置repos,直接yum install puppetserver简单粗暴
#Enable the Puppet Labs Package Repository
rpm -ivh https://yum.puppetlabs.com/puppetlabs-release-el-6.noarch.rpm
#安装yum-plugin-downloadonly插件
yum install -y yum-plugin-downloadonly
#yum install puppetserver
yum install --downloadonly --downloaddir=/tmp/puppetserver puppetserver
Total download size: 73 M
Is this ok [y/N]: y
Downloading Packages:
(1/22): augeas-libs-1.0.0-10.el6.x86_64.rpm
(2/22): compat-readline5-5.2-17.1.el6.x86_64.rpm
(3/22): facter-2.4.6-1.el6.x86_64.rpm
(4/22): hiera-1.3.4-1.el6.noarch.rpm
(5/22): java-1.7.0-openjdk-1.7.0.79-2.5.5.4.el6.x86_6
(6/22): libjpeg-turbo-1.2.1-3.el6_5.x86_64.rpm
(7/22): libselinux-2.0.94-5.8.el6.i686.rpm
(8/22): libselinux-2.0.94-5.8.el6.x86_64.rpm
(9/22): libselinux-devel-2.0.94-5.8.el6.x86_64.rpm
(10/22): libselinux-python-2.0.94-5.8.el6.x86_64.rpm
(11/22): libselinux-ruby-2.0.94-5.8.el6.x86_64.rpm
(12/22): libselinux-utils-2.0.94-5.8.el6.x86_64.rpm
(13/22): puppet-3.8.6-1.el6.noarch.rpm
(14/22): puppetserver-1.1.3-1.el6.noarch.rpm
(15/22): ruby-1.8.7.374-4.el6_6.x86_64.rpm
(16/22): ruby-augeas-0.4.1-3.el6.x86_64.rpm
(17/22): ruby-irb-1.8.7.374-4.el6_6.x86_64.rpm
(18/22): ruby-libs-1.8.7.374-4.el6_6.x86_64.rpm
(19/22): ruby-rdoc-1.8.7.374-4.el6_6.x86_64.rpm
(20/22): ruby-shadow-2.2.0-2.el6.x86_64.rpm
(21/22): rubygem-json-1.5.5-3.el6.x86_64.rpm
(22/22): rubygems-1.3.7-5.el6.noarch.rpm
master@/tmp/puppetserver#rpm -Uvh *
warning: augeas-libs-1.0.0-10.el6.x86_64.rpm: Header V3 RSA/SHA1 Signature, key ID c105b9de: NOKEY
warning: facter-2.4.6-1.el6.x86_64.rpm: Header V4 RSA/SHA1 Signature, key ID 4bd6ec30: NOKEY
Preparing... ########################################### [100%]
1:libselinux ########################################### [ 5%]
2:augeas-libs ########################################### [ 9%]
3:libselinux-ruby ########################################### [ 14%]
4:libselinux-utils ########################################### [ 18%]
5:libjpeg-turbo ########################################### [ 23%]
6:java-1.7.0-openjdk ########################################### [ 27%]
7:compat-readline5 ########################################### [ 32%]
8:ruby-libs ########################################### [ 36%]
9:ruby ########################################### [ 41%]
10:facter ########################################### [ 45%]
11:ruby-irb ########################################### [ 50%]
12:ruby-rdoc ########################################### [ 55%]
13:rubygems ########################################### [ 59%]
14:rubygem-json ########################################### [ 64%]
15:hiera ########################################### [ 68%]
16:ruby-shadow ########################################### [ 73%]
17:ruby-augeas ########################################### [ 77%]
18:puppet ########################################### [ 82%]
19:puppetserver ########################################### [ 86%]
20:libselinux-devel ########################################### [ 91%]
21:libselinux-python ########################################### [ 95%]
22:libselinux ########################################### [100%]
#验证puppetserver
master@/tmp/puppetserver#yum install puppetserver
Loaded plugins: downloadonly, product-id, refresh-packagekit, security, subscription-manager
Updating certificate-based repositories.
Unable to read consumer identity
Setting up Install Process
Package puppetserver-1.1.3-1.el6.noarch already installed and latest version
Nothing to do
#增加puppet master配置信息
vi /etc/puppet/puppet.conf
[main]
# master的主机名
server = master
# master的主机名
certname = master
#禁用插件同步
pluginsync = false
# The Puppet log directory.
# The default value is '$vardir/log'.
logdir = /var/log/puppet
# Where Puppet PID files are kept.
# The default value is '$vardir/run'.
rundir = /var/run/puppet
# Where SSL certificates are kept.
# The default value is '$confdir/ssl'.
ssldir = $vardir/ssl
[agent]
# The file in which puppetd stores a list of the classes
# associated with the retrieved configuratiion. Can be loaded in
# the separate ``puppet`` executable using the ``--loadclasses``
# option.
# The default value is '$confdir/classes.txt'.
classfile = $vardir/classes.txt
# Where puppetd caches the local configuration. An
# extension indicating the cache format is added automatically.
# The default value is '$confdir/localconfig'.
localconfig = $vardir/localconfig
#启动puppet
puppet master
ps -ef |grep master
puppet 3077 1 0 10:09 ? 00:00:00 /usr/bin/ruby /usr/bin/puppet master
root 3081 3015 0 10:09 pts/0 00:00:00 grep master
Puppet Client
如果可以访问外网并配置repos,直接yum install puppet简单粗暴
#Enable the Puppet Labs Package Repository
rpm -ivh https://yum.puppetlabs.com/puppetlabs-release-el-6.noarch.rpm
#安装yum-plugin-downloadonly插件
yum install -y yum-plugin-downloadonly
#yum install puppet
yum install --downloadonly --downloaddir=/tmp/puppet puppet
Downloading Packages:
(1/19): augeas-libs-1.0.0-10.el6.x86_64.rpm
(2/19): compat-readline5-5.2-17.1.el6.x86_64.rpm
(3/19): facter-2.4.6-1.el6.x86_64.rpm
(4/19): hiera-1.3.4-1.el6.noarch.rpm
(5/19): libselinux-2.0.94-5.8.el6.i686.rpm
(6/19): libselinux-2.0.94-5.8.el6.x86_64.rpm
(7/19): libselinux-devel-2.0.94-5.8.el6.x86_64.rpm
(8/19): libselinux-python-2.0.94-5.8.el6.x86_64.rpm
(9/19): libselinux-ruby-2.0.94-5.8.el6.x86_64.rpm
(10/19): libselinux-utils-2.0.94-5.8.el6.x86_64.rpm
(11/19): puppet-3.8.6-1.el6.noarch.rpm
(12/19): ruby-1.8.7.374-4.el6_6.x86_64.rpm
(13/19): ruby-augeas-0.4.1-3.el6.x86_64.rpm
(14/19): ruby-irb-1.8.7.374-4.el6_6.x86_64.rpm
(15/19): ruby-libs-1.8.7.374-4.el6_6.x86_64.rpm
(16/19): ruby-rdoc-1.8.7.374-4.el6_6.x86_64.rpm
(17/19): ruby-shadow-2.2.0-2.el6.x86_64.rpm
(18/19): rubygem-json-1.5.5-3.el6.x86_64.rpm
(19/19): rubygems-1.3.7-5.el6.noarch.rpm
#离线安装
client@/tmp/puppet#rpm -Uvh *
warning: facter-2.4.6-1.el6.x86_64.rpm: Header V4 RSA/SHA1 Signature, key ID 4bd6ec30: NOKEY
Preparing... ########################################### [100%]
1:libselinux ########################################### [ 5%]
2:augeas-libs ########################################### [ 11%]
3:libselinux-ruby ########################################### [ 16%]
4:libselinux-utils ########################################### [ 21%]
5:compat-readline5 ########################################### [ 26%]
6:ruby-libs ########################################### [ 32%]
7:ruby ########################################### [ 37%]
8:facter ########################################### [ 42%]
9:ruby-irb ########################################### [ 47%]
10:ruby-rdoc ########################################### [ 53%]
11:rubygems ########################################### [ 58%]
12:rubygem-json ########################################### [ 63%]
13:hiera ########################################### [ 68%]
14:ruby-shadow ########################################### [ 74%]
15:ruby-augeas ########################################### [ 79%]
16:puppet ########################################### [ 84%]
17:libselinux-devel ########################################### [ 89%]
18:libselinux-python ########################################### [ 95%]
19:libselinux ########################################### [100%]
#验证puppet
client@/tmp/puppet#yum install puppet
Loaded plugins: fastestmirror, product-id, refresh-packagekit, security, subscription-manager
Updating certificate-based repositories.
Unable to read consumer identity
Setting up Install Process
Loading mirror speeds from cached hostfile
Package puppet-3.8.6-1.el6.noarch already installed and latest version
Nothing to do
#增加puppet client配置信息
vi /etc/puppet/puppet.conf
[main]
# master的主机名
server = master
# 禁用插件同步
pluginsync = false
# The Puppet log directory.
# The default value is '$vardir/log'.
logdir = /var/log/puppet
# Where Puppet PID files are kept.
# The default value is '$vardir/run'.
rundir = /var/run/puppet
# Where SSL certificates are kept.
# The default value is '$confdir/ssl'.
ssldir = $vardir/ssl
[agent]
# The file in which puppetd stores a list of the classes
# associated with the retrieved configuratiion. Can be loaded in
# the separate ``puppet`` executable using the ``--loadclasses``
# option.
# The default value is '$confdir/classes.txt'.
classfile = $vardir/classes.txt
# Where puppetd caches the local configuration. An
# extension indicating the cache format is added automatically.
# The default value is '$confdir/localconfig'.
localconfig = $vardir/localconfig
Puppet证书认证
Puppet为了安全,采用ssl隧道通信,因此需要申请证书来验证的
#client agent连接server
puppet agent --server=master
#在master上查看申请证书请求
puppet cert --list
"client" (SHA256) BC:1B:42:88:B0:A4:F0:F2:81:56:5D:0E:7A:49:90:83:79:F2:41:A5:E3:12:FC:E2:F2:DB:DE:30:8E:DB:0D:D0
#在master上签发证书
#puppet cert sign --all
puppet cert --sign client
Notice: Signed certificate request for client
Notice: Removing file Puppet::SSL::CertificateRequest client at '/var/lib/puppet/ssl/ca/requests/client.pem'
#查看证书,"+"表示已经签名成功
puppet cert -all
+ "client" (SHA256) BC:1B:42:88:B0:A4:F0:F2:81:56:5D:0E:7A:49:90:83:79:F2:41:A5:E3:12:FC:E2:F2:DB:DE:30:8E:DB:0D:D0
+ "master" (SHA256) 04:45:21:0B:B5:5E:41:AE:9C:F4:B4:6B:EC:2F:AA:D2:BE:46:33:3E:B1:0E:85:2E:3C:B7:6B:98:95:A8:CE:4D
Puppet同步验证
#在master上创建一个site.pp文件
vi /etc/puppet/manifests/site.pp
node default { file { "/tmp/test.txt": content => "Hello, First puppet test!"} }
#在client机进行验证,如果/tmp/test.txt文件生成并有内容,则说明功能正常。
puppet agent --test
Info: Caching catalog for client
Info: Applying configuration version '1458888162'
Notice: /Stage[main]/Main/Node[default]/File[/tmp/test.txt]/ensure: defined content as '{md5}390b4c389233b9ae38a84ff8c731a8a1'
Info: Creating state file /var/lib/puppet/state/state.yaml
Notice: Finished catalog run in 0.03 seconds
Troubleshooting
硬件配置/操作系统记得按照Puppet的官方建议来做,遇到错误仔细分析日志
https://docs.puppetlabs.com/pe/latest/install_system_requirements.html
https://docs.puppetlabs.com/guides/troubleshooting.html
#Error: Could not find certificate request for client
#execute on your puppet master.
puppet cert clean "yourhostnamehere"
#execute on your puppet agent.
rm -f /etc/puppetlabs/puppet/ssl/certs/yourhostnamehere
find /var/lib/puppet -name *yourhostnamehere* -delete
puppet agent -t
#back for your puppet master
puppet cert --list
#check your name certificate and sign.
puppet cert --sign "yourhostnamehere"
#come back to your puppet agent and be happy :D
puppet agent -t
#客户端报错提示的方法也是类似
Error: Could not request certificate: The certificate retrieved from the master does not match the agent's private key.
To fix this, remove the certificate from both the master and the agent and then start a puppet run, which will automatically regenerate a certficate.
On the master:
puppet cert clean "client"
On the agent:
1a. On most platforms: find /var/lib/puppet/ssl -name client.pem -delete
1b. On Windows: del "/var/lib/puppet/ssl/client.pem" /f
2. puppet agent -t
#Error: Could not run: Could not create PID file: /var/run/puppet/master.pid
killall puppet
puppet master --verbose --no-daemonize
#puppet agent --test
Error: Could not retrieve catalog from remote server: Error 400 on SERVER: Could not parse for environment production: Permission denied - /etc/puppet/manifests/site.pp on node client.cffex.com.cn
Warning: Not using cache on failed catalog
Error: Could not retrieve catalog; skipping run
#注意/etc/puppet/manifests的权限