共计 12515 个字符,预计需要花费 32 分钟才能阅读完成。
一、简介
当服务器数量达到一定的规模时,仅依靠人为完成批量部署服务器个资源的配置,运维工作将变得繁琐且容易出错,为了解决这一问题,我们应该怎么办呢?我们可以引入一批工具,这批工具可编写相应的 manifests 代码,运行它便可以自动完成所有的工作,目前比较流行的运维工具主要有:puppet,ansible,slackstack 等,在这我们主要以 puppet 来展开话题。在一些大型互联网企业中,运维自动化管理着几百甚至上千台服务器,它可以针对多台服务器进行统一操作,例如部署统一软件、进行统一上线维护等,而且能够快速完成上线部署,减少人力及人力误操作风险。
二、Puppet 的工作原理
puppet 的目的是让系统管理员只集中于要管理的目标服务器,而忽略实现的细节。puppet 既可以在单机上使用,也可以 C / S 结构使用,在大规模部署 puppet 的情况下,通常我们会使用 C / S 结构,在这种结构下,服务端运行 puppet-master 程序客户端运行 puppet-client 服务程序
具体的工作流程图如下所示:
对于 puppet 的的掌握,理解 puppet 的工作原理是一个必要的的阶段,只有在了解了 puppet 的工作原理后才能更好应用 puppet,下面让我们一起了解学习 puppet 的工作原理:
说到 puppet 的工作原理,不得不从以下四个方面来说到,如下所示:
(1)定义:使用 Puppet 特定的语言定义基础配置信息。通常我们把这些信息写在 Modules 中。
(2)模板:在配置执行之前检测代码,但并不真正执行。
(3)执行:定义的配置自动部署。检测并记录下所发生变化的部分。
(4)报告:将期待的变化、实际发生的变化及任何修改发送给报告系统。
如下所示为 puppet 的工作数据流示意图
数据流说明:
1. 首先所有的节点(Node)Node 节点将 Facts 和本机信息发送给 Master
2.Master 告诉 Node 节点应该如何配置,将这些信息写入 Catalog 后传给 Node。
3.Node 节点在本机进行代码解析验证并执行,将结果反馈给 Master。
4.Master 通过 API 将数据发给分析工具。报告完全可以通过开放 API 或与其他系统集成。
整个数据流的走向是基于 SSL 安全协议的,如下图所示:
模板文件处理过程说明如下:
Puppet 通过编译 Manifest 中的内容 (即模板中内容),将编译好的代码存入 Catalog。在执行前先进行代码的验证,再执行,完成最开始所定义好的状态。代码编译过程如图所示:
如下所示为整个 puppet 自动部署过程中 agent 和 master 的详细的交互过程:
过程说明:
1. Puppet 客户端 Agent 将节点名与 facts 信息发送给 Master。
2. Puppet 服务端 Master 通过分类判断请求的客户端是谁,它将要做什么。这个判断是通过 site.pp 中包含的 Node.pp 配置文件定义的。
3. Puppet 服务端 Master 将所需要的 Class 类信息进行编译后存入 Catalog 并发送给 Puppet 客户端 Agent,到此完成第一次交互。
4. Puppet 客户端 Agent 对 Catalog 进行代码验证(语法检查及错误检查)并执行。主要是代码的验证,并将执行过程的信息及结果写入日志。
5. Puppet 客户端 Agent 最终达到最开始所定义的状态,并且将结果及任何执行数据通过开放 API 的形式发送给 Puppet 服务端 Master。
以上就是 puppet 的工作原理需要注意是: 因为整个过程中都是基于 ssl 实现的,所以首要的是保证 agent 和 master 间可以基于 ssl 通讯!
三、puppet 常用资源及配置实例
实例一:创建 CentOS 用户为普通用户,且 uid 为 4000,gid 为 3000,所属组为 centos,附加组为 mygrp
user{‘centos’:
name => ‘centos’, #定义用户名
ensure => present, #创建用户
uid => 4000, #定用户 id
groups => ‘mygrp’, #定义其他附加组
require => Group[‘mygrp’] #此资源依赖于事先创建 mygrps 组
}
group {‘mygrp’:
name => ‘mygrp’,# 定义组名
ensure => present, #创建组,与此相反的是 absent,删除组
gid => ‘3000’, #组 id
system => false, #是否为系统组,默认为 false
}
总结:
user 常用属性:
name:用户名,uid: 用户 id,gid: 组 id,groups: 附加组,comment:注释信息
expiry: 过期时间,home:家目录,shell:默认的 shell 类型,system:是否为系统组,
ensure:创建或删除用户即 present、absent,password:加密后的密码
group 常用属性:
ensure:创建或删除组即 present、absent,name: 组 id,system:是否为系统组等
[root@node1 manifets]# puppet apply -v user.pp #将此 manifests 清单编译为伪代码 catalog,并执行,且返回执行结果至此单机模式的主机上
Notice: Compiled catalog for node1.alren.com in environment production in 0.55 seconds
Info: Applying configuration version ‘1480561275’
Notice: /Stage[main]/Main/Group[mygrp]/ensure: created
Notice: /Stage[main]/Main/User[centos]/ensure: created
Notice: Finished catalog run in 0.11 seconds
[root@node1 manifets]# id centos
uid=4000(centos) gid=4000(centos) groups=4000(centos),3000(mygrp)
[root@node1 manifets]# vi user.pp
[root@node1 manifets]# puppet apply -v user.pp
Notice: Compiled catalog for node1.alren.com in environment production in 0.58 seconds
Info: Applying configuration version ‘1480561376’
Notice: /Stage[main]/Main/Group[mygrp]/ensure: removed
Notice: /Stage[main]/Main/User[centos]/ensure: removed
Notice: Finished catalog run in 0.13 seconds
[root@node1 manifets]# id centos
id: centos: no such user
[root@node1 manifets]#
实例二:此 manifests 代码为安装 httpd 包,为其提供配置文件,并且启动服务
service{‘httpd’:
ensure => running,
enable => true,
restart => ‘systemctl restart httpd.service’,
require => Package[‘httpd’],
}
package{‘httpd’:
ensure => installed,
}
file{‘httpd.conf’:
path => ‘/etc/httpd/conf/httpd.conf’,
source => ‘/root/manifests/httpd.conf’,
ensure => file,
notify => Service[‘httpd’],
before => Service[‘httpd’],
}
package 常用属性:
ensure:installed,present,latest,absent name: 包名
source:程序包来源,仅对不会自动下载的相关程序包的 provider 有用,例如 rpm 或 dpkg
servicec 常用属性:
ensure:running,stopped 运行停止 enable:开机是否启动 restart:重启命令
require:被依赖于事先安装程序包,
file 常用属性:
path: 文件需放置的位置所在处 source:源文件在哪 ensure:file,present,absent,directory,link…
file 指的是普通文件,link 为连接文件,此需结合 target 一起使用 directory:类型为目录,可通过 source 指向的路径复制生成,recuse 属性指明是否为递归复制
owner:属主 group:属组 mode:权限
[root@node1 manifets]# puppet apply -v web.pp
Notice: Compiled catalog for node1.alren.com in environment production in 1.48 seconds
Info: Applying configuration version ‘1480563754’
Info: Computing checksum on file /etc/httpd/conf/httpd.conf
Info: /Stage[main]/Main/File[httpd.conf]: Filebucketed /etc/httpd/conf/httpd.conf to puppet with sum 42566ec31df37e3d44429b285d015e1d
Notice: /Stage[main]/Main/File[httpd.conf]/content: content changed ‘{md5}42566ec31df37e3d44429b285d015e1d’ to ‘{md5}8b01e334a6e975b659df5dd351923ccb’
Info: /Stage[main]/Main/File[httpd.conf]: Scheduling refresh of Service[httpd]
Notice: /Stage[main]/Main/Service[httpd]: Triggered ‘refresh’ from 1 events
Notice: Finished catalog run in 1.95 seconds
[root@node1 manifets]# ss -tnl
State Recv-Q Send-Q Local Address:Port Peer Address:Port
LISTEN 0 5 192.168.122.1:53 *:*
LISTEN 0 128 *:22 *:*
LISTEN 0 128 127.0.0.1:631 *:*
LISTEN 0 100 127.0.0.1:25 *:*
LISTEN 0 32 :::21 :::*
LISTEN 0 128 :::22 :::*
LISTEN 0 128 ::1:631 :::*
LISTEN 0 128 :::8088 :::*
LISTEN 0 100 ::1:25 :::*
[root@node1 manifets]#
实例三:每三分钟同步下系统时间, 写入定时任务
cron{‘synctime’:
command => ‘/usr/sbin/ntpdate 10.1.0.1 &>/dev/null’, #须执行的命令
ensure => present, #创建任务计划
minute => ‘*/5’, #过多长是时间执行
user => root, #以谁的身份运行
}
[root@node1 testmanifests]# puppet apply -v cron.pp
Notice: Compiled catalog for node1.alren.com in environment production in 0.18 seconds
Info: Applying configuration version ‘1480593969’
Notice: /Stage[main]/Main/Cron[synctime]/minute: minute changed ‘*/3’ to ‘*/5’
Notice: Finished catalog run in 0.09 seconds
[root@node1 testmanifests]# crontab -l
# HEADER: This file was autogenerated at 2016-12-01 20:06:10 +0800 by puppet.
# HEADER: While it can still be managed manually, it is definitely not recommended.
# HEADER: Note particularly that the comments starting with ‘Puppet Name’ should
# HEADER: not be deleted, as doing so could cause duplicate cron jobs.
# Puppet Name: synctime
*/5 * * * * /usr/sbin/ntpdate 10.1.0.1 &>/dev/null #查看到此任务计划存在
[root@node1 testmanifests]#
实例四:puppet 之 if 条件判断
if $osfamily =~ /(?i-mx:debian)/ {$osfamily 为 facter 中取得的内嵌变量
$webserver = ‘apache2’ #自定义变量
} else {
$webserver = ‘httpd’
}
package{“$webserver”:
ensure => installed,
before => [File[‘httpd.conf’], Service[‘httpd’] ],
}
file{‘httpd.conf’:
path => ‘/etc/httpd/conf/httpd.conf’,
source => ‘/root/testmanifests/httpd.conf’,
ensure => file,
}
service{‘httpd’:
ensure => running,
enable => true,
restart => ‘systemctl restart httpd.service’,
subscribe => File[‘httpd.conf’], #通知其他的资源进行刷新操作
}
[root@node1 testmanifests]# puppet apply -v if.pp
Notice: Compiled catalog for node1.alren.com in environment production in 1.53 seconds
Info: Applying configuration version ‘1480594920’
Info: Computing checksum on file /etc/httpd/conf/httpd.conf
Info: FileBucket got a duplicate file {md5}8b01e334a6e975b659df5dd351923ccb
Info: /Stage[main]/Main/File[httpd.conf]: Filebucketed /etc/httpd/conf/httpd.conf to puppet with sum 8b01e334a6e975b659df5dd351923ccb
Notice: /Stage[main]/Main/File[httpd.conf]/content: content changed ‘{md5}8b01e334a6e975b659df5dd351923ccb’ to ‘{md5}42566ec31df37e3d44429b285d015e1d’
Info: /Stage[main]/Main/File[httpd.conf]: Scheduling refresh of Service[httpd]
Notice: /Stage[main]/Main/Service[httpd]: Triggered ‘refresh’ from 1 events
Notice: Finished catalog run in 1.97 seconds
[root@node1 testmanifests]# ss -tnl
State Recv-Q Send-Q Local Address:Port Peer Address:Port
LISTEN 0 5 192.168.122.1:53 *:*
LISTEN 0 128 *:22 *:*
LISTEN 0 128 127.0.0.1:631 *:*
LISTEN 0 100 127.0.0.1:25 *:*
LISTEN 0 128 :::80 :::*
LISTEN 0 32 :::21 :::*
LISTEN 0 128 :::22 :::*
LISTEN 0 128 ::1:631 :::*
LISTEN 0 100 ::1:25 :::*
[root@node1 testmanifests]#
实例五:puppet 之 case 语句
case $osfamily {
“RedHat”: {$webserver=’httpd’}
/(?i-mx:debian)/: {$webserver=’apache2′}
default: {$webserver=’httpd’}
}
package{“$webserver”:
ensure=> installed,
before=> [File[‘httpd.conf’], Service[‘httpd’] ],
}
file{‘httpd.conf’:
ensure=> file,
path => ‘/etc/httpd/conf/httpd.conf’,
source=> ‘/root/testmanifests/httpd.conf’,
}
service{‘httpd’:
ensure=> running,
enable=> true,
restart => ‘systemctl restart httpd.service’,
subscribe=> File[‘httpd.conf’],
}
[root@node1 testmanifests]# puppet apply -v case.pp
Notice: Compiled catalog for node1.alren.com in environment production in 1.61 seconds
Info: Applying configuration version ‘1480595667’
Info: Computing checksum on file /etc/httpd/conf/httpd.conf
Info: FileBucket got a duplicate file {md5}42566ec31df37e3d44429b285d015e1d
Info: /Stage[main]/Main/File[httpd.conf]: Filebucketed /etc/httpd/conf/httpd.conf to puppet with sum 42566ec31df37e3d44429b285d015e1d
Notice: /Stage[main]/Main/File[httpd.conf]/content: content changed ‘{md5}42566ec31df37e3d44429b285d015e1d’ to ‘{md5}3dfa14b023127a3766bddfe15fe14b9a’
Info: /Stage[main]/Main/File[httpd.conf]: Scheduling refresh of Service[httpd]
Notice: /Stage[main]/Main/Service[httpd]: Triggered ‘refresh’ from 1 events
Notice: Finished catalog run in 1.91 seconds
[root@node1 testmanifests]# #可根据自行的语言习惯选择适合的语法,如下所示同样可达到上诉的目的
$webserver = $osfamily ? {
“Redhat” => ‘httpd’,
/(?i-mx:debian)/ => ‘apache2’,
default => ‘httpd’,
}
package{“$webserver”:
ensure => installed,
before => [File[‘httpd.conf’], Service[‘httpd’] ],
}
file{‘httpd.conf’:
path => ‘/etc/httpd/conf/httpd.conf’,
source => ‘/root/testmanifests/httpd.conf’,
ensure => file,
}
service{‘httpd’:
ensure => running,
enable => true,
restart => ‘systemctl restart httpd.service’,
subscribe => File[‘httpd.conf’],
}
四、puppet 类与继承
puppet 中命名的代码模块,经常需要被使用,如如重写则代码冗余,使用定义一组通用目标的资源,可在 puppet 全局调用,就能解决这类问题,类可以被继承,也可以包含子类。
类的语法格式有两种,调用类的方法常用的有三种,可以在类中传递参数等灵活的操作,如以下实例:
class webserver {#类申明后续调用后才生效,调用的方法常用的有三种
$webpkg = $operatingsystem ? {
/(?i-mx:(centos|redhat|Fedora))/ => ‘httpd’,
/(?i-mx:(Ubuntu|debian))/ => ‘apache2’,
default => ‘httpd’,
}
package{“$webpkg”:
ensure => installed,
}
file{‘/etc/httpd/conf/httpd.conf’:
ensure => file,
owner => root,
group => root,
source => ‘/root/testmanifests/httpd.conf’,
require => Package[“$webpkg”],
notify => Service[‘httpd’],
}
service{‘httpd’:
ensure => running,
enable => true,
}
}
include webserver #使用 include 进行调用
# 申明调用类的第二种方法
class web($webserver=’httpd’) {#向类中传递参数
package{“$webserver”:
ensure => installed,
before => [File[‘httpd.conf’], Service[‘httpd’] ],
}
file{‘httpd.conf’:
path => ‘/etc/httpd/conf/httpd.conf’,
source => ‘/root/testmanifests/httpd.conf’,
ensure => file,
}
service{‘httpd’:
ensure => running,
enable => true,
restart => ‘systemctl restart httpd.service’,
subscribe => File[‘httpd.conf’],
}
}
class{‘web’:
webserver => ‘apache2’, #调用类
}
[root@node1 ~]# puppet apply -v –noop class2.pp
Notice: Compiled catalog for node1.alren.com in environment production in 1.53 seconds
Info: Applying configuration version ‘1480596978’
Notice: /Stage[main]/Web/Package[apache2]/ensure: current_value absent, should be present (noop)
Notice: /Stage[main]/Web/File[httpd.conf]/content: current_value {md5}3dfa14b023127a3766bddfe15fe14b9a, should be {md5}8b01e334a6e975b659df5dd351923ccb(noop)
Info: /Stage[main]/Web/File[httpd.conf]: Scheduling refresh of Service[httpd]
Notice: /Stage[main]/Web/Service[httpd]: Would have triggered ‘refresh’ from 1 events
Notice: Class[Web]: Would have triggered ‘refresh’ from 3 events
Notice: Stage[main]: Would have triggered ‘refresh’ from 1 events
Notice: Finished catalog run in 0.65 seconds
[root@node1 ~]#
类的继承:子类可继承父类的资源属性,同时可定义父类不存在的额资源属性,一个父类可同时被多个子类所继承
class nginx {#定义父类信息
package{‘nginx’:
ensure => installed, #安装程序包
}
service{‘nginx’: #启动程序
ensure => running,
enable => true,
require => Package[‘nginx’],
}
}
class nginx::web inherits nginx {#继承父类的原有属性,同时增加 file 资源属性
file{‘ngx-web.conf’:
path => ‘/etc/nginx/conf.d/ngx-web.conf’,
ensure => file,
require => Package[‘nginx’],
source => ‘/root/testmanifests/nginx/ngx-web.conf’,
}
file{‘nginx.conf’:
path => ‘/etc/nginx/nginx.conf’,
ensure => file,
content => template(‘/root/testmanifests/nginx.conf.erb’), #此模板需事先存在方可使用
require => Package[‘nginx’],
}
Service[‘nginx’] {
subscribe => [File[‘ngx-web.conf’], File[‘nginx.conf’] ], #通知其他资源进行刷新操作
}
}
include nginx::web #调用声明的类
五、puppet 模板(此内容不过多解释,需自行加强)
模板是一个按照约定的、预定的结构存放了多个文件或子目录的目录,目录里面的这些文件或子目录必须遵循一定的格式的命名规范,puppet 会在配置的路径下查找所需的资源模块。模块的名称通常是只能以小写字母开头,可以包含小写字母,数字下划线,但是不能使用 main 和 settings。
模块的组成部分:
manifests/: 资源清单
init.pp: 必须定义一个类,类名必须与模块名相同;
files/: 静态文件
templates/: 模板文件
lib/: 插件目录,常用于存储自定义的 facts 以及自定义类型
spec/:类似于 tests 目录,存储 lib/ 目录下插件的使用帮助和范例;
tests/:当前模块的使用帮助或使用范例文件;
总结:运维工具有很多例如:Puppet,Ansible,slackstack 等,puppet 还是一个很好用的自动化运维工具,大大减轻的运维人员的重复操作,提高了工作效率,在运维过程中可根据业务需求选择不同的运维工具,在服务器数量不是很大的情形下可使用轻量级的 ansible,在服务器数量达到一定的规模时使用重量级的 puppet 相对来说效率更高。当面临有得选择的时候想起一句话:箩卜白菜各有所爱,适合自己专注、精通一个运维工具比全会那么一点,解决问题更有优势。
Puppet 学习系列:
Puppet 学习一:安装及简单实例应用 http://www.linuxidc.com/Linux/2013-08/88710.htm
Puppet 学习二: 简单模块配置和应用 http://www.linuxidc.com/Linux/2013-08/88711.htm
相关阅读:
有关 Puppet agent 端三种备份恢复方案探讨研究 http://www.linuxidc.com/Linux/2013-07/87885.htm
选择更安全的方式注册你的 Puppet 节点 http://www.linuxidc.com/Linux/2013-07/87884.htm
通过配置 SSH 深刻理解 Puppet 的语法及工作机制 http://www.linuxidc.com/Linux/2013-07/87882.htm
Puppet 利用 Nginx 多端口实现负载均衡 http://www.linuxidc.com/Linux/2013-02/79794.htm
CentOS(5 和 6)下 Puppet 的 C / S 模式实例 http://www.linuxidc.com/Linux/2011-12/50502.htm
Puppet 的详细介绍 :请点这里
Puppet 的下载地址 :请点这里
本文永久更新链接地址 :http://www.linuxidc.com/Linux/2016-12/137893.htm