一、puppet简介

puppet是基于ruby语言开发的一款开源的软件自动化配置和部署工具,它使用简单且功能强大,可以C/S模式或独立运行。


二、puppet工作模式与流程

①puppet的工作模式

定义:使用puppet配置语言定义基础配置信息;master要指明agent相关配置

模拟: 模拟测试运行,不真正执行

强制:强制当前agent与定义的目标状态保持一致;执行所有配置

报告:通过puppet api将执行结果发送给接受者; 执行完成agent向master报告

②Master/Agent的工作流程



三、puppet基本用法

3.1、 puppet的核心组件是资源,下面讲解一下几个常用资源的使用方法:

#puppetdescribe--list//查看puppet的资源列表#puppetdescribe资源名称//查看该资源的使用方法#puppetapply*.pp//应用定义的资源清单


①group -- 组管理

常用属性:name//组名,NameVargid//GIDsystem{true|false}    //是否为系统组ensure{present|absent}//创建,删除members//定义组内成员

例子:test1.ppgroup{"redhat"://组名ensure=>present,//创建gid=>950,//组idsystem=>true,//为系统组,因为使用的是centos7,1~1000都是系统组id}

[root@node1puppet]#puppetapply-vtest1.pp//在本地应用Notice:Compiledcatalogfornode1inenvironmentproductionin0.22secondsInfo:Applyingconfigurationversion'1446996520'Notice:/Stage[main]/Main/Group[redhat]/ensure:createdNotice:Finishedcatalogrunin0.08seconds[root@node1puppet]#tail-1/etc/group//查看结果redhat:x:950:


②user -- 用户管理

常用属性:comment//注释信息ensure{present|absent}//创建,删除expiry//过期期限gid//基本组idgroups//附加组home//家目录shell//默认shellname//用户名,NameVarsystem{true|false}//是否为系统用户uid//用户的UIDpassword//用户的密码

例子:test2.ppuser{"centos":comment=>"thisisacentosuser",//注释ensure=>present,//创建用户gid=>950,//组iduid=>950,//用户idhome=>"/home/centos",//家目录shell=>"/bin/bash",//默认shellsystem=>true,//系统用户password=>'$1$b1010cc9$V0WJdVPoXCVBI70nse5/H.',//定义密码}[root@node1~]#opensslpasswd-1-salt`opensslrand-hex4`//生成密码的方法Password:$1$b1010cc9$V0WJdVPoXCVBI70nse5/H.

[root@node1puppet]#puppetapply-vtest2.ppNotice:Compiledcatalogfornode1inenvironmentproductionin0.30secondsInfo:Applyingconfigurationversion'1446997336'Notice:/Stage[main]/Main/User[centos]/ensure:createdNotice:Finishedcatalogrunin0.09seconds[root@node1puppet]#tail-1/etc/shadow//查看密码文件centos:$1$b1010cc9$V0WJdVPoXCVBI70nse5/H.:16747::::::[root@node1puppet]#tail-1/etc/passwd//查看用户文件centos:x:950:950:thisisacentosuser:/home/centos:/bin/bash


③cron -- 计划任务

常用属性:ensure{present|absent}//创建,删除command//要运行的jobhour//时,0-23minute//分,0-59month//月,1-12monthday//日,即每月的第几天,1-31weekday//周,0-7name//定义计划任务名称user//运行的用户

例子:test3.ppcron{"synctime":ensure=>present,//创建计划任务command=>'/usr/sbin/ntpdatentp.sjtu.edu.cn&>/dev/null',//使用绝对路径命令minute=>'*/5',//每5分钟同步一次时间}

[root@node1puppet]#puppetapply-vtest3.ppNotice:Compiledcatalogfornode1inenvironmentproductionin0.07secondsInfo:Applyingconfigurationversion'1446998027'Notice:/Stage[main]/Main/Cron[synctime]/ensure:createdNotice:Finishedcatalogrunin0.26seconds[root@node1puppet]#crontab-l//查看结果#HEADER:Thisfilewasautogeneratedat2015-11-0823:53:48+0800bypuppet.#HEADER:Whileitcanstillbemanagedmanually,itisdefinitelynotrecommended.#HEADER:Noteparticularlythatthecommentsstartingwith'PuppetName'should#HEADER:notbedeleted,asdoingsocouldcauseduplicatecronjobs.#PuppetName:synctime*/5****/usr/sbin/ntpdatentp.sjtu.edu.cn&>/dev/null


④notify -- 消息

常用属性:message//要发送的消息的内容;NameVar

例子:test4.ppnotify{"hi":message=>"helloworld",//输出消息信息为helloworld}

[root@node1puppet]#puppetapply-vtest4.ppNotice:Compiledcatalogfornode1inenvironmentproductionin0.05secondsInfo:Applyingconfigurationversion'1448117125'Notice:helloworld//应用的结果Notice:/Stage[main]/Main/Notify[hi]/message:defined'message'as'helloworld'Notice:Finishedcatalogrunin0.04seconds


⑤file --文件管理

指明文件内容来源:content//直接给出文件内容,支持\n,\t===要用双引号;source//从指定位置下载文件ensure{file|directory|link|present|absent}//文件,目录,链接,创建,删除常用属性:force//强制运行,可用值yes,no,true,falsegroup//文件的属组owner//文件的属主mode//指定权限,支持八进制格式权限,以及u,g,o的赋权方式path//目标路径;必须为绝对路径source//源文件路径;可以是本地文件路径(单机模型),也可以使用puppet:///modules/module_name/file_name;target//当ensure为“link”时,target表示path指向的文件是一个符号链接文件,其目标为此target属性所指向的路径;此时content及source属性自动失效;

例子:test5.ppfile{"/tmp/hello":ensure=>directory,//在/tmp目录下,创建hello目录owner=>"centos",//属主centosgroup=>"redhat",//属组redhatmode=>"400",//权限为400,但为目录,必然会有x权限,故创建后权限为500}file{"/tmp/test1"://创建文件test1ensure=>file,owner=>"centos",//属主为centos}file{"/tmp/link":ensure=>link,//创建test1的链接文件为linktarget=>"/tmp/test1",}

[root@node1puppet]#puppetapply-vtest5.ppNotice:Compiledcatalogfornode1inenvironmentproductionin0.15secondsInfo:Applyingconfigurationversion'1448117739'Notice:/Stage[main]/Main/File[/tmp/test1]/ensure:createdNotice:/Stage[main]/Main/File[/tmp/hello]/ensure:createdNotice:/Stage[main]/Main/File[/tmp/link]/ensure:createdNotice:Finishedcatalogrunin0.05seconds[root@node1puppet]#ll/tmp///查看结果total4dr-x------2centosredhat4096Nov2122:55hellolrwxrwxrwx1rootroot10Nov2122:55link->/tmp/test1-rw-r--r--1centosroot0Nov2122:55test1


⑥exec -- 命令管理

常用选项:command//运行的命令;NameVar;creates//此属性指定的文件不存在时才执行此命令;cwd//在此属性指定的路径下运行命令;user//以指定的用户身份运行命令;group//指定组;onlyif//给定一个测试命令;仅在此命令执行成功(返回状态码为0)时才运行command指定的命令;unless//给定一个测试命令;仅在此命令执行失败(返回状态码不为0)时才运行command指定的命令;refresh//接受到其它资源发来的refresh通知时,默认是重新执行exec定义的command,//refresh属性可改变这种行为,即可指定仅在refresh时运行的命令;refreshonly//仅在收到refresh通知,才运行此资源;returns//期望的状态返回值,返回非此值时表示命令执行失败;tries//尝试执行的次数;timeout//超时时长;path//指明命令搜索路径,其功能类型PATH环境变量;其值通常为列表['path2','path3',...];如果不定义此属性,则必须给定命令的绝对路径;

例子:test6.ppexec{"/bin/echohello>/tmp/hello.txt":user=>root,group=>root,unless=>"/usr/bin/test-e/tmp/hello.txt",//文件不存在的时候执行echo命令}

[root@node1puppet]#puppetapply-vtest6.ppNotice:Compiledcatalogfornode1inenvironmentproductionin0.04secondsInfo:Applyingconfigurationversion'1448121368'Notice:/Stage[main]/Main/Exec[/bin/echohello>/tmp/hello.txt]/returns:executedsuccessfullyNotice:Finishedcatalogrunin0.11seconds[root@node1puppet]#cat/tmp/hello.txt//查看应用结果hello

注: creates后面直接跟文件,不存在的时候运行命令;

onlyif或unless后面必须跟判断语句;

onlyif执行成功运行命令,unless执行不成功运行命令;


⑦package -- 软件包管理

常用选项:name//软件包名ensure{present,installed|latest|absent}//安装,安装最新的,卸载

例子:test7.pppackage{"httpd":ensure=>present,allow_virtual=>false,}

[root@node1puppet]#rpm-qhttpdpackagehttpdisnotinstalled


⑧service -- 服务管理

常用选项:ensure{running运行状态|stopped停止状态}//指定服务的目标状态enable{true|false}//指定服务是否开机自启动,并非对所有均有效name//服务名,默认与title相同

例子:test8.ppservice{"httpd":ensure=>running,enable=>true,}

[root@node1puppet]#puppetapply-vtest8.ppNotice:Compiledcatalogfornode1inenvironmentproductionin0.48secondsInfo:Applyingconfigurationversion'1448119012'Notice:/Stage[main]/Main/Service[httpd]/ensure:ensurechanged'stopped'to'running'Info:/Stage[main]/Main/Service[httpd]:UnschedulingrefreshonService[httpd]Notice:Finishedcatalogrunin0.84seconds[root@node1puppet]#ss-tanl//查看应用结果StateRecv-QSend-QLocalAddress:PortPeerAddress:PortLISTEN0128:::80:::*[root@node1puppet]#systemctllist-unit-files--typeservice|grephttpdhttpd.serviceenabled


3.2、puppet的资源引用

①资源引用格式: Type['title'] 资源类型首字母要大写,例Group|Package|File等


②关系的定义

定义依赖关系 :即资源定义有先后顺序

被依赖的资源中使用:before

例:创建用户之前,所定义gid所对应的组应该事先存在,在group中使用

依赖其它资源的资源:require

例:依赖对应gid的组,在user中使用

->:链式依赖

定义通知关系:

被依赖的资源中使用:notify(通知)

例:配置文件使用,当发生改变的时候,通知相应服务进行reload或restart

监听其它资源的资源:subscribe (订阅)

例:服务中使用,可订阅对应服务的配置文件

~>:链式通知


3.3、puppet的数据类型

<1> 字符型:

①非结构化文本字符串,可使用引号也可不用;

②单引号强引用,双引号弱引用;

③支持转义符


<2> 数值型:

整数和浮点数,只有在执行数值计算或比较的时候才会当做数值型,默认为字符型


<3> 数组:

①[]中括号以逗号分隔的元素

②数组中的元素可以是任意数据类型

③ 数组的索引从0开始,也可以是负数索引


<4> 布尔型:

true或false,不能加引号


<5> undef:

未被声明的变量值的类型


<6> hash:类似集合

①键值数据类型,key=>value,定义在{}大括号中,以逗号分隔

②key必须为字符型,value可以是任意数据类型

③访问hash类型的数据元素要使用key当索引


<7> 正则表达式:

非标准数据类型,不能赋值给变量,只接受=~和!~匹配操作符的位置

使用方法:/正则表达式/,正则表达式格式

(?<ENABLED OPTION>:<SUBPATTERN>) ;(?<DISABLED OPTION>:<SUBPATTERN>)

例: =~ /^(?i-mx(centos|fedora))/

常用的选项:

i:忽略字符大小写

m:把点当换行符

x:忽略空白字符和注释


3.4、puppet的变量

puppet的变量名称必须以“$”开头,赋值操作符为“=”

facter变量:可直接引用

查看puppet支持的各facts

# facter -p

内置变量

客户端内置: $clientcert ; $clientversion

服务器端内置 : $servername ; $serverip; $serverversion ; $module_name


3.5、puppet的类

用于公共目的的一组资源,是命名的代码块,创建后可在puppet全局进行调用,类可以继承。

3.5.1、类的定义

①不带参数的类 class class_name {

...puppet code...

}

②带参数的类 calss class_name (param1='value1',param2='value2') {

...puppet code...

}

注意:类名只能包含小写字母、数字和下载线,且必须以小写字母开头 ;类需要声明后才可以执行


3.5.2、类的声明,常用方式:

①类声明的方式 1 :

include class_name1,class_name2, ....

②类声明的方式2 :

class { 'class_name':

...puppet code...

}

3.5.3、类的继承:继承一个已有的类,并实现覆盖资源属性,或向资源属性追加额外值 (=> , +> )

定义方式: base_class为基类,也称为父类

class base_class {

... puppet code .....

}

class base_class::class_name inherits base_class {

... puppet code .....

}


3.6、puppet的条件语句语法格式

①if语句

单分支:

if CONDITION {

statement

...

}

双分支:

if CONDITION {

statement

...

}

else {

statement

...

}

多分支:

if CONDITION {

statement

...

}

elif CONDITION {

statement

...

}

else {

statement

...

}

CONDITION 的用法:

1、比较表达式

2、变量引用

3、有返回值的函数调用


②case语句

case语句会从多个代码块中选择第一个与控制表达式匹配的块进行执行

case CONTROL_EXPRESS {

case1,...: { statement }

case2,...: { statement }

......

default:{ statement }

}


③selector语句

selector只能用于期望出现的位置,不能用于一个已经嵌套了selector的case中,也不能用于一个已经嵌套了case的case语句中;如果给出的case都不匹配控制变量,那么必须定义default case,否则会报错。

CONTROL_VARIABLE ? {

case1 => value1 ,

case2 => value2 ,

......

default => valueN

}


3.7、puppet的模板

puppet模板: 基于ERB模板语言,在静态文件中使用变量等编程元素生成适用于多种不同的环境的文本文件(配置文件);

Embedded RuBy,用于实现在文本文件中嵌入ruby代码,原来的文本信息不会被改变,但ruby代码会被执行,执行结果将直接替换原来代码

常用代码: <%= Ruby Expression %> ==== 替换为表达式的值

//一般结合facter获取系统的信息,修改服务的配置文件使用


3.8、puppet模块

puppet的模块定义方法,类似于ansible的roles;定义模块有助于以结构化、层次化的方式使用puppet。

①模块定义的目录层次如下:默认存放在/etc/puppet/modules中,也可在配置文件中修改路径。

module_name/:模块名称manifests/:资源清单init.pp:至少应该包含一个与当前模块名称同名的类files/:静态文件;puppet:///modules/module_name/file_nametemplates/:模板文件目录;template('module_name/template_file_name')lib/:插件目录tests/:当前模块的使用帮助文件及示例文件spec/:类似于tests目录,存储lib目录下定义的插件的使用帮助及示例文件


②模块管理命令

USAGE:puppetmodule<action>[--environmentproduction][--modulepath$basemodulepath]//模块的使用方法动作使用环境:生产环境模块的路径ACTIONS:buildBuildamodulereleasepackage.//创建changesShowmodifiedfilesofaninstalledmodule.//改变的文件generateGenerateboilerplateforanewmodule.//生成一个新的模块installInstallamodulefromthePuppetForgeorareleasearchive.//安装模块listListinstalledmodules//模块列表searchSearchthePuppetForgeforamodule.//搜索模块uninstallUninstallapuppetmodule.//卸载模块upgradeUpgradeapuppetmodule.//升级模块


四、安装配置puppet的Master/Agent

4.1、配置文件 /etc/puppet/puppet.conf

显示或设置配置参数:#puppetconfigprint//显示所有参数#puppetconfigset//设置参数的值

4.2、获取puppet文档:

#puppetdoc--list//列出所有的reference参考手册#puppetdoc-rreference_name//查看某个reference参考手册


4.3、配置puppet--- Master/Agent

准备工作:node1:172.16.116.231//master,安装puppet-server,facternode2:172.16.116.232//agent,安装puppet,facter#vim/etc/hosts172.16.116.231node1172.16.116.232node2

#关键步骤:要让master和各agent基于ssh主机互信#ssh-keygen-trsa-P''#ssh-copy-id############特别强调,不能少~~否则出现下列问题##############Error:Couldnotrequestcertificate:Connectionrefused-connect(2)


1、配置Master:

启动:首次启动先查看是否存在问题,如果没有再使用-D选项(守护进程);自动生成的ca证书/var/lib/puppet/ssl目录中[root@node1~]#puppetmaster-v--no-daemonize//查看相关信息Info:CreatinganewSSLkeyforcaInfo:CreatinganewSSLcertificaterequestforcaInfo:CertificateRequestfingerprint(SHA256):5D:2F:58:58:37:C3:E5:A5:35:82:D0:3B:8F:36:7A:10:B7:93:C9:3E:CB:E2:EC:13:34:23:50:7A:C6:58:9C:87Notice:SignedcertificaterequestforcaInfo:CreatinganewcertificaterevocationlistInfo:CreatinganewSSLkeyfornode1Info:csr_attributesfileloadingfrom/etc/puppet/csr_attributes.yamlInfo:CreatinganewSSLcertificaterequestfornode1Info:CertificateRequestfingerprint(SHA256):6A:C8:00:C7:EB:CE:7A:1C:07:6B:8A:44:1C:35:B3:2B:28:7A:DE:5B:64:BE:53:BD:72:AF:8D:4F:D8:2F:9E:E6Notice:node1hasawaitingcertificaterequestNotice:Signedcertificaterequestfornode1Notice:RemovingfilePuppet::SSL::CertificateRequestnode1at'/var/lib/puppet/ssl/ca/requests/node1.pem'Notice:RemovingfilePuppet::SSL::CertificateRequestnode1at'/var/lib/puppet/ssl/certificate_requests/node1.pem'Notice:StartingPuppetmasterversion3.6.2


2、配置Agent:

[root@node2~]#puppetagent--server=node1-v--no-daemonize--test--noopInfo:CreatinganewSSLkeyfornode2Info:CachingcertificateforcaInfo:csr_attributesfileloadingfrom/etc/puppet/csr_attributes.yamlInfo:CreatinganewSSLcertificaterequestfornode2Info:CertificateRequestfingerprint(SHA256):4B:92:71:6A:48:48:37:36:C1:12:84:63:C1:C1:57:40:7E:58:5C:29:ED:D9:57:F4:B0:79:8D:AE:25:C4:AF:E1Info:Cachingcertificateforca//等待ca颁发证书Exiting;nocertificatefoundandwaitforcertisdisabled//在node1上显示如下的信息,说明已收到node2的证书申请Notice:node2hasawaitingcertificaterequest

3、crt 证书相关操作:

puppetcertsignAGENT_HOSTNAME//给某个agent签证list//列出所有的待签署证书sign//签署--all//签署所有,存在隐患,慎用~~~clean//清理指定agent证书

[root@node1~]#puppetcertlist//查看所有待签证书"node2"(SHA256)4B:92:71:6A:48:48:37:36:C1:12:84:63:C1:C1:57:40:7E:58:5C:29:ED:D9:57:F4:B0:79:8D:AE:25:C4:AF:E1[root@node1~]#puppetcertsignnode2//给node2签证Notice:Signedcertificaterequestfornode2Notice:RemovingfilePuppet::SSL::CertificateRequestnode2at'/var/lib/puppet/ssl/ca/requests/node2.pem'


4、测试

[root@node2~]#puppetagent--server=node1-v--no-daemonize//在agent上查看Info:Cachingcertificatefornode2Info:Cachingcertificate_revocation_listforcaInfo:Cachingcertificatefornode2Notice:StartingPuppetclientversion3.6.2Info:RetrievingpluginfactsInfo:RetrievingpluginInfo:Cachingcatalogfornode2Info:Applyingconfigurationversion'1448189086'Info:Creatingstatefile/var/lib/puppet/state/state.yamlNotice:Finishedcatalogrunin0.02seconds[root@node1~]#puppetmaster-v--no-daemonize//在master上查看的结果Notice:StartingPuppetmasterversion3.6.2Info:access[^/catalog/([^/]+)$]:allowing'method'findInfo:access[^/catalog/([^/]+)$]:allowing$1accessInfo:access[^/node/([^/]+)$]:allowing'method'findInfo:access[^/node/([^/]+)$]:allowing$1accessInfo:access[/certificate_revocation_list/ca]:allowing'method'findInfo:access[/certificate_revocation_list/ca]:allowing*accessInfo:access[^/report/([^/]+)$]:allowing'method'saveInfo:access[^/report/([^/]+)$]:allowing$1accessInfo:access[/file]:allowing*accessInfo:access[/certificate/ca]:addingauthenticationanyInfo:access[/certificate/ca]:allowing'method'findInfo:access[/certificate/ca]:allowing*accessInfo:access[/certificate/]:addingauthenticationanyInfo:access[/certificate/]:allowing'method'findInfo:access[/certificate/]:allowing*accessInfo:access[/certificate_request]:addingauthenticationanyInfo:access[/certificate_request]:allowing'method'findInfo:access[/certificate_request]:allowing'method'saveInfo:access[/certificate_request]:allowing*accessInfo:access[/v2.0/environments]:allowing'method'findInfo:access[/v2.0/environments]:allowing*accessInfo:access[/]:addingauthenticationanyInfo:Insertingdefault'/status'(authtrue)ACLInfo:Cachingnodefornode2Info:Cachingnodefornode2Notice:Compiledcatalogfornode2inenvironmentproductionin0.02seconds


5、定义该agnet的站点清单;在master端:

(1)安装所有要用到的模块:

#puppetmoduleinstallmodule_name

(2) 定义 site mainfest ;各agent的站点清单

#vim/etc/puppet/mainfests/site.ppnode'NODE_NAME'{...puppetcode...(类声明,也可以定义资源或变量等)}例如:node"node2"{includehttpd::web,}

至此~puppet的相关介绍及Master/Agent搭建完成~~O(∩_∩)O~~