Puppet 集中化管理系统
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.5 selinux and iptables disabled
sever:172.25.44.33 server3.example.com puppet master
client:172.25.44.44 server4.example.com puppet agent
client:172.25.44.55 server5.example.com puppet agent
重要:server与所有client之间需要解析,以及时间同步,不然会验证失败。
1.对server端和client端进行配置
在server端:
yum install -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-shadow-2.2.0-2.el6.x86_64.rpm ruby-augeas-0.4.1-3.el6.x86_64.rpm rubygems-1.3.7-5.el6.noarch.rpm
/etc/puppet下的配置目录如下图所示:
在client端: yum install -y 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-shadow-2.2.0-2.el6.x86_64.rpm ruby-augeas-0.4.1-3.el6.x86_64.rpm rubygems-1.3.7-5.el6.noarch.rpm puppet agent --server server3.example.com --no-daemonize -vt ##客户端连接到puppet master,client向master发出证书验证请求,然后等待master签名并返回证书。参数--server 指定了需要连接的puppet master的名字或是地址,默认连接名为“puppet”的主机如要修改默认连接主机可以修改/etc/sysconfig/puppet 文件中的 PUPPET_SERVER=puppet选项参数--no-daemonize是puppet客户端运行在前台. 如图:
如果报错为‘Exiting; no certificate found and waitforcert is disabled’,需要在puppet master上对client端进行证书验证, puppet cert sign server4.example.com.
在server端:
puppet cert list --all ##显示所有等待签名的证书 如图:
2.开启自动验证
在server端:
vim /etc/puppet/puppet.conf [main] autosign = true ##允许所有客户端认证 # The Puppet log directory. # The default value is '$vardir/log'. logdir = /var/log/puppet /etc/puppet 目录下创建autosign.conf文件,内容如下: *.example.com ##表示允许所有example.com域内的主机进行认证 puppet cert --clean server4.example.com ##可以删除原client端的签名认证
3.puppet资源定义
(1)定义用户
在server端: vim /etc/puppet/manifests/site.pp file { '/tmp/testfile': content => 'www.westos.org', mode => 600, owner => puppet, group => puppet } /etc/init.d/puppetmaster reload 在client端: puppet agent --server server3.example.com --no-daemonize -vt 如图:
[root@server4 ~]# ll /tmp/testfile -rw------- 1 puppet puppet 14 7月 5 11:29 /tmp/testfile ##查看对testfile权限的修改是否生效 在server端: cd /etc/puppet/ mkdir files cp /etc/passwd files ##把passwd拷贝到files里用作检测 vim fileserver.conf [files] path /etc/puppet/files allow *.example.com /etc/init.d/puppetmaster reload vim /etc/puppet/manifests/site.pp file { '/tmp/testfile': content => 'www.westos.org', mode => 600, owner => puppet, group => puppet } file { '/tmp/passwd': source => 'puppet:///files/passwd' } 在client端: [root@server4 ~]# puppet agent --server server3.example.com --no-daemonize -vt Info: Retrieving pluginfacts Info: Retrieving plugin Info: Caching catalog for server4.example.com Info: Applying configuration version '1467815900' Notice: /Stage[main]/Main/File[/tmp/passwd]/ensure: defined content as '{md5}ee6c5e7a60a74d4a2e40825a7575d383' Notice: Finished catalog run in 0.20 seconds [root@server4 ~]# ll /tmp/testfile -rw------- 1 puppet puppet 14 7月 5 11:29 /tmp/testfile [root@server4 ~]# cat /tmp/testfile www.westos.org
(2)定义软件包
在server端:
vim /etc/puppet/manifests/site.pp file { '/tmp/testfile': content => 'www.westos.org', mode => 600, owner => puppet, group => puppet } file { '/tmp/passwd': source => 'puppet:///files/passwd' } package { 'httpd': ensure =>present } 在client端: [root@server4 ~]# puppet agent --server server3.example.com --no-daemonize -vt Info: Retrieving pluginfacts Info: Retrieving plugin Info: Caching catalog for server4.example.com Info: Applying configuration version '1467857897' Notice: /Stage[main]/Main/Package[httpd]/ensure: created Notice: Finished catalog run in 12.00 seconds
(3)定义服务
在server端:
vim /etc/puppet/manifests/site.pp file { '/tmp/testfile': content => 'www.westos.org', mode => 600, owner => puppet, group => puppet } file { '/tmp/passwd': source => 'puppet:///files/passwd' } package { 'httpd': ensure =>present } service { 'httpd': ensure => running, require => Package['httpd'] } 在client端:
如图:
(4)定义用户及用户组
在server端:
vim /etc/puppet/manifests/site.pp file { '/tmp/passwd': source => 'puppet:///files/passwd' } package { 'httpd': ensure =>present } service { 'httpd': ensure => running, require => Package['httpd'] } user { "test": uid => 900, home => "/home/test", shell => "/bin/bash", provider => useradd, managehome => true, ensure => present, #password => westos } exec { "echo westos | passwd --stdin test": path => "/usr/bin:/bin", onlyif => "id test" ##只有在用户ID存在时执行 } 在client端: 如图:
查看password,如图:
(5)文件系统挂载
在server端: vim /etc/puppet/manifests/site.pp package { ['httpd','nfs-utils']: ensure =>present } file { "/public": ensure => directory } mount { "/public": device => "172.25.254.251:/var/ftp/pub", fstype => "nfs", options => "defaults", ensure => mounted } 在client端: 如图:
(6)crontab任务
在server端: vim /etc/puppet/manifests/site.pp cron { echo: command => "/bin/echo `/bin/date` >> /tmp/echo", user => root, hour => ['2-4'], minute => '*/10' }
在client端:
如图:
cat /var/spool/cron/root
如图:
4.Puppet不同节点的定义
在server端:
cd /etc/puppet/manifests mkdir nodes ##创建不同节点 cp site.pp nodes/server4.pp vim site.pp import 'nodes/*.pp' file { '/tmp/testfile': content => 'www.westos.org', mode => 600, owner => puppet, group => puppet } vim server4.pp node 'server4.example.com' { package { 'httpd': ensure =>present } service { 'httpd': ensure => stopped, ##停掉sever4上的apache服务 require => Package['httpd'] } } vim server5.pp node 'server5.example.com' { package { 'httpd': ensure =>present } service { 'httpd': ensure => running, ##开启server5上的apache服务 require => Package['httpd'] } } 在client端: puppet agent --server server3.example.com --no-daemonize -vt ##server4 如图:
time puppet agent --server server3.example.com --no-daemonize -vt ##server5
如图:
5.编写模板
在server端:
cd /etc/puppet/modules/ mkdir vsftpd ##添加vsftp cd vsftpd/ mkdir files cd files/ yum install -y vsftpd cp /etc/vsftpd/vsftpd.conf . ##把vsftp的主配置文件拷贝到当前路径 chmod 644 vsftpd.conf ##修改主配置文件的权限 vim vsftpd.conf anonymous_enable=NO ##关闭匿名用户登录限制 cd /etc/puppet/modules/vsftpd/ mkdir manifests/ cd manifests/ touch install.pp config.pp service.pp init.pp vim install.pp class vsftpd::install { package { 'vsftpd': ensure => present } } vim config.pp class vsftpd::config { file { '/etc/vsftpd/vsftpd.conf': source => 'puppet:///modules/vsftpd/vsftpd.conf', ##资源调用的路径 mode => 600, require => Class['vsftpd::install'], notify => Class['vsftpd::service'] } } vim service.pp class vsftpd::service { service { 'vsftpd': ensure => running, require => Class['vsftpd::install','vsftpd::config'] } } vim init.pp class vsftpd { include vsftpd::install,vsftpd::config,vsftpd::service } cd /etc/puppet/manifests/nodes/ vim server4.pp node 'server4.example.com' { include vsftpd package { 'httpd': ensure =>present } service { 'httpd': ensure => stopped, require => Package['httpd'] } } vim server5.pp node 'server5.example.com' { include vsftpd package { 'httpd': ensure =>present } service { 'httpd': ensure => running, require => Package['httpd'] } } 在client端: puppet agent --server server3.example.com --no-daemonize -vt ##server4 如图:
time puppet agent --server server3.example.com --no-daemonize -vt ##server5
如图;
6.添加虚拟主机配置——模板应用
文件存放在 templates 目录中,以*.erb结尾。
在server端:
cd /etc/puppet/modules/ yum install -y httpd cp vsftpd/ -r httpd/ cd /etc/puppet/modules/httpd/files rm -rf * cp /etc/httpd/conf/httpd.conf . ##将http的主配置文件拷贝到当前路径 vim httpd.conf NameVirtualHost *:80 <VirtualHost *:80> DocumentRoot /var/www/html ServerName server4.example.com </VirtualHost> cd /etc/puppet/modules/httpd/manifests vim install.pp class httpd::install { package { 'httpd': ensure => present } } vim config.pp class httpd::config { file { '/etc/httpd/conf/httpd.conf': source => 'puppet:///modules/httpd/httpd.conf', mode => 600, require => Class['httpd::install'], notify => Class['httpd::service'] } } vim service.pp class httpd::service { service { 'httpd': ensure => running, require => Class['httpd::install','httpd::config'] } } vim init.pp class httpd { include httpd::install,httpd::config,httpd::service } define httpd::vhost($domainname) { file { "/etc/httpd/conf.d/${domainname}_vhost.conf": content => template("httpd/httpd_vhost.erb"), require => Class["httpd::install"], notify => Class["httpd::service"] } file { "/var/www/$domainname": ensure => directory } file { "/var/www/$domainname/index.html": content => $domainname } } cd /etc/puppet/manifests/nodes/ vim server5.pp node 'server5.example.com' { include vsftpd,httpd httpd::vhost { 'www.example.com': domainname => "www.example.com", } httpd::vhost { 'www.gaofang.com': domainname => "www.gaofang.com", } } cd /etc/puppet/modules/httpd mkdir templates vim /etc/puppet/modules/httpd/templates/httpd_vhost.erb <VirtualHost *:80> ServerName <%= domainname %> DocumentRoot /var/www/<%= domainname %> ErrorLog logs/<%= domainname %>_error.log CustomLog logs/<%= domainname %>_access.log common </VirtualHost> 在物理机上: vim /etc/hosts 172.25.44.55 server5.example.com www.example.com www.gaofang.com ##加入解析 在client端: puppet agent --server server3.example.com --no-daemonize -vt ##server5
如图:
cd /var/www/www.example.com/ [root@server5 www.example.com]# cat index.html www.example.com cd /var/www/www.gaofang.com/ [root@server5 www.gaofang.com]# cat index.html www.gaofang.com 登陆网页访问 如图: