Puppet 自动化运维

1、Puppet 简介

Puppet,原意木偶的意思

puppet 是一个为实现数据中心自动化管理而设计的配置管理软件。

puppet 的服务器端保存着所有对客户端服务器的配置代码,在 puppet 里面叫做 manifest(清单)。 manifest(清单)存放在 puppetmaster 服务端。 puppet 客户端下载 manifest 之后,可以根据manifest 对客户端服务器进行配置,例如软件包管理,用户管理和文件管理等等。

官方网站: http://puppetlabs.com/

pupptet下载链接:http://downloads.puppetlabs.com/puppet/

Puppet的社区版是免费开源版本:

image-20191118165337048

2.1 Puppet 工作原理

星状:

img

树状:

image-20191118165520035

2.2 Puppet的工作流程

image-20191118165617421

  1. 客户端puppetd调用facter (facter是能过要SSL加密收集及检测分析客户配置信息的一个 工具,,facter探测出主机的一些变量,例如主机名,内存大小,ip地址等。pupppetd 把这些信息通过ssl连接发送到服务器端puppetmaster;

  2. 服务器端的puppetmaster 检测客户端的主机名,然后找到manifest里面对应主机的配置,并对该部分内容进行解析,让对应的客户端执行。

    • 语法检查,如果语法错误就报错。

    • 如果语法没错,就继续解析,解析的结果生成一个中间的“伪代码”,即 catalog 日志,然后把伪代码发给客户端;

  3. 客户端接收到“catalog”日志,并且执行,客户端把执行结果发送给服务器;

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

  1. 客户端,通过factar,探测一些信息

  2. master,检测探测到的信息,对对应的主机,到master的清单里面解析,为了让对应的客户端执行

  3. 如果错误,马上报错,如果没错,生成伪代码

  4. 伪代码发送给客户端

  5. 客户但执行,结果进入日志

Puppet工作过程中有以下两点值得注意

典型的 Puppet 架构为星型结构,Clients 默认每 30 分钟请求一次 Server 端,确认是否有新的变更操作指令。

  1. 为了保证安全,Client和Master之间是基于SSL和证书的,只有经过Master证书的Client可以与Master通信。

  2. puppet会让系统保持在人们所期望的某种状态一直维持下去,如检测某个文件并保证一直存在,保证ssh服务始终开启,如果文件被删除了或者ssh服务被关闭了,puppet下次执行时(默认30分钟),会重新创建该文件或者启动ssh服务。

Puppet 工作模式和端口

服务的对象,都是Server

C/S模式 8140端口

facter-1.6.7.tar 探测服务器上一些信息,http://downloads.puppetlabs.com/

puppet-2.7.3.tar puppet这个软件包,包括了puppetmaster服务器软件和puppetd客户端。

2、部署Puppet并实现自动化

环境说明:

主机操作系统IP地址主要软件
puppetmasterCentOS 6.5 x86_64192.168.1.131ruby-rdoc-1.8.7.352-13.e16.x86_64ruby-libs-1.8.7.352-13.e16.x86_64ruby-irb-1.8.7.352-13.e16.x86_64ruby-1.8.7.352-13.e16.x86_64puppet-2.7.21.tar.gzfacter-1.7.1.tar.gz
Puppetclient01CentOS 6.5 x86_64192.168.1.132ruby-rdoc-1.8.7.352-13.e16.x86_64ruby-libs-1.8.7.352-13.e16.x86_64ruby-irb-1.8.7.352-13.e16.x86_64ruby-1.8.7.352-13.e16.x86_64puppet-2.7.21.tar.gzfacter-1.7.1.tar.gz
Puppetclient01CentOS 6.5 x86_64192.168.1.137ruby-rdoc-1.8.7.352-13.e16.x86_64ruby-libs-1.8.7.352-13.e16.x86_64ruby-irb-1.8.7.352-13.e16.x86_64ruby-1.8.7.352-13.e16.x86_64puppet-2.7.21.tar.gzfacter-1.7.1.tar.gz
NTP ServerCentOS 6.5 x86_64192.168.1.200

准备工作:

基于 ruby 脚本写的,安装 ruby 开发环境。
Puppet 要求所有机器有完整的域名(FQDN)。
配好: 主机名 保持服务器时间同步。
关闭 iptables 和 selinux

2.1 部署puppetmaster

2.1.1 规划服务器主机名

1
2
3
[root@centos1 ~]# vim /etc/sysconfig/network
NETWORKING=yes
HOSTNAME=centos1.benet.com

2.1.2 添加本地主机名解析

1
2
3
4
5
6
[root@centos1 ~]# vim /etc/hosts
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
192.168.1.131 centos1.benet.com
192.168.1.132 centos2.benet.com
192.168.1.137 centos3.benet.com

2.1.3 配置本机为NTP服务器

1
2
3
4
5
6
[root@centos2 ~]# yum -y install ntp
[root@centos1 ~]# vim /etc/ntp.conf
server 127.127.1.0
fudge 127.127.1.0 stratum 8
[root@centos1 ~]# service ntpd start
Starting ntpd:

2.1.4 安装依赖包和ruby,并检查ruby版本

1
2
3
[root@centos1 ~]# yum -y install openssl openssl-devel ruby
[root@centos1 ~]# ruby -v
ruby 1.8.7 (2011-06-30 patchlevel 352) [x86_64-linux]

2.1.5 安装facter

(通过pacter工具分析检测客户端传输过来的信息)

1
2
3
[root@centos1 ~]# tar xf facter-1.7.1.tar.gz 
[root@centos1 ~]# cd facter-1.7.1
[root@centos1 facter-1.7.1]# ruby install.rb

2.1.6 安装puppet

1
2
3
4
[root@centos1 ~]# useradd -s /sbin/nologin puppet
[root@centos1 ~]# tar xf puppet-2.7.21.tar.gz
[root@centos1 ~]# cd puppet-2.7.21
[root@centos1 puppet-2.7.21]# ruby install.rb

复制相关配置文件

1
2
3
4
[root@centos1 puppet-2.7.21]# cp conf/redhat/fileserver.conf /etc/puppet/
[root@centos1 puppet-2.7.21]# cp conf/redhat/puppet.conf /etc/puppet/
[root@centos1 puppet-2.7.21]# cp conf/redhat/server.init /etc/init.d/puppetmaster
[root@centos1 puppet-2.7.21]# chmod +x /etc/init.d/puppetmaster

创建puppet清单目录,模块目录

1
2
[root@centos1 puppet-2.7.21]# mkdir /etc/puppet/manifests
[root@centos1 puppet-2.7.21]# mkdir /etc/puppet/modules

2.1.7 puppet服务证书请求与签名

生产环境中iptables默认是全部关闭的
master端配置:

1
2
3
4
[root@centos1 puppet-2.7.21]# service iptables stop
iptables: Setting chains to policy ACCEPT: filter [ OK ]
iptables: Flushing firewall rules: [ OK ]
iptables: Unloading modules: [ OK ]

修改配置文件(添加红色部分)
在[main]标题下添加:

1
[root@centos1 puppet-2.7.21]# vim /etc/puppet/puppet.conf

[main]
#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
modulepath = /etc/puppet/modules:/usr/share/puppet/modules

启动puppet主程序

1
2
[root@centos1 puppet-2.7.21]# /etc/init.d/puppetmaster start
Starting puppetmaster: [ OK ]

2.2 部署puppetclient01,02

2.2.1 规划服务器主机名

1
2
3
[root@centos2 ~]# vim /etc/sysconfig/network
NETWORKING=yes
HOSTNAME=centos2.benet.com

2.2.2 添加本地主机名解析

(确保可以ping通centos1.benet.com, centos2.benet.com, centos3.benet.com)

1
2
3
4
5
6
[root@centos2 ~]# vim /etc/hosts
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
192.168.1.131 centos1.benet.com
192.168.1.132 centos2.benet.com
192.168.1.137 centos3.benet.com

2.2.3 服务器时间同步

1
2
3
[root@centos2 ~]# yum -y install ntp
[root@centos2 ~]# ntpdate 192.168.1.131
29 Oct 11:32:41 ntpdate[44049]: step time server 192.168.1.131 offset 1.662984 sec

2.2.4 安装ruby,并检查ruby版本

1
2
3
[root@centos2 ~]# yum -y install openssl openssl-devel ruby
[root@centos2 ~]# ruby -v
ruby 1.8.7 (2011-06-30 patchlevel 352) [x86_64-linux]

2.2.5 安装facter

1
2
3
[root@centos2 ~]# tar xf facter-1.7.1.tar.gz 
[root@centos2 ~]# cd facter-1.7.1
[root@centos2 facter-1.7.1]# ruby install.rb

2.2.6 安装puppet

1
2
3
4
[root@centos2 ~]# useradd -s /sbin/nologin puppet
[root@centos2 ~]# tar xf puppet-2.7.21.tar.gz
[root@centos2 ~]# cd puppet-2.7.21
[root@centos2 puppet-2.7.21]# ruby install.rb

复制相关配置文件

1
2
3
[root@centos2 puppet-2.7.21]# cp conf/redhat/puppet.conf /etc/puppet/
[root@centos2 puppet-2.7.21]# cp conf/redhat/client.init /etc/init.d/puppetclient
[root@centos2 puppet-2.7.21]# chmod +x /etc/init.d/puppetclient

2.2.7 puppet服务证书与签名

生产环境中iptables默认是全部关闭的

1
2
3
4
[root@centos2 puppet-2.7.21]# service iptables stop
iptables: Setting chains to policy ACCEPT: filter [ OK ]
iptables: Flushing firewall rules: [ OK ]
iptables: Unloading modules: [ OK ]

修改client配置文件(添加红色部分,为puppetmaster主机名)
在[main]标题下添加以下一行:

1
[root@centos2 puppet-2.7.21]# vim /etc/puppet/puppet.conf

[main]
#The Puppet log directory.

#The default value is ‘$vardir/log’.

[main]
#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
<font color=red>server = centos1.benet.com</font>          //puppetmaster主机名

分别在puppetclient01和puppetclient01上进行注册(出现如下信息即可按ctrl+c停止)

1
2
3
4
5
6
7
8
9
[root@centos2 puppet-2.7.21]# puppet agent --server=centos1.benet.com --no-daemonize --verbose
info: Caching certificate for ca
info: Creating a new SSL certificate request for centos2.benet.com
info: Certificate Request fingerprint (md5): 64:25:F9:40:EE:6B:92:18:A1:27:63:95:6C:56:3A:DC
[root@centos3 puppet-2.7.21]# puppet agent --server=centos1.benet.com --no-daemonize --verbose
info: Creating a new SSL key for centos3.benet.com
info: Caching certificate for ca
info: Creating a new SSL certificate request for centos3.benet.com
info: Certificate Request fingerprint (md5): 57:12:6D:F1:79:0F:00:2A:EB:A3:AA:2F:11:E6:05:52

2.2.8 在puppetmaster服务器上查看申请注册的客户端

查看申请注册的客户端

1
2
3
[root@centos1 ~]# puppet cert --list
"centos2.benet.com" (64:25:F9:40:EE:6B:92:18:A1:27:63:95:6C:56:3A:DC)
"centos3.benet.com" (57:12:6D:F1:79:0F:00:2A:EB:A3:AA:2F:11:E6:05:52)

将未注册的客户端进行注册

1
2
3
4
5
[root@centos1 ~]# puppet cert sign --all
notice: Signed certificate request for centos2.benet.com
notice: Removing file Puppet::SSL::CertificateRequest centos2.benet.com at '/var/lib/puppet/ssl/ca/requests/centos2.benet.com.pem'
notice: Signed certificate request for centos3.benet.com
notice: Removing file Puppet::SSL::CertificateRequest centos3.benet.com at '/var/lib/puppet/ssl/ca/requests/centos3.benet.com.pem'

可以通过目录去查看已经注册的客户端

1
2
3
4
5
[root@centos1 ~]# ll /var/lib/puppet/ssl/ca/signed/
total 12
-rw-r----- 1 puppet puppet 1992 Oct 29 11:00 centos1.benet.com.pem
-rw-r----- 1 puppet puppet 1915 Oct 29 11:52 centos2.benet.com.pem
-rw-r----- 1 puppet puppet 1915 Oct 29 11:52 centos3.benet.com.pem

2.3 配置实例(Master端配置SSH)

2.3.1 配置一个测试节点:

  • 节点信息:/etc/puppet/manifests/nodes
  • 模块信息:/etc/puppet/modules

为了保护Linux的ssh端口爆破,批量修改客户端sshd端口,将端口22修改为9922,并实现生词工作。
创建ssh模块,模块目录为ssh,模块下面有三个文件:manifests、templates、和files。
Manisests里面必须要包含一个init.pp的文件,这该模块的初始(入口)文件,导入一个模块的时候,会从init.pp开始执行。可以把所有的代码都写到init.pp里面,也可以分成多个pp文件,init再去包含其他文件,定义class类名的时候必须是ssh,这样能实现调用。
Files目录是该模块的文件发布目录,puppet提供一个文件分发机制,类似rsync的模块。
Templates目录包含erb模型文件,这个和file资源的template属性有关(很少用)。

创建需要的必要目录

1
2
3
4
[root@centos1 ~]# mkdir -p /etc/puppet/modules/ssh/{manifests,templates,files}
[root@centos1 ~]# mkdir /etc/puppet/modules/ssh/files/ssh
[root@centos1 ~]# mkdir /etc/puppet/manifests/nodes
[root@centos1 ~]# chown -R puppet /etc/puppet/modules/

此时/etc/puppet/modules/ssh/目录下结构

1
2
3
4
5
[root@centos1 ~]# ll /etc/puppet/modules/ssh/
total 12
drwxr-xr-x 3 puppet root 4096 Oct 29 11:57 files
drwxr-xr-x 2 puppet root 4096 Oct 29 11:56 manifests
drwxr-xr-x 2 puppet root 4096 Oct 29 11:56 templates

创建模块配置文件install.pp

1
2
3
4
5
6
[root@centos1 ~]# vim /etc/puppet/modules/ssh/manifests/install.php
class ssh::install{
package{ "openssh":
ensure => present,
}
}

创建模块配置文件config.pp

1
2
3
4
5
6
7
8
9
10
11
12
[root@centos1 ~]# vim /etc/puppet/modules/ssh/manifests/config.php
class ssh::config{
file { "/etc/ssh/sshd_config": //配置客户端同步的文件
ensure => present, //确定客户端此文件存在
owner => "root", //文件所属用户
group => "root", //文件所属组
mode => "0600", //文件权限
source => "puppet://$puppetserver/modules/ssh/ssh/sshd_config", //从服务器端目录同步文件
require => Class["ssh::install"], //调用install.pp确定ssh已经安装
notify => Class["ssh::service"], //如果config.pp发生变化通知service.pp
}
}

创建模块配置文件service.pp

1
2
3
4
5
6
7
8
9
10
[root@centos1 ~]# vim /etc/puppet/modules/ssh/manifests/service.pp
class ssh::service {
service {"sshd":
ensure => running, //确定ssh运行
hasstatus => true, //puppet该服务支持status命令,即类似service sshd status
hasrestart => true, //puppet该服务支持restart命令,即类似service sshd restart
enable => true, //服务器是否开机启动
require => Class["ssh::config"] //确认config.pp调用
}
}

创建模块主配置文件init.pp
将以上配置文件加载进去,输入以下信息:

1
2
3
4
[root@centos1 ~]# vim /etc/puppet/modules/ssh/manifests/init.pp
class ssh{
include ssh::install,ssh::config,ssh::service //引用前面定义的几种类
}

此时/etc/puppet/modules/ssh/manifests/目录下有四个文件

1
2
3
4
5
6
[root@centos1 ~]# ll /etc/puppet/modules/ssh/manifests/
total 16
-rw-r--r-- 1 root root 270 Oct 29 12:03 config.php
-rw-r--r-- 1 root root 60 Oct 29 12:07 init.pp
-rw-r--r-- 1 root root 65 Oct 29 12:00 install.php
-rw-r--r-- 1 root root 160 Oct 29 12:06 service.pp

建立服务器端,ssh统一维护文件
由于服务器和客户端的sshd_config文件默认一样,此时将服务器端/etc/ssh/sshd_config复制互模块默认路径。

1
2
[root@centos1 ~]# cp /etc/ssh/sshd_config /etc/puppet/modules/ssh/files/ssh/
[root@centos1 ~]# chown puppet /etc/puppet/modules/ssh/files/ssh/sshd_config

创建测试节点配置文件,并将ssh加载进去

1
2
3
4
5
6
7
[root@centos1 ~]# vim /etc/puppet/manifests/nodes/ssh.pp
node 'centos2.benet.com'{ //puppetclient主机名
include ssh
}
node 'centos3.benet.com'{
include ssh
}

将测试仪节点载入puppet,即修改site.pp

1
2
[root@centos1 ~]# vim /etc/puppet/manifests/site.pp
import "nodes/ssh.pp"

修改服务器端编护的sshd_config配置文件

1
[root@centos1 ~]# vim /etc/puppet/modules/ssh/files/ssh/sshd_config

#Port 22
Port 9922
#AddressFamily any
#ListenAddress 0.0.0.0
#ListenAddress

重新启动puppet

1
2
3
[root@centos1 ~]# /etc/init.d/puppetmaster restart
Stopping puppetmaster: [ OK ]
Starting puppetmaster: [ OK ]

2.3.2 测试客户端主动拉取(Client01)

一般在小规模自动化集群中,如代码上线需要重启服务时,为了防止网站暂时性无法访问的问题,每台客户端运行一次puppet agent -t命令,选择模式根据客户端集群规模的大小,根据经验,一般运维工程师puppet服务器到各客户端会建立ssh信任,然后自定义shell脚本,ssh批量让客户端执行puppet同步命令。

Client02 192.168.1.132上执行命令如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
[root@centos2 puppet-2.7.21]# puppet agent -t
info: Caching catalog for centos3.benet.com
info: Applying configuration version '1477808911'
notice: /Stage[main]/Ssh::Config/File[/etc/ssh/sshd_config]/content:
--- /etc/ssh/sshd_config 2013-11-23 06:40:03.000000000 +0800
+++ /tmp/puppet-file20161030-43464-10v2v8r-0 2016-10-30 14:28:32.726572780 +0800
@@ -11,6 +11,7 @@
# default value.

#Port 22
+Port 9922
#AddressFamily any
#ListenAddress 0.0.0.0
#ListenAddress ::

info: FileBucket adding {md5}53ad75eb1f2269d23f6e4228353cbca3
info: /Stage[main]/Ssh::Config/File[/etc/ssh/sshd_config]: Filebucketed /etc/ssh/sshd_config to puppet with sum 53ad75eb1f2269d23f6e4228353cbca3
notice: /Stage[main]/Ssh::Config/File[/etc/ssh/sshd_config]/content: content changed '{md5}53ad75eb1f2269d23f6e4228353cbca3' to '{md5}3a2dee85056976947f1c154af9a0bf35'
info: /Stage[main]/Ssh::Config/File[/etc/ssh/sshd_config]: Scheduling refresh of Class[Ssh::Service]
info: Class[Ssh::Service]: Scheduling refresh of Service[sshd]
notice: /Stage[main]/Ssh::Service/Service[sshd]: Triggered 'refresh' from 1 events
info: Creating state file /var/lib/puppet/state/state.yaml
notice: Finished catalog run in 0.57 seconds

此时在Client端已经执行成功,验证如下

1
[root@centos2 ~]# vim /etc /ssh/sshd_config

#Port 22
Port 9922
#AddressFamily any
#ListenAddress 0.0.0.0
#ListenAddress

查看服务器ssh服务是否重启,端口是否生效

1
[root@centos2 puppet-2.7.21]# ss -anpt | grep ssh

LISTEN 0 128 127.0.0.1:6010 : users:((“sshd”,2109,8))
LISTEN 0 128 ::1:6010 :::* users:((“sshd”,2109,7))
LISTEN 0 128 :::9922 :::* users:((“sshd”,43765,4))
LISTEN 0 128 *:9922 : users:((“sshd”,43765,3))
ESTAB 0 52 192.168.1.132:22 192.168.1.20:53059 users:((“sshd”,2109,3))

2.3.3 测试服务器推送同步

(当大规模部署时采用服务器推送模式)

Client端配置:192.168.1.133上配置如下:
修改配置文件(最后一行添加)

1
2
3
4
[root@centos3 puppet-2.7.21]# vim /etc/puppet/puppet.conf
listen = true //使puppet监听8139端口
[root@centos3 puppet-2.7.21]# vim /etc/puppet/auth.conf
allow * //验证配置文件auth.conf定义一些验证信息及访问权限

启动puppet客户端

1
2
[root@centos3 puppet-2.7.21]# /etc/init.d/puppetclient start
Starting puppet: [ OK ]

确认ssh服务端口

1
[root@centos3 puppet-2.7.21]# ss -anpt | grep ssh

LISTEN 0 128 :::22 :::* users:((“sshd”,43870,4))
LISTEN 0 128 *:22 : users:((“sshd”,43870,3))
LISTEN 0 128 127.0.0.1:6010 : users:((“sshd”,2109,8))
LISTEN 0 128 ::1:6010 :::* users:((“sshd”,2109,7))
ESTAB 0 0 192.168.1.133:22 192.168.1.20:53059 users:((“sshd”,2109,3))

Master端:
开始住客户端推送

1
2
3
4
5
6
[root@centos1 ~]# puppet kick centos3.benet.com
Triggering centos3.benet.com
Getting status
status is success
centos3.benet.com finished with exit code 0
Finished

在客户端上检验结果

1
[root@centos3 puppet-2.7.21]# ss -anpt | grep ssh

LISTEN 0 128 127.0.0.1:6010 : users:((“sshd”,2109,8))
LISTEN 0 128 ::1:6010 :::* users:((“sshd”,2109,7))
LISTEN 0 128 :::9922 :::* users:((“sshd”,44683,4))
LISTEN 0 128 *:9922 : users:((“sshd”,44683,3))
ESTAB 0 52 192.168.1.133:22 192.168.1.20:53059 users:((“sshd”,2109,3))

2.4 puppet的使用方法帮助文档:

file资源:http://puppet.wikidot.com/file
package资源:http://puppet.wikidot.com/package
service 资源: http://puppet.wikidot.com/srv
exec 资源:http://puppet.wikidot.com/exec
cron 资源:http://puppet.wikidot.com/cron
注意:如果时区问题:cp /usr/share/zoneinfo/Asia/shanghai /etc/localtime

-------------本文结束感谢您的阅读-------------