作者:⽬录
⼀、puppet 介绍
1、puppet是什么
2、puppet的⼯作机制
1)⼯作模型2)⼯作流程3)使⽤模型3、puppet 名词解释⼆、puppet 资源详解
1、程序安装及环境2、puppet 资源简介
1)资源抽象2)资源定义
3)资源属性中的三个特殊属性:3、常⽤资源总结4、资源的特殊属性
tag 标签5、puppet 变量
1)puppet的变量种类2)变量的作⽤域6、puppet 流程控制语句
1)if 语句2)case 语句3)selector 语句
写在后⾯ 正⽂
⼀、puppet 介绍
1、puppet是什么
puppet是⼀个IT基础设施⾃动化管理⼯具,它能够帮助系统管理员管理基础设施的整个⽣命周期: 供应(provisioning)、配置(configuration)、联动(orchestration)及报告(reporting)。
基于puppet ,可实现⾃动化重复任务、快速部署关键性应⽤以及在本地或云端完成主动管理变更和快速扩展架构规模等。 遵循GPL 协议(2.7.0-), 基于ruby语⾔开发。 2.7.0 以后使⽤(Apache 2.0 license)
对于系统管理员是抽象的,只依赖于ruby与facter。
能管理多达40 多种资源,例如:file、user、group、host、package、service、cron、exec、yum repo等。
2、puppet的⼯作机制
1)⼯作模型
puppet 通过声明性、基于模型的⽅法进⾏IT⾃动化管理。
定义:通过puppet 的声明性配置语⾔定义基础设置配置的⽬标状态; 模拟:强制应⽤改变的配置之前先进⾏模拟性应⽤;
强制:⾃动、强制部署达成⽬标状态,纠正任何偏离的配置;
报告:报告当下状态及⽬标状态的不同,以及达成⽬标状态所进⾏的任何强制性改变;puppet三层模型
puppet三层模型如下:
puppet三层模型2)⼯作流程
⼯作流程3)使⽤模型
puppet的使⽤模型分为单机使⽤模型和master/agent模型,下⾯我们来看看这两个模型的原理图。单机使⽤模型
实现定义多个manifests --> complier --> catalog --> apply
单机使⽤模型⼯作原理
master/agent模型
master/agent模型实现的是集中式管理,即 agent 端周期性向 master 端发起请求,请求⾃⼰需要的数据。然后在⾃⼰的机器上运⾏,并将结果返回给 master 端。 架构和⼯作原理如下:架构
master/agent模式架构⼯作原理
master/agent模式⼯作原理
3、puppet 名词解释
资源:是puppet的核⼼,通过资源申报,定义在资源清单中。相当于ansible中的模块,只是抽象的更加彻底。类:⼀组资源清单。
模块:包含多个类。相当于ansible中的⾓⾊。站点清单:以主机为核⼼,应⽤哪些模块。
⼆、puppet 资源详解
接下来,我们就以单机模式来具体介绍⼀下puppet的各个部分。
1、程序安装及环境
⾸先,我们还是来安装⼀下puppet,puppet的安装可以使⽤源码安装,也可以使⽤rpm(官⽅提供)、epel源、官⽅提供的yum仓库来安装(通过下载官⽅提供的rpm包可以指定官⽅的yum仓库)。 在这⾥,我们就是⽤ yum 安装的⽅式。
yum install -y puppet
安装完成过后,我们可以通过rpm -ql puppet | less来查看⼀下包中都有⼀些什么⽂件。 其中主配置⽂件为/etc/puppet/puppet.conf,使⽤的主程序为/usr/bin/puppet。
2、puppet 资源简介
1)资源抽象
puppet 从以下三个维度来对资源完成抽象:
1. 相似的资源被抽象成同⼀种资源**“类型”** ,如程序包资源、⽤户资源及服务资源等;
2. 将资源属性或状态的描述与其实现⽅式剥离开来,如仅说明安装⼀个程序包⽽不⽤关⼼其具体是通过yum、pkgadd、ports或是其它⽅式实现;
3. 仅描述资源的⽬标状态,也即期望其实现的结果,⽽不是其具体过程,如“确定nginx 运⾏起来” ⽽不是具体描述为“运⾏nginx命令将其启动起来”;
这三个也被称作puppet 的资源抽象层(RAL)
RAL 由type( 类型) 和provider( 提供者,即不同OS 上的特定实现)组成。 2)资源定义
资源定义通过向资源类型的属性赋值来实现,可称为资源类型实例化; 定义了资源实例的⽂件即清单,manifest;
定义资源的语法如下:
type {'title':
attribute1 => value1, atrribute2 => value2, ……}
注意:type必须使⽤⼩写字符;title是⼀个字符串,在同⼀类型中必须惟⼀;每⼀个属性之间需要⽤“,”隔开,最后⼀个“,”可省略。 例如,可以同时有名为nginx 的“service”资源和“package”资源,但在“package” 类型的资源中只能有⼀个名为“nginx”的资源。3)资源属性中的三个特殊属性:
Namevar:可简称为name;ensure:资源的⽬标状态;Provider:指明资源的管理接⼝;
3、常⽤资源总结
1)查看资源
我们可以使⽤puppet describe来打印有关Puppet资源类型,提供者和元参数的帮助。使⽤语法如下:
puppet describe [-h|--help] [-s|--short] [-p|--providers] [-l|--list] [-m|--meta] [type] -l:列出所有资源类型;
-s:显⽰指定类型的简要帮助信息;
-m:显⽰指定类型的元参数,⼀般与-s⼀同使⽤;
2)group:管理系统上的⽤户组。 查看使⽤帮助信息:
group使⽤帮助
属性:
name:组名,可以省略,如果省略,将继承title的值; gid:GID;
system:是否为系统组,true OR false; ensure:⽬标状态,present/absent; members:成员⽤户;
简单举例如下:
vim group.pp group{'mygrp':
name => 'mygrp', ensure => present, gid => 2000, }
我们可以来运⾏⼀下:
运⾏写好的group资源
3)user:管理系统上的⽤户。 查看使⽤帮助信息:
user使⽤帮助
属性:
name:⽤户名,可以省略,如果省略,将继承title的值; uid: UID;
gid:基本组ID;
groups:附加组,不能包含基本组; comment:注释; expiry:过期时间 ; home:⽤户的家⽬录; shell:默认shell类型;
system:是否为系统⽤户 ; ensure:present/absent; password:加密后的密码串;
简单举例如下:
vim user1.pp user{'keerr':
ensure => present, system => false,
comment => 'Test User', shell => '/bin/tcsh', home => '/data/keerr', managehome => true, groups => 'mygrp', uid => 3000, }
4)package:puppet的管理软件包。 查看使⽤帮助信息:
package使⽤帮助
属性:
ensure:installed, present, latest, absent, any version string (implies present) name:包名,可以省略,如果省略,将继承title的值;
source:程序包来源,仅对不会⾃动下载相关程序包的provider有⽤,例如rpm或dpkg; provider:指明安装⽅式;
简单举例如下:
vim package1.pp package{'nginx':
ensure => installed, procider => yum }
5)service:定义服务的状态 查看使⽤帮助信息:
puppet describe service -s -m
service使⽤帮助
属性:
ensure:服务的⽬标状态,值有true(running)和false(stopped) enable:是否开机⾃动启动,值有true和false
name:服务名称,可以省略,如果省略,将继承title的值 path:服务脚本路径,默认为/etc/init.d/下 start:定制启动命令 stop:定制关闭命令 restart:定制重启命令 status:定制状态
简单举例如下:
vim service1.pp service{'nginx':
ensure => true, enable => false }
6)file:管理⽂件、⽬录、软链接 查看使⽤帮助信息:
file使⽤帮助
属性:
ensure:⽬标状态,值有absent,present,file,directory和link
file:类型为普通⽂件,其内容由content属性⽣成或复制由source属性指向的⽂件路径来创建; link:类型为符号链接⽂件,必须由target属性指明其链接的⽬标⽂件;
directory:类型为⽬录,可通过source指向的路径复制⽣成,recurse属性指明是否递归复制; path:⽂件路径; source:源⽂件; content:⽂件内容;
target:符号链接的⽬标⽂件; owner:定义⽂件的属主; group:定义⽂件的属组; mode:定义⽂件的权限; atime/ctime/mtime:时间戳;
简单举例如下:
vim file1.pp file{'aaa':
path => '/data/aaa', source => '/etc/aaa', owner => 'keerr', mode => '611', }
7)exec:执⾏命令,慎⽤。通常⽤来执⾏外部命令 查看使⽤帮助信息:
puppet describe exec -s -m
exec使⽤帮助
属性:
command(namevar):要运⾏的命令; cwd:指定运⾏该命令的⽬录;
creates:⽂件路径,仅此路径表⽰的⽂件不存在时,command⽅才执⾏; user/group:运⾏命令的⽤户⾝份; path:指定命令执⾏的搜索路径;
onlyif:此属性指定⼀个命令,此命令正常(退出码为0)运⾏时,当前command才会运⾏;
unless:此属性指定⼀个命令,此命令⾮正常(退出码为⾮0)运⾏时,当前command才会运⾏; refresh:重新执⾏当前command的替代命令;
refreshonly:仅接收到订阅的资源的通知时⽅才运⾏;
简单举例如下:
vim exec1.pp exec{'cmd':
command => 'mkdir /data/testdir',
path => ['/bin','/sbin','/usr/bin','/usr/sbin'], # path => '/bin:/sbin:/usr/bin:/usr/sbin', }
8)cron:定义周期性任务 查看使⽤帮助信息:
cron使⽤帮助
属性:
command:要执⾏的任务(命令或脚本); ensure:⽬标状态,present/absent; hour:时; minute:分; monthday:⽇; month:⽉; weekday:周;
user:以哪个⽤户的⾝份运⾏命令(默认为root); target:添加为哪个⽤户的任务; name:cron job的名称;
简单举例如下:
vim cron1.pp cron{'timesync':
command => '/usr/sbin/ntpdata 172.16.0.1', ensure => present, minute => '*/3', user => 'root', }
我们可以运⾏⼀下,查看我们的crontab,来看看该任务是否已经被添加:
[root@master manifests]# puppet apply -v --noop cron1.pp #试运⾏[root@master manifests]# puppet apply -v cron1.pp #运⾏[root@master manifests]# crontab -l #查看计划任务
# HEADER: This file was autogenerated at 2017-12-14 15:05:05 +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: timesync
*/3 * * * * /usr/sbin/ntpdata 172.16.0.1
9)notify:调试输出
查看使⽤帮助信息:
属性:
message:记录的信息 name:信息名称
该选项⼀般⽤于master/agent模式中,来记录⼀些操作的时间,⽐如重新安装了⼀个程序呀,或者重启了应⽤等等。会直接输出到代理机的运⾏⽇志中。
以上,就是我们常见的8个资源。其余的资源我们可以使⽤puppet describe -l来列出,上⽂中也已经说过了~
4、资源的特殊属性
puppet中也提供了before、require、notify和subscribe四个参数来定义资源之间的依赖关系和通知关系。
before:表⽰需要依赖于某个资源
require:表⽰应该先执⾏本资源,在执⾏别的资源
notify:A notify B:B依赖于A,且A发⽣改变后会通知B;
subscribe:B subscribe A:B依赖于A,且B监控A资源的变化产⽣的事件; 同时,依赖关系还可以使⽤->和~>来表⽰:
-> 表⽰后资源需要依赖前资源
~> 表⽰前资源变动通知后资源调⽤ 举例如下:
vim file.pp
file{'test.txt': #定义⼀个⽂件 path => '/data/test.txt', ensure => file,
source => '/etc/fstab', }
file{'test.symlink': #依赖⽂件建⽴超链接 path => '/data/test.symlink', ensure => link,
target => '/data/test.txt', require => File['test.txt'], }
file{'test.dir': #定义⼀个⽬录 path => '/data/test.dir', ensure => directory,
source => '/etc/yum.repo.d/', recurse => true, }
我们还可以使⽤在最下⾯统⼀写依赖关系的⽅式来定义:
vim redis.pp package{'reids':
ensure => installed, }
file{'/etc/redis.conf':
source => '/root/manifets/files/redis.conf', ensure => file, owner => redis, group => root, mode => '0640', }
service{'redis':
ensure => running, enable => true, hasrestart => true, }
Package['redis'] -> File['/etc/redis.conf'] -> Service['redis'] #定义依赖关系
tag 标签
如同 anssible ⼀样,puppet 也可以定义“标签”——tag,打了标签以后,我们在运⾏资源的时候就可以只运⾏某个打过标签的部分,⽽
⾮全部。这样就更⽅便于我们的操作。
⼀个资源中,可以有⼀个tag也可以有多个。具体使⽤语法如下:
type{'title': ...
tag => 'TAG1',}
type{'title': ...
tag => ['TAG1','TAG2',...],}
调⽤时的语法如下:
puppet apply --tags TAG1,TAG2,... FILE.PP
实例
⾸先,我们去修改⼀下redis.pp⽂件,添加⼀个标签进去
vim redis.pp package{'redis':
ensure => installed, }
file{'/etc/redis.conf':
source => '/root/manifets/file/redis.conf', ensure => file, owner => redis, group => root, mode => '0640',
tag => 'instconf' #定义标签 }
service{'redis':
ensure => running, enable => true, hasrestart => true, }
Package['redis'] -> File['/etc/redis.conf'] -> Service['redis']
然后,我们⼿动先开启redis服务:
systemctl start redis
现在,我们去修改⼀下file⽬录下的配置⽂件:
vim file/redis.conf requirepass keerya
接着,我们就去运⾏redis.pp,我们的配置⽂件已经修改过了,现在想要实现的就是重启该服务,实现,需要使⽤密码keer登录:
puppet apply -v --tags instconf redis.pp
redis.pp运⾏结果
现在,我们就去登录⼀下redis看看是否⽣效:
redis-cli -a keerya
redis验证
验证成功,实验完成。
5、puppet 变量
puppet 变量以“$”开头,赋值操作符为“=”,语法为$variable_name=value。数据类型:
字符型:引号可有可⽆;但单引号为强引⽤,双引号为弱引⽤;⽀持转义符; 数值型:默认均识别为字符串,仅在数值上下⽂才以数值对待; 数组:[]中以逗号分隔元素列表; 布尔型值:true, false;不能加引号;
hash:{}中以逗号分隔k/v数据列表; 键为字符型,值为任意puppet⽀持的类型;{ ‘mon’ => ‘Monday’, ‘tue’ => ‘Tuesday’, };
undef:从未被声明的变量的值类型;正则表达式:
(? i:忽略字符⼤⼩写; m:把.当换⾏符; x:忽略 注意:不能赋值给变量,仅能⽤在接受=~或!~操作符的位置;1)puppet的变量种类 puppet 种类有三种,为facts,内建变量和⽤户⾃定义变量。facts: 由facter提供;top scope;内建变量: master端变量 $servername, $serverip, $serverversion agent端变量 $clientcert, $clientversion, $environment parser变量 $module_name⽤户⾃定义变量2)变量的作⽤域 不同的变量也有其不同的作⽤域。我们称之为Scope。 作⽤域有三种,top scope,node scope,class scope。 其⽣效范围排序为:top scope > node scope > class scope 变量⽣效范围 其优先级排序为:top scope < node scope < class scope 6、puppet 流程控制语句 puppet ⽀持if 语句,case 语句和selector 语句。1)if 语句 if语句⽀持单分⽀,双分⽀和多分⽀。具体语法如下: 单分⽀: if CONDITION { statement …… } 双分⽀: if CONDITION { statement …… } else{ statement …… } 多分⽀: if CONDITION { statement …… } elsif CONDITION{ statement …… } else{ statement …… } 其中,CONDITION的给定⽅式有如下三种: 变量 ⽐较表达式 有返回值的函数举例 vim if.pp if $operatingsystemmajrelease == '7' { $db_pkg='mariadb-server' }else{ $db_pkg='mysql-server' } package{\"$db_pkg\": ensure => installed, } 2)case 语句 类似 if 语句,case 语句会从多个代码块中选择⼀个分⽀执⾏,这跟其它编程语⾔中的 case 语句功能⼀致。 case 语句会接受⼀个控制表达式和⼀组 case 代码块,并执⾏第⼀个匹配到控制表达式的块。 使⽤语法如下: case CONTROL_EXPRESSION { case1: { ... } case2: { ... } case3: { ... } …… default: { ... }} 其中,CONTROL_EXPRESSION的给定⽅式有如下三种: 变量表达式 有返回值的函数 各case的给定⽅式有如下五种: 直接字串;变量 有返回值的函数正则表达式模式;default举例 vim case.pp 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': path => '/etc/httpd/conf/httpd.conf', source => '/root/manifests/httpd.conf', ensure => file, } service{'httpd': ensure => running, enable => true, restart => 'systemctl restart httpd.service', subscribe => File['httpd.conf'], } 3)selector 语句 Selector 只能⽤于期望出现直接值(plain value) 的地⽅,这包括变量赋值、资源属性、函数参数、资源标题、其它 selector。 selector 不能⽤于⼀个已经嵌套于于selector 的case 中,也不能⽤于⼀个已经嵌套于case 的case 语句中。 具体语法如下: CONTROL_VARIABLE ? { case1 => value1, case2 => value2, ... default => valueN,} 其中,CONTROL_EXPRESSION的给定⽅式有如下三种: 变量表达式 有返回值的函数 各case的给定⽅式有如下五种: 直接⼦串;变量; 有返回值的函数;正则表达式模式;default selectors 使⽤要点: 1. 整个selector 语句会被当作⼀个单独的值,puppet 会将控制变量按列出的次序与每个case 进⾏⽐较,并在遇到⼀个匹配的 case 后,将其值作为整个语句的值进⾏返回,并忽略后⾯的其它 case。 2. 控制变量与各 case ⽐较的⽅式与 case 语句相同,但如果没有任何⼀个 case 与控制变量匹配时,puppet 在编译时将会返回⼀个错误,因此,实践中,其必须提供default case。 3. selector 的控制变量只能是变量或有返回值的函数,切记不能使⽤表达式。 4. 其各 case 可以是直接值(需要加引号) 、变量、能调⽤返回值的函数、正则表达式模式或 default。5. 但与 case 语句所不同的是,selector 的各 case 不能使⽤列表。 6. selector 的各 case 的值可以是⼀个除了 hash 以外的直接值、变量、能调⽤返回值的函数或其它的 selector。举例 vim selector.pp $pkgname = $operatingsystem ? { /(?i-mx:(ubuntu|debian))/ => 'apache2', /(?i-mx:(redhat|fedora|centos))/ => 'httpd', default => 'httpd', } package{\"$pkgname\": ensure => installed, } 写在后⾯ 以上,我们本次的介绍就告⼀段落,剩余的部分,请看下回分解。 因篇幅问题不能全部显示,请点此查看更多更全内容