puppet 是一个配置管理工具, 典型的, puppet 是一个 C/S 结构, 固然,这里的 C 能够有不少,因html
此,也能够说是一个星型结构. 全部的 puppet 客户端同一个服务器端的 puppet 通信. 每一个node
puppet 客户端每半小时(能够设置)链接一次服务器端, 下载最新的配置文件,而且严格按照配mysql
置文件来配置服务器. 配置完成之后,puppet 客户端能够反馈给服务器端一个消息. 若是出错,linux
也会给服务器端反馈一个消息. 下图展现了一个典型的 puppet 配置的数据流动状况.nginx
稳定性puppet 与其余手工操做工具备一个最大的区别就是 puppet 的配置具备稳定性,所以你能够屡次执行 puppet, 一旦你更新了你的配置文件,puppet 就会根据配置文件来更改你的机配置,一般每 30 分钟检查一次. puppet 会让你的系统状态同配置文件所要求的状态保持一致. 好比你配置文件里面要求 ssh 服务必须开启. 假如不当心 ssh 服务被关闭了,那么下一次执行 puppet 的c++
时候,puppet 会发现这个异常,而后会开启 ssh 服务. 以使系统状态和配置文件保持一web
致.puppet 就象一个魔术师,会让你的混乱的系统收敛到 puppet 配置文件所想要的状态.sql
可使用 puppet 管理服务器的整个生命周期,从初始化到退役.不一样于传统的例如 sun 的shell
Jumpstart 或者 redhat 的 Kickstart, puppet 能够终年让服务器保持最新状态.只要一开始就正数据库
确的配置他们,而后不再用去管他们.一般 puppet 用户只须要给机器安装好 puppet 并让他们
运行,而后剩余的工做都由 puppet 来完成.
puppet 的细节和原理
1. 客户端 Puppetd 向 Master 发起认证请求,或使用带签名的证书。
2. Master 告诉 Client 你是合法的。
3. 客户端 Puppetd 调用 Facter,Facter 探测出主机的一些变量,例如主机名、内存大小、IP 地址
等。Puppetd 将这些信息经过 SSL 链接发送到服务器端。
4. 服务器端的 Puppet Master 检测客户端的主机名,而后找到 manifest 对应的 node 配置,并对该部份内容进行解析。Facter 送过来的信息能够做为变量处 理,node 牵涉到的代码才解析,其余没牵涉的代码不解析。解析分为几个阶段,首先是语法检查,若是语法错误就报错;若是语法没错,就继续解析,解析的结 果生成一个中间的“伪代码”(catelog),而后把伪代码发给客户端。
5. 客户端接收到“伪代码”,而且执行。
6. 服务器端把客户端的执行结果写入日志,并发送给报告系统。
详细配置过程:
系统环境:rhel6.5 selinux and iptables disabled
sever: 172.25.254.1 vm1.example.com puppet master
client:172.25.254.2 vm2.example.com puppet agent
client:172.25.254.3 vm3.example.com puppet agent
重要:server 与全部 client 之间须要解析,以及时间同步,否则会验证失败。
server 端:
puppetmaster的安装:
a.若是主机能上网
# yum localinstall -y rubygems-1.3.7-1.el6.noarch.rpm
把如下条目加入 yum 仓库:
[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
# yum install puppet-server -y
b.若是主机不能上网
需呀下载如下安装包:
[root@vm1 update]# ls
facter-2.4.4-1.el6.x86_64.rpm ruby-augeas-0.4.1-3.el6.x86_64.rpm
hiera-1.3.4-1.el6.noarch.rpm rubygem-json-1.5.5-3.el6.x86_64.rpm
puppet-3.8.1-1.el6.noarch.rpm rubygems-1.3.7-5.el6.noarch.rpm
puppet-dashboard-1.2.23-1.el6.noarch.rpm ruby-shadow-2.2.0-2.el6.x86_64.rpm
puppet-server-3.8.1-1.el6.noarch.rpm
[root@vm1 update]# yum localinstall -y puppet-server-3.8.1-1.el6.noarch.rpm puppet-3.8.1-1.el6.noarch.rpm facter-2.4.4-1.el6.x86_64.rpm hiera-1.3.4-1.el6.noarch.rpm rubygem-json-1.5.5-3.el6.x86_64.rpm ruby*
/etc/puppet 配置目录:
组织结构以下:
|-- puppet.conf #主配置配置文件,详细内容可执行 puppet --genconfig
|-- fileserver.conf #文件服务器配置文件
|-- auth.conf #认证配置文件
|-- autosign.conf #自动验证配置文件
|-- tagmail.conf #邮件配置文件(将错误信息发送)
|-- manifests #文件存储目录(puppet 会先读取该目录的.PP 文件<site.pp>)
|--nodes
| puppetclient.pp
|-- site.pp #定义 puppet 相关的变量和默认配置。
|-- modules.pp #加载 class 类模块文件(include syslog)
|-- modules #定义模块
|-- syslog #以 syslog 为例
|-- file
|-- manifests
|-- init.pp #class 类配置
|-- templates #模块配置目录
|-- syslog.erb #erb 模板
puppet 的第一个执行的代码是在/etc/puppet/manifest/site.pp,所以这个文件必须存在,而
且其余的代码也要经过该文件来调用。
[root@vm1 puppet]# touch /etc/puppet/manifest/site.pp #没有此文件 puppet master 没法启动,配置后面再定义
[root@vm1 puppet]# service puppetmaster start #启动 puppet master
[root@vm1 puppet]# netstat -antlp |grep ruby
tcp 0 0 0.0.0.0:8140 0.0.0.0:* LISTEN 1863/ruby
client 端:
只要安装 puppet 便可,安装方法同 server 端:
a.
# yum install puppet -y
b.
[root@vm2 ~]# yum localinstall -y puppet-3.8.1-1.el6.noarch.rpm puppet-3.8.1-1.el6.noarch.rpm facter-2.4.4-1.el6.x86_64.rpm hiera-1.3.4-1.el6.noarch.rpm rubygem-json-1.5.5-3.el6.x86_64.rpm ruby*
puppet 客户端链接到 puppet master:
[root@vm2 ~]# puppet agent --server vm1.example.com --no-daemonize --verbose
Info: Creating a new SSL key for vm2.example.com
Info: Caching certificate for ca
Info: Creating a new SSL certificate request for vm2.example.com
Info: Certificate Request fingerprint (SHA256):
5C:72:77:D8:27:DF:5A:DF:34:EF:25:97:5A:CF:25:29:9F:58:83:A2:61:57:D9:20:7B:1E:C0:36:75:9D:
FB:FC
client 向 master 发出证书验证请求,而后等待 master 签名并返回证书。
参数--server 指定了须要链接的 puppet master 的名字或是地址,默认链接名为“puppet”的主机
如要修改默认链接主机能够修改/etc/sysconfig/puppet 文件中的 PUPPET_SERVER=puppet 选项
参数--no-daemonize 是 puppet 客户端运行在前台
参数--verbose 使客户端输出详细的日志
在 master 端:
[root@vm1 puppet]# puppet cert list #显示全部等待签名的证书
"vm2.example.com" (SHA256)
CD:BD:13:D0:B8:46:07:F2:B7:AE:00:C4:E6:E9:E1:A4:92:F6:A4:F1:AB:F7:FF:8D:BE:B0:B7:90:E1:
7B:A8:C0
[root@vm1 puppet]# puppet cert sign vm2.example.com #签名证书
Signed certificate request for vm2.example.com
Removing file Puppet::SSL::CertificateRequest vm2.example.com at
'/var/lib/puppet/ssl/ca/requests/vm2.example.com.pem'
如要同时签名全部证书,执行如下命令:
[root@vm1 puppet]# puppet cert sign --all
[root@vm1 puppet]# puppet cert clean vm2.example.com #删除签名证书
在对证书签名后的两分钟后,在 agent 端上能够看到以下输出:
Info: Caching certificate for vm2.example.com
Starting Puppet client version 3.0.0
Info: Caching certificate_revocation_list for ca
Info: Retrieving plugin
Info: Caching catalog for vm2.example.com
Info: Applying configuration version '1349536603'
Finished catalog run in 0.13 seconds
自动验证:
在 server 端, 编辑 puppet.conf 文件:
[root@vm1 puppet]# vim /etc/puppet/puppet.conf
[main]
autosign = true
#容许全部客户端的认证
/etc/puppet 目录下建立 autosign.conf 文件,内容以下:
# vim /etc/puppet/autosign.conf
*.example.com #表示容许全部 example.com 域的主机
[root@vm1 puppet]# service puppetmaster reload
在 client 端只需执行:
# puppet agent 或 # server puppet start
在实际中有时会修改 client 端的主机名,这样就须要从新生成证书:
1)在 server 端执行:puppet cert --clean vm2.example.com #你要删除的原 client 端主机名
2)在 client 端执行:rm -fr /var/lib/puppet/ssl/*
3)puppet agent --server vm1.example.com --no-daemonize --verbose
puppet 资源定义
如下资源均定义在/etc/puppet/manifest/site.pp 文件中,在没有指定节点的状况下,对全部
已经通过验证的 client 都生效。
1. 建立文件
[root@vm1 puppet]# vim /etc/puppet/fileserver.conf 加入如下行:
[files]
path /etc/puppet/files
allow *.example.com
[root@vm1 puppet]# service puppetmaster reload #重启服务
[root@vm1 manifests]# vim site.pp
file { "/mnt/testfile": #在/mnt下建立testfile文件
source => "puppet:///files/passwd" #来源:server端/etc/puppet/files/passwd
source => "/etc/passwd" #来源:client端/etc/passwd
}
2. 软件包定义
package { "httpd": ensure => present; #安装httpd
"vsftpd": ensure => absent #卸载vsftpd
}
3. 服务定义
service { "httpd": ensure => running; #启动httpd
"vsftpd": ensure => stopped #关闭vsftpd
}
4. 组定义
group { "wonder": gid => 600 }
5. 用户定义
user { "wonder": #建立wonder用户
uid => 600,
gid => 600,
home => "/home/wonder",
shell => "/bin/bash",
password => westos
}
file { "/home/wonder":
owner => wonder,
group => wonder,
mode => 700,
ensure => directory
}
file { "/home/wonder/.bash_profile":
source => "/etc/skel/.bash_profile",
owner => wonder,
group => wonder
}
file { "/home/wonder/.bashrc":
source => "/etc/skel/.bashrc",
owner => wonder,
group => wonder
}
user { "test": uid => 900, #建立test用户
home => "/home/test",
shell => "/bin/bash",
provider => useradd,
managehome => true,
ensure => present
}
exec { "echo westos | passwd --stdin test":
path => "/usr/bin:/usr/sbin:/bin",
onlyif => "id test"
}
6. 文件系统挂载
mount { "/mnt": #172.25.254.252主机须要开启nfs服务
device => "172.25.254.252:/var/ftp/pub",
fstype => "nfs",
options => "defaults",
ensure => absent
}
自动挂载文件系统,并同步 fstab 文件,若是须要卸载,改成 absent
7. crontab 任务
cron { echo: #2点到4点每隔10分钟,把时间导入/tmp/echo
command => "/bin/echo `/bin/date` >> /tmp/echo",
user => root,
hour => ['2-4'],
minute => '*/10'
}
# 任务会在 client 上/var/spool/cron 目录中生成
不一样节点的定义:
1. 在 puppetmaster 上编辑 site.pp
[root@vm1 puppet]# vim /etc/puppet/manifests/site.pp #写上
import "nodes/*.pp"
2. 创建节点文件
[root@vm1 puppet]#vim /etc/puppet/manifests/nodes/vm2.pp
node 'vm2' {
package { "httpd": ensure=>present}
}
[root@vm1 puppet]#vim /etc/puppet/manifests/nodes/vm3.pp
node 'vm3' {
user { "test": uid => 900,
home => "/home/test",
shell => "/bin/bash",
provider => useradd,
managehome => true,
ensure => present
}
exec { "echo westos | passwd --stdin test":
path => "/usr/bin:/usr/sbin:/bin",
onlyif => "id test"
}
}
编写模块:
[root@vm1 puppet]# mkdir -p /etc/puppet/modules/httpd/{files,manifests,templates}
[root@vm1 puppet]# cd /etc/puppet/modules/httpd/manifests
[root@vm1 manifests]# vim install.pp
class httpd::install {
package { "httpd":
ensure => present
}
}
[root@vm1 manifests]# vim config.pp
class httpd::config {
file { "/etc/httpd/conf/httpd.conf":
ensure => present,
source => "puppet:///modules/httpd/httpd.conf",
#实际路径在/etc/puppet/modules/httpd/files/httpd.conf
require => Class["httpd::install"],
notify => Class["httpd::service"]
}
}
[root@vm1 manifests]# vim service.pp
class httpd::service {
service { "httpd":
ensure => running,
require => Class["httpd::install","httpd::config"]
}
file { "/var/www/html/index.html": #添加web主页
source => "puppet:///files/index.html"
}
}
[root@vm1 manifests]# vim init.pp
class httpd {
include httpd::install,httpd::config,httpd::service
}
[root@vm1 manifests]# vim /etc/puppet/manifests/nodes/vm2.pp
node 'vm2' {
include httpd
}
[root@vm1 manifests]# service puppetmaster reload
模板应用(添加虚拟主机配置):
文件存放在 templates 目录中,以*.erb 结尾。
[root@vm1 manifests]# vim /etc/puppet/modules/httpd/manifests/init.pp #添加如下行
define httpd::vhost($domainname) {
#file { "/etc/httpd/conf/httpd.conf":
#
content => template("httpd/httpd.conf.erb")
#}
file { "/etc/httpd/conf.d/${domainname}_vhost.conf":
content => template("httpd/httpd_vhost.conf.erb"),
require => Class["httpd::install"],
notify => Class["httpd::service"]
}
file { "/var/www/$domainname":
ensure => directory
}
file { "/var/www/$domainname/index.html":
content => $domainname
}
}
[root@vm1 manifests]# vim /etc/puppet/modules/httpd/templates/httpd_vhost.conf.erb
<VirtualHost *:80>
ServerName <%= domainname %>
DocumentRoot /var/www/<%= domainname %>
ErrorLog logs/<%= domainname %>_error.log
CustomLog logs/<%= domainname %>_access.log common
</VirtualHost>
[root@vm1 manifests]# vi /etc/puppet/manifests/nodes/vm2.pp
node 'vm2' {
include httpd
httpd::vhost { 'server2.example.com':
domainname => "server2.example.com",
}
}
Puppet dashboard 安装 (用以 web 方式管理 puppet)
依赖性:
* Ruby 1.8.7
* RubyGems
* Rake >= 0.8.3
* MySQL server 5.x
* Ruby-MySQL bindings 2.7.x or 2.8.x
所需安装包 puppet-dashboard-1.2.12-1.el6.noarch.rpm rubygem-rake-0.8.7-2.1.el6.noarch.rpm ruby-mysql-2.8.2-1.el6.x86_64.rpm
[root@vm1 manifests]# yum localinstall -y puppet-dashboard-1.2.12-1.el6.noarch.rpm rubygem-rake-0.8.7-2.1.el6.noarch.rpm ruby-mysql-2.8.2-1.el6.x86_64.rpm
[root@vm1 manifests]# yum install -y mysql mysql-server
[root@vm1 manifests]# /etc/init.d/mysqld start
配置 mysql 数据库:
mysql> CREATE DATABASE dashboard_production CHARACTER SET utf8;
Query OK, 1 row affected (0.00 sec)
mysql> CREATE USER 'dashboard'@'localhost' IDENTIFIED BY 'westos';
Query OK, 0 rows affected (0.01 sec)
mysql> GRANT ALL PRIVILEGES ON dashboard_production.* TO 'dashboard'@'localhost';
Query OK, 0 rows affected (0.00 sec)
mysql>
# cd /usr/share/puppet-dashboard/
[root@vm1 puppet-dashboard]# vim config/database.yml #只留下生产环境配置
production:
database: dashboard_production
username: dashboard
password: westos
encoding: utf8
adapter: mysql
[root@vm1 puppet-dashboard]# rake RAILS_ENV=production db:migrate
#创建 dashboard 所需的数据库和表
puppet-dashboard 默认时区不正确,须要修改:
[root@vm1 puppet-dashboard]# vim /usr/share/puppet-dashboard/config/settings.yml
time_zone: 'Beijing'
启动服务:
[root@vm1 puppet-dashboard]# service puppet-dashboard start
Starting Puppet Dashboard: => Booting WEBrick
=> Rails 2.3.14 application starting on http://0.0.0.0:3000
[ OK ]
[root@vm1 puppet-dashboard]# chmod 0666 /usr/share/puppet-dashboard/log/production.log
[root@vm1 puppet-dashboard]# service puppet-dashboard-workers start
实时报告汇总:
设置 server 端:
root@vm1 ~]# vim /etc/puppet/puppet.conf
[main]
#添加如下两项
reports = http
reporturl = http://172.25.254.1:3000/reports
root@vm1 ~]# service puppetmaster reload
设置 client 端:
[root@vm1 puppet-dashboard]# vim /etc/puppet/puppet.conf #添加如下行
[agent]
report = true
[root@vm1 puppet-dashboard]# service puppet reload
在客户端安装完 puppet 后,而且认证完后,咱们能够看到效果,那怎样让它自动与服务器同步
呢?默认多少分钟跟服务器同步呢?怎样修改同步的时间呢,这时候咱们须要配置客户端:
(1) 配置 puppet 相关参数和同步时间:
[root@vm2 ~]# vim /etc/sysconfig/puppet
PUPPET_SERVER=puppet.example.com #puppet master 的地址
PUPPET_PORT=8140 #puppet 监听端口
PUPPET_LOG=/var/log/puppet/puppet.log #puppet 本地日志
#PUPPET_EXTRA_OPTS=--waitforcert=500 【默认同步的时间,我这里不修改这行参数】
(2) 默认配置完毕后,客户端会半个小时跟服务器同步一次,咱们能够修改这个时间。
[root@vm2 ~]# vim /etc/puppet/puppet.conf
[agent]
runinterval = 60 #表明 60 秒跟服务器同步一次
[root@vm2 ~]# service puppet reload
对puppet的优化 经过nginx + passenger替换掉puppet的WEBRickHTTP,来处理HTTPS请求,并实现对puppet的负载均衡。
实验步骤:master 端须要可以连上外网把如下条目加入 yum 仓库:[puppet]name=puppetbaseurl=http://yum.puppetlabs.com/el/6Server/products/x86_64/gpgcheck=0[ruby]name=rubybaseurl=http://yum.puppetlabs.com/el/6Server/dependencies/x86_64/gpgcheck=0# yum install -y gcc gcc-c++ curl-devel zlib-devel openssl-devel ruby-devel# gem install rack passenger ##次过程须要等待一段时间# gem list*** LOCAL GEMS ***json (1.5.5)passenger (5.0.15)rack (1.6.4)rake (10.4.2)# passenger-config --root/usr/lib/ruby/gems/1.8/gems/passenger-5.0.15# ls /usr/lib/ruby/gems/1.8/gems/passenger-5.0.15/ext/ apache2 boost common libev libuv nginx oxt ruby #nginx 等许多支持# passenger-install-nginx-module脚本会自动安装 nginx 支持,按提示操做,基本就是一路回车。 nginx 默认安装在/opt/nginx 目录: # vim /opt/nginx/conf/nginx.conf 1 #user nobody; 2 worker_processes 4; 3 4 #error_log logs/error.log; 5 #error_log logs/error.log notice; 6 #error_log logs/error.log info; 7 8 #pid logs/nginx.pid; 9 10 11 events { 12 use epoll; 13 worker_connections 1024; 14 } 15 16 17 http { 18 passenger_root /usr/lib/ruby/gems/1.8/gems/passenger-5.0.15; 19 passenger_ruby /usr/bin/ruby; 20 21 include mime.types; 22 default_type application/octet-stream; 23 24 #log_format main '$remote_addr - $remote_user [$time_local] "$request" ' 25 # '$status $body_bytes_sent "$http_referer" ' 26 # '"$http_user_agent" "$http_x_forwarded_for"'; 27 28 #access_log logs/access.log main; 29 30 sendfile on; 31 tcp_nopush on; 32 33 #keepalive_timeout 0; 34 keepalive_timeout 65; 35 36 #gzip on; 37 38 server { 39 listen 8140; 40 server_name benberba.example.com; 41 root /etc/puppet/rack/public; 42 passenger_enabled on; 43 passenger_set_header X_CLIENT_DN $ssl_client_s_dn; 44 passenger_set_header X_CLIENT_VERIFY $ssl_client_verify; 45 ssl on; 46 ssl_session_timeout 5m; 47 ssl_certificate /var/lib/puppet/ssl/certs/vm1.example.com.pem; 48 ssl_certificate_key /var/lib/puppet/ssl/private_keys/vm1.example.co m.pem; 49 ssl_client_certificate /var/lib/puppet/ssl/ca/ca_crt.pem; 50 ssl_crl /var/lib/puppet/ssl/ca/ca_crl.pem; 51 ssl_verify_client optional; 52 ssl_ciphers SSLv2:-LOW:-EXPORT:RC4+RSA; 53 ssl_prefer_server_ciphers on; 54 ssl_verify_depth 1; 55 ssl_session_cache shared:SSL:128m; 56 } 57 }# mkdir /etc/puppet/rack/{public,tmp} -p# cp /usr/share/puppet/ext/rack/config.ru /etc/puppet/rack/# chown puppet.puppet /etc/puppet/rack/config.ru# chkconfig puppetmaster off# service puppetmaster stop# /opt/nginx/sbin/nginx -t #检测 nginx# /opt/nginx/sbin/nginx #启动 nginxpuppetmaster 不须要启动 , nginx 启动时会自动调用 puppet。测试 master端 # netstat -antpl |grep 8140tcp 0 0 0.0.0.0:8140 0.0.0.0:* LISTEN 4245/nginx # /etc/init.d/puppetmaster status puppet is stoppedclient端 # puppet agent --server vm1.example.com --no-daemonize --verboseNotice: Starting Puppet client version 3.8.1Info: Retrieving pluginfactsInfo: Retrieving pluginInfo: Caching catalog for vm2.example.comInfo: Applying configuration version '1440218993'Notice: Finished catalog run in 0.21 seconds