本文主要针对puppet自动化技术基础详细解读,其中包括技术原理、配置解析、示例部署和服务认证等,内容针对企业准生产,适应性强,可即学即用。


 一 puppet原理介绍

    puppet是一种Linux、Unix平台的集中配置管理系统,使用ruby语言,可管理配置文件、用户、cron任务、软件包、系统服务等。puppet把这些系统实体称之为资源,puppet的设计目标是简化对这些资源的管理以及妥善处理资源间的依赖关系。

    1 puppet工作模式

    Puppet是一个C/S架构的配置管理工具,在中央服务器上安装puppet-server软件包(master)。在需要管理的目标主机上安装puppet客户端软件(Client)。当客户端连接上master后,定义在master上的配置文件会被编译,然后在客户端上运行。每个客户端默认每半个小时和服务器进行一次通信,确认配置信息的更新情况。如果有新的配置信息或者配置信息已经改变,配置将会被重新编译并发布到各客户端执行。也可以在服务器上主动触发一个配置信息的更新,强制各客户端进行配置。如果客户端的配置信息被改变了,它可以从服务器获得原始配置进行校正。

    2 puppet工作流程

                         wKiom1irnn_B-QIFAAB6VZi58HM511.jpg

    (1)客户端puppetd调用facter,facter探测出主机的一些变量,例如主机名,内存大小,ip地址等。pupppetd 把这些信息通过ssl连接发送到服务器端; 

    (2)服务器端的master 检测客户端的主机名,然后找到manifest里面对应的node配置, 并对该部分内容进行解析,facter送过来的信息可以作为变量处理,node牵涉到的代码才解析,其他没牵涉的代码不解析。解析分为几个阶段,语法检查,如果语法错误就报错。如果语法没错,就继续解析,解析的结果生成一个中间的“伪代码”,然后把伪代码发给客户端;

    (3)客户端接收到“伪代码”,并且执行,客户端把执行结果发送给服务器;

    (4)服务器端把客户端的执行结果写入日志。


二 puppet配置解读


主配置文件  /etc/puppet/puppet.conf

1) 配置文件命名空间:

    [main]通用配置选项

    [agent]客户端配置选项

    [master]服务端配置选项

2) main命名空间选项:

    confdir配置文件目录,默认在/etc/puppet

    vardir动态数据目录,默认在/var/lib/puppet

    logdir日志目录,默认在/var/log/log

    rundirpuppetPID目录,默认在/var/run/puppet

    statedirstate目录,默认在$vardir/state

    statefilestate文件,默认在$statedir/state.yaml

    ssldirSSL证书目录,默认在$vardir/ssl

    trace发生错误时显示跟踪信息,默认false

    filetimeout检测配置文件状态改变的时间周期,单位秒,默认15秒

    syslogfacility指定syslog功能为user级,默认为daemon级

3).master命名空间选项:

    user后台进程执行的用户

    group后台进程执行的组

    mainfestdirmainfests文件存储目录,默认为$confdir/mainfests

    mainfestmainfest站点文件的名字,默认为site.pp

    bindaddress后台进程绑定的网卡地址接口

    masterport后台进程执行的端口,默认为8140

4).puppet命名空间选项:

    serverpuppetpuppet服务器名,默认为puppet

    runintervalsecondspuppet应用配置的时间间隔,默认1800秒(0.5小时)

    puppetdlockfiefilepuppetlock文件位置,默认$statedir/puppetdlock

    puppetportport后台进程执行的端口,默认8139

    文件服务配置文件(fileserver.conf):

        [files]
        path /var/lib/puppet/files
        allow 192.168.1.*
        allow *.test.com
        deny *.example.com

        path定义文件存放路径,通过allow/deny来控制访问权限。


三 puppet安装配置


在安装Puppet之前是需要做很多预备工作的,比如网络地址、主机名、certname名、时间等。


1 安装前准备

    网络地址分配:

【HOSTNAME】                        【IP】                     【certname】            【operatingsystem】 

master.puppet.com        192.168.1.10/24     master_cert.puppet.com         RHEL6.7
agent1.puppet.com        192.168.1.11/24     agent1_cert.puppet.com         RHEL6.7
agent2.puppet.com        192.168.1.12/24     agent2_cert.puppet.com         RHEL6.8
agent3.puppet.com        192.168.1.13/24     agent3_cert.puppet.com         RHEL6.8

    修改hosts文件,vim /etc/hosts 添加以下内容

192.168.1.10     master.puppet.com      master
192.168.1.11     agent1.puppet.com      agent1
192.168.1.12     agent2.puppet.com      agent2
192.168.1.13     agent3.puppet.com      agent3


    设置主机名:

[root@master ~]# vim /etc/sysconfig/network
NETWORKING=yes
HOSTNAME=master.puppet.com


[root@agent1 ~]# vim /etc/sysconfig/network
NETWORKING=yes
HOSTNAME=agent1.puppet.com

agent2 agent3上也要修改


    修改ip地址:

[root@master ~]# vim /etc/sysconfig/network-scripts/ifcfg-eth0
DEVICE=eth0
TYPE=Ethernet
ONBOOT=yes
NM_CONTROLLED=yes
BOOTPROTO=static
IPADDR=192.168.1.10
NETMASK=255.255.255.0
GATEWAY=192.168.1.1
DNS1=8.8.8.8
IPV6INIT=no
USERCTL=no

agent端的三台机器也要对应修改


    关闭防火墙和selinux:

[root@master ~]# /etc/init.d/iptables stop

[root@master ~]# chkconfig iptables off

[root@master ~]# sed -i 's/SELINUX=.*/SELINUX=disabled/g' /etc/selinux/config


    设置key 公钥私钥,通过master端统一部署:

[root@master ~]# ssh-keygen     #生成公钥私钥

[root@master ~]# for i in {1..3}; do ssh-copy-id -i 192.168.1.1$i; done    #复制秘钥到agent


    设置时间同步:

    ntpdate -u 210.72.145.44        #同步授时中心时间


    配置yum源:

 wget http://yum.puppetlabs.com/el/6/products/x86_64/puppet-2.7.26-1.el6.noarch.rpm 

 wget http://yum.puppetlabs.com/el/6/products/x86_64/facter-1.7.6-1.el6.x86_64.rpm

 wget http://yum.puppetlabs.com/el/6/products/x86_64/puppet-server-2.7.26-1.el6.noarch.rpm

 wget http://yum.puppetlabs.com/el/6/products/x86_64/puppetlabs-release-6-7.noarch.rpm


2 安装与配置


安装master

[root@master ~]# yum install puppet puppet-server facter -y 

 配置puppet.conf 注意:这个里面配置了两个certname名称,其中[master]中配置的certname是为所有节点认证用的master名称,[agent]中配置的certname是他本身agent的名称,当然不配置默认是和master的名称一样

[root@master ~]# cp /etc/puppet/puppet.conf{,.bak}   #备份

[root@master ~]# vim /etc/puppet/puppet.conf  #注释已经删除

[main]
       logdir = /var/log/puppet          #默认日志存放路径
       rundir = /var/run/puppet          #pid存放路径
       ssldir = $vardir/ssl                     #证书存放目录,默认$vardir为/var/lib/puppet
[agent]
       classfile = $vardir/classes.txt
       localconfig = $vardir/localconfig
       server = master.puppet.com         #设置认证名称,注意这个名字必须能够被节点解析
       certname = master_cert.puppet.com         #设置agent端certname名称
[master]
       certname = master.puppet.com  master.puppet.com         #设置master认证服务器名

创建site.pp文件 site.pp文件是puppet读取所有模块pp文件的开始,在3.0版本以前必须设置,否则服务无法启动。

[root@master ~]# touch /etc/puppet/manifests/site.pp


启动master服务

[root@master ~]# /etc/init.d/master start

Starting master:       [  OK  ]

[root@master ~]# chkconfig master on #设置开机启动


查看本地证书情况 master第一次启动会自动生成证书自动注册自己

[root@master ~]# tree /var/lib/puppet/ssl/
/var/lib/puppet/ssl/
├── ca
│   ├── ca_crl.pem
│   ├── ca_crt.pem
│   ├── ca_key.pem
│   ├── ca_pub.pem
│   ├── inventory.txt
│   ├── private
│   │   └── ca.pass
│   ├── requests
│   ├── serial
│   └── signed
│       └── master.puppet.com.pem  #已注册

├── certificate_requests
├── certs
│   ├── ca.pem
│   └── master.puppet.com.pem
├── crl.pem
├── private
├── private_keys
│   └── master.puppet.com.pem
└── public_keys
   └── master.puppet.com.pem

[root@master ~]# puppet cert --list --all  #带+标示已经注册成功

+ "master.puppet.com" (C0:E3:68:76:36:2C:92:93:5D:BF:80:8F:77:G0:91:C8) (alt names: "DNS:puppet", "DNS:puppet.puppet.com", "DNS:master.puppet.com")


查看监听状态 master服务开启后,默认监听TCP 8140端口

[root@master ~]# netstat -nlatp | grep 8140
tcp        0      0 0.0.0.0:8140                0.0.0.0:*                   LISTEN      1926/ruby          
[root@master ~]# lsof -i:8140
COMMAND    PID   USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
master 1926 puppet    2u  IPv4  12531      0t0  TCP *:8140 (LISTEN)


安装agent端


安装puppet和facter

[root@agent1 ~]# yum install puppet facter -y


配置puppet.conf

[root@agent1 ~]# cp /etc/puppet/puppet.conf{,.bak}
[root@agent1 ~]# vim /etc/puppet/puppet.conf
[main]
   logdir = /var/log/puppet
   rundir = /var/run/puppet
   ssldir = $vardir/ssl
[agent]
   classfile = $vardir/classes.txt
   localconfig = $vardir/localconfig
   server = master.puppet.com   #指向master端
   certname = agent1_cert.puppet.com  #设置自己的certname名


通过测试模式向master端发起认证

[root@agent1 ~]# puppet agent --test

[root@master ~]# puppet cert --list --all             #master端查看认证情况

[root@master ~]# puppet cert --sign agent1_cert.puppet.com #认证注册agent1

[root@master ~]# puppet cert --list --all             #查看认证情况

+ "agent1_cert.puppet.com"  (3E:46:4E:75:34:9A:5A:62:A6:3C:AE:BD:49:EE:C0:F5)
+ "master.puppet.com" (C0:E3:6B:76:36:EC:92:93:4D:BF:F0:8F:77:00:91:C8)

[root@master ~]# tree /var/lib/puppet/ssl/         #查看认证文件的方式


四 编写简单的test模块


1 创建模块目录结构

[root@master ~]# puppet master --genconfig >/etc/puppet/puppet.conf.out

[root@master ~]# cat /etc/puppet/puppet.conf.out | grep modulepath

   modulepath = /etc/puppet/modules:/usr/share/puppet/modules

[root@master modules]# mkdir test

[root@master modules]# cd test

[root@master modules]# mkdir files manifests templates     #创建模块目录结构

tree /etc/puppet/modules/test

/etc/puppet/modules/test
   ├── files              #存放文件目录
   │   └── etc
   │       └── test
   ├── manifests     #存放模块pp配置文件目录
   │   └── init.pp
   └── templates     #存放模板目录


2 编写init.pp文件

[root@master modules]# vim motd/manifests/init.pp
class test{                       #定义一个类叫test
   package{ 'setup':        #定义package资源
   ensure => present,    #要求setup这个包处于被安装状态
 }
 file{ '/etc/test':          #定义file资源
   ensure  => present,  #要求file文件处于存在状态
   owner   => 'root',     #要求file文件属主为root
   group   => 'root',     #要求file文件属组为root
   mode    => '0644',   #要求file文件权限为644
   source  => "puppet://$puppetserver/modules/motd/etc/test", #file文件从master端服务器下载
   require => Package['setup'], #要求文件被配置之前先执行package资源
 }
}


3  编写site.pp文件

[root@master ~]# vim /etc/puppet/manifests/site.pp
$puppetserver = 'master.puppet.com' #设置全局变量
node 'master_cert.puppet.com'{
 include  test
}
node 'agent1_cert.puppet.com'{
 include  test
}
node 'agent2_cert.puppet.com'{
 include  test
}
node 'agent3_cert.puppet.com'{
 include  test
}


4 节点测试

[root@agent1 ~]# puppet agent --test                   #测试节点agent1

[root@master ~]# puppet agent -t              #测试节点puppetmaster

测试节点查看是否成功分发etc下的test文件


五 常见错误情况及解决办法


1.  连接master的时候出现如下报错:

dnsdomainname: Unknown host

解决办法:检查机器主机名的设置,以及是否添加进hosts。

2.   连接master的时候出现如下报错:

err: Could not request certificate: getaddrinfo: Name or service not known

解决办法:服务器端没有配置hosts域名绑定,在hosts中添加。

3.  连接master的时候出现如下报错:

warning: peer certificate won't be verified in this SSL session

解决办法:服务端还没有返回签发证书,使用puppet cert --list查看

4.  连接master的时候出现如下报错:

err: Could not retrieve catalog from remote server: certificate verify failed

解决办法:客户端和服务器端时间不同步,用ntpdate命令同步时间