1.什么是資源?
資源是Puppet最基礎的元素,每個資源的定義都具有標題,類型,以及一系列的屬性。
資源定義有如下的特性:
(1) Puppet使用title在編譯時區分每個資源,使用命名變量在執行時區分資源
(2)在同一類型的資源中title和namevar都是唯一的
(3)每個類型都有部分屬性有默認值
(4)如果不指定namevar,則默認賦予其title的值
2.常用的核心資源類型
notify,package,user,group,file,exec,cron,service

(1)資源介紹-Package安裝
puppet的安裝方式有yum,rpm,ports,gem,msi,dpkg,pkg等多種方式
Puppet軟件管理采用的是package資源,依賴不同的provider來完成各項功能。通常可以選擇采用默認的軟件包管理來解決各種依賴問題,這些都由Puppet根據操作系統自行判斷。
Packages常用的參數:
ensure:程序的目標狀態
absent:協助安裝包
latest:更新到最新的安裝狀態
name:資源的名稱
provider:軟件包安裝管理器
source:指定程序包文件路徑
install_options:安裝選項,最常用的就是通過INSTALLDIR來指定安裝目錄
例子1:使用Package安裝包
[root@puppet-master manifests]# vim install.pp package { 'mysql-server': ensure => 'present', ###定義目標是安裝,或者使用installed source => "puppet://$puppetserver/modules/mysql-server-5.1.73-5.el6_6.x86_64.rpm", ###指定安裝源路徑 }
$puppetserver:是在/etc/puppet/manifests/site.pp上定義的Master主機
【Agent】下發catalog
[root@puppet-agent1 ~]# puppet agent -t
Info: Retrieving pluginfacts
Info: Retrieving plugin
Info: Caching catalog for puppet-agent1.nlf.com
Info: Applying configuration version '1482310850'
Notice: /Stage[main]/Mysql::Install/Package[mysql-server]/ensure: created
Notice: Finished catalog run in 12.05 seconds
[root@puppet-agent1 ~]#
例子2:使用Package卸載安裝包
[root@puppet-master manifests]# cat install.pp
class mysql::install{
package{'mysql-server':
ensure => 'absent', ###卸載mysql服務
}
}
【Agent】下發catalog
[root@puppet-agent1 ~]# puppet agent -t
Info: Retrieving pluginfacts
Info: Retrieving plugin
Info: Caching catalog for puppet-agent1.nlf.com
Info: Applying configuration version '1482312419'
Notice: /Stage[main]/Mysql::Install/Package[mysql-server]/ensure: removed
Notice: Finished catalog run in 0.38 seconds
[root@puppet-agent1 ~]#
例子3:確保軟件包為倉庫中最新的版本
[root@puppet-master manifests]# vim install.pp
class mysql::install{
package{'mysql-server':
ensure => latest, ###安裝最新的mysql安裝包
}
}
【Agent】下發catalog
[root@puppet-agent1 ~]# puppet agent -t
Info: Retrieving pluginfacts
Info: Retrieving plugin
Info: Caching catalog for puppet-agent1.nlf.com
Info: Applying configuration version '1482371186'
Notice: /Stage[main]/Mysql::Install/Package[mysql-server]/ensure: created
Notice: Finished catalog run in 23.35 seconds
[root@puppet-agent1 ~]#
例子4:安裝多個軟件包
[root@puppet-master manifests]# vim install.pp
class mysql::install{
package{
['nginx','httpd','mysql-server']: ###安裝多個安裝包,采用數組形式安裝
ensure => installed,
}
}
【Agent】下發catalog
[root@puppet-agent1 ~]# puppet agent -t
Info: Retrieving pluginfacts
Info: Retrieving plugin
Info: Caching catalog for puppet-agent1.nlf.com
Info: Applying configuration version '1482373219'
Notice: /Stage[main]/Mysql::Install/Package[nginx]/ensure: created
Notice: /Stage[main]/Mysql::Install/Package[mysql-server]/ensure: created
Notice: /Stage[main]/Mysql::Install/Package[httpd]/ensure: created
[root@puppet-agent1 ~]#
例子5:不同操作系統選擇不同的軟件包
[root@puppet-master manifests]# vim install.pp
case $::operatingsystem{
CentOS:{
$package_list = 'mysql'
}
solaris:{
$package_list = 'httpd'
}
default:{
fail("Module does not support ${::operatingsystem}")
}
}
package { $package_list:
ensure =>present,
}
}
注釋:
$::operatingsystem:puppet調用系統類型參數類型,如Centos,solaris,SUSE等類型,可以使用命令#facter -p查看系統相關的信息
$package_list:做個別名,方便后面package的針對系統情況調用
(2)資源介紹-service管理
service 常用參數;
ensure:服務的目標狀態(true,false兩種)
enable:是否開機自啟動服務(true,false兩種)
name:服務名稱
path:服務腳本路徑
服務執行操作【start,stop,restart,status,hasrestart,hasstatus】
hasrestart:指出管理腳本是否支持restart參數,若不支持,就使用stop/start實現restart的效果。可設置為true或者false
hasstatus:指出管理腳本是否支持status參數,可設置為true或者false
pattern:設置搜索進程的匹配字符串,當init腳本不支持restart/status命令用來在進程列表中找到此服務進程以重啟或者確定狀態
restart:重啟命令
start:啟動命令
status:狀態命令
stop:停止命令
例子1:啟動服務命令
[root@puppet-master manifests]# vim service.pp
class mysql::service{
service{'mysqld':
ensure => "running", ###啟動mysql服務
enable => true, ###開機啟動服務,不啟動使用true改成false
path => "/etc/init.d", ###指定路徑,確保服務運行並隨系統啟動而啟動
}
}
【Agent】下發catalog
[root@puppet-agent1 ~]# puppet agent -t
Info: Retrieving pluginfacts
Info: Retrieving plugin
Info: Caching catalog for puppet-agent1.nlf.com
Info: Applying configuration version '1482374624'
Notice: /Stage[main]/Mysql::Service/Service[mysqld]/ensure: ensure changed 'stopped' to 'running'
Info: /Stage[main]/Mysql::Service/Service[mysqld]: Unscheduling refresh on Service[mysqld]
Notice: Finished catalog run in 1.58 seconds
[root@puppet-agent1 ~]#
例子2:觸發服務重啟
[root@puppet-master manifests]# vim service.pp
class mysql::service{
service{'httpd':
ensure => "running",
enable => true,
hasrestart => true,
hasstatus => true,
restart => "/etc/init.d/httpd reload", ###重啟httpd服務
subscribe => File["/etc/httpd/conf/httpd.conf"], ###監聽配置文件,當其有修改,立即出發重啟httpd服務
}
file{"/etc/httpd/conf/httpd.conf":
ensure => file,
source => 'puppet:///modules/mysql/httpd.conf', ###指向配置文件的存放路徑
notify => Service["httpd"], ###通知service,當配置文件有修改的時候
}
}
【Agent】下發catalog
[root@puppet-agent1 ~]# puppet agent -t
Info: Retrieving pluginfacts
Info: Retrieving plugin
Info: Caching catalog for puppet-agent1.nlf.com
Info: Applying configuration version '1482376003'
Notice: /Stage[main]/Mysql::Service/Service[httpd]/ensure: ensure changed 'stopped' to 'running'
Info: /Stage[main]/Mysql::Service/Service[httpd]: Unscheduling refresh on Service[httpd]
Notice: Finished catalog run in 0.40 seconds
Agent端測試httpd服務是否開啟
[root@puppet-agent1 ~]# lsof -i:80 ###查看端口服務是否開啟成功
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
httpd 6396 root 4u IPv6 26943 0t0 TCP *:http (LISTEN)
httpd 6400 apache 4u IPv6 26943 0t0 TCP *:http (LISTEN)
httpd 6401 apache 4u IPv6 26943 0t0 TCP *:http (LISTEN)
httpd 6402 apache 4u IPv6 26943 0t0 TCP *:http (LISTEN)
httpd 6403 apache 4u IPv6 26943 0t0 TCP *:http (LISTEN)
httpd 6404 apache 4u IPv6 26943 0t0 TCP *:http (LISTEN)
httpd 6405 apache 4u IPv6 26943 0t0 TCP *:http (LISTEN)
httpd 6406 apache 4u IPv6 26943 0t0 TCP *:http (LISTEN)
httpd 6407 apache 4u IPv6 26943 0t0 TCP *:http (LISTEN)
修改配置文件httpd.conf(存放在/etc/puppet/modules/httpd/files下面,files是專門存放模塊文件的地方),將端口80改成8080端口,測試觸發service重新啟動
[root@puppet-agent1 ~]# puppet agent -t
Info: Retrieving pluginfacts
Info: Retrieving plugin
Info: Caching catalog for puppet-agent1.nlf.com
Info: Applying configuration version '1482377523'
Notice: /Stage[main]/Mysql::Service/File[/etc/httpd/conf/httpd.conf]/content:
--- /etc/httpd/conf/httpd.conf 2014-08-15 14:57:48.000000000 +0800
+++ /tmp/puppet-file20161222-7971-ilhkw2-0 2016-12-22 19:32:02.573667445 +0800
@@ -133,7 +133,7 @@
# prevent Apache from glomming onto all bound IP addresses (0.0.0.0)
#
#Listen 12.34.56.78:80
-Listen 80 +Listen 8080
#
# Dynamic Shared Object (DSO) Support
Info: Computing checksum on file /etc/httpd/conf/httpd.conf
Info: /Stage[main]/Mysql::Service/File[/etc/httpd/conf/httpd.conf]: Filebucketed /etc/httpd/conf/httpd.conf to puppet with sum 27a5c8d9e75351b08b8ca1171e8a0bbd
Notice: /Stage[main]/Mysql::Service/File[/etc/httpd/conf/httpd.conf]/content: content changed '{md5}27a5c8d9e75351b08b8ca1171e8a0bbd' to '{md5}b7ca7a0e786418ba7b5ad84efac70265'
Info: /Stage[main]/Mysql::Service/File[/etc/httpd/conf/httpd.conf]: Scheduling refresh of Service[httpd]
Info: /Stage[main]/Mysql::Service/File[/etc/httpd/conf/httpd.conf]: Scheduling refresh of Service[httpd]
Notice: /Stage[main]/Mysql::Service/Service[httpd]: Triggered 'refresh' from 2 events
Notice: Finished catalog run in 0.59 seconds
[root@puppet-agent1 ~]# lsof -i:80 ###檢測原來的httpd服務80端口已被關閉
[root@puppet-agent1 ~]# lsof -i:8080 ###修改后的httpd服務的8080端口已被開啟
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
httpd 6396 root 6w IPv6 32082 0t0 TCP *:webcache (LISTEN)
httpd 8178 apache 6u IPv6 32082 0t0 TCP *:webcache (LISTEN)
httpd 8179 apache 6u IPv6 32082 0t0 TCP *:webcache (LISTEN)
httpd 8180 apache 6u IPv6 32082 0t0 TCP *:webcache (LISTEN)
httpd 8181 apache 6u IPv6 32082 0t0 TCP *:webcache (LISTEN)
httpd 8182 apache 6u IPv6 32082 0t0 TCP *:webcache (LISTEN)
httpd 8183 apache 6u IPv6 32082 0t0 TCP *:webcache (LISTEN)
httpd 8184 apache 6u IPv6 32082 0t0 TCP *:webcache (LISTEN)
httpd 8185 apache 6u IPv6 32082 0t0 TCP *:webcache (LISTEN)
[root@puppet-agent1 ~]#
(3)資源介紹-User管理
常用屬性:
ensure:目標狀態
選項:home shell gid uid password system comment
例子1:創建普通用戶cfj
[root@puppet-master manifests]# vim install.pp
user {'cfj':
ensure => present, ###建立用戶
uid => '502', ###指定uid號
groups => 'system', ###指定用戶組,此用戶組需要先創建
home => '/home/cfj', ###指定用戶的家目錄
shell => '/bin/bash', ###指定shell類型
expiry => '2016-12-26', ###指定用戶過期日期
}
}
【Agent】下發catalog
[root@puppet-agent1 ~]# groupadd system ###創建system
[root@puppet-agent1 ~]# puppet agent -t
Info: Retrieving pluginfacts
Info: Retrieving plugin
Info: Caching catalog for puppet-agent1.nlf.com
Info: Applying configuration version '1482724108'
Notice: /Stage[main]/Mysql::Install/User[cfj]/ensure: created
Notice: Finished catalog run in 0.13 seconds
[root@puppet-agent1 ~]# id cfj ###驗證用戶是否創建
uid=502(cfj) gid=502(cfj) groups=502(cfj),500(system)
[root@puppet-agent1 ~]#
例子2:刪除用戶cfj
[root@puppet-master manifests]# vim install.pp
user {'cfj':
ensure => absent, ###刪除用戶
}
}
[root@puppet-agent1 ~]# puppet agent -t
Info: Retrieving pluginfacts
Info: Retrieving plugin
Info: Caching catalog for puppet-agent1.nlf.com
Info: Applying configuration version '1482725099'
Notice: /Stage[main]/Mysql::Install/User[cfj]/ensure: removed
Notice: Finished catalog run in 0.12 seconds
[root@puppet-agent1 ~]# id cfj ###測試用戶是否刪除
id: cfj: No such user
[root@puppet-agent1 ~]#
(4)資源介紹- Group管理
Group組使用方法跟User類似
常用屬性:
ensure:目標狀態
name:組名稱
gid:GID
system:系統組
例子1:創建用戶組
[root@puppet-master manifests]# vim install.pp
group {'company': ###創建company組
ensure => present,
name => 'company', ###指定組名稱
gid => '5560', ###指定GID號
members => ['www','yyy'], ###指定加入改組的用戶成員 }
}
【Agent】下發catalog
[root@puppet-agent1 ~]# puppet agent -t
Info: Retrieving pluginfacts
Info: Retrieving plugin
Info: Caching catalog for puppet-agent1.nlf.com
Info: Applying configuration version '1482725855'
Notice: /Stage[main]/Mysql::Install/Group[company]/ensure: created
Notice: Finished catalog run in 0.11 seconds
[root@puppet-agent1 ~]# id www ###驗證用戶是否添加到company組
uid=500(www) gid=5561(www) groups=5561(www)
[root@puppet-agent1 ~]# id yyy ###驗證用法是否添加到conpany組
uid=501(yyy) gid=501(yyy) groups=501(yyy)
[root@puppet-agent1 ~]#
例子2:刪除用戶組
[root@puppet-master manifests]# vim install.pp
group {'company':
ensure => absent,
}
}
【Agent】下發catalog
[root@puppet-agent1 ~]# puppet agent -t
Info: Retrieving pluginfacts
Info: Retrieving plugin
Info: Caching catalog for puppet-agent1.nlf.com
Info: Applying configuration version '1482730985'
Notice: /Stage[main]/Mysql::Install/Group[company]/ensure: removed
Notice: Finished catalog run in 0.15 seconds
(5)資源介紹- Cron管理
定時腳本用於安裝和管理系統cron作用,每一個cron的資源要有命令和至少一個周期的屬性(hour小時,minute分鍾,month月,monthday月的第一天,special特殊)。定義腳本這些屬性都由Puppet存儲與檢索。
Puppet會將任務寫入/var/spool/cron目錄中與用戶對應的文件中,/etc/crontab中原有的任務不會變,如果Puppet指定的任務與信啊有任務完全一致,Puppet不會對此有任何的修改。建議cron完全有Puppet管理,不然可能會出現難以預料的情況,其中特別要注意的就是出現定義了不同的任務而任務目的完全一致的情況。
cron資源常用參數:
ensure; 目標狀態(present,abset)
command: 需要執行的命令,通常使用雙引號引起來
environment:運行的環境變量配置,例如PATH=/bin/:/usr/bin/;/usr/sbin
hour: 小時(0-23)
minute: 分鍾(0-59)
month: 月(1-12)
monthday: 月中的天(1-31)
weekday: 周中的天(0-7)
name: 名稱
user: 指定運行的用戶,默認是root
target: 指定用戶的cron項,默認為用戶的shell
special: 特殊的配置
provider:指定后端使用cron資源,通常不指定
例子1:假設每天早上6點執行一次ntpdate
【crontab寫法如下】
#crontab -l
0 6 * * * /usr/sbin/ntpdate ntpserver.nlf.com
在Puppet的寫法如下:
[root@puppet-master manifests]# vim install.pp
cron {'ntpdate':
command => "/usr/sbin/ntpdate ntpserver.nlf.com",
user => root,
hour => 6,
minute => 0,
}
}
例子2:假設每兩個小時執行一次ntpdate
【crontab 寫入如下】
#crontab -l
0 */2 * * * /usr/sbin/ntpdate ntpserver.nlf.com
在Puppet的寫法如下:
[root@puppet-master manifests]# vim install.pp
cron {'ntpdate':
command => "/usr/sbin/ntpdate ntpserver.nlf.com",
user => root,
hour => '*/2',
minute => 0,
}
}
例子3:假設晚上11點到早上8點之間每兩個小時,以及早上8點執行一次ntpdate
【crontab 寫入如下】
#crontab -l
0 23-7/2,8 * * * /usr/sbin/ntpdate ntpserver.nlf.com
在Puppet的寫法如下:
[root@puppet-master manifests]# vim install.pp
cron {'ntpdate':
command => "/usr/sbin/ntpdate ntpserver.nlf.com",
user => root,
hour => '23-7/2,8',
minute => 0,
}
}
(6)資源介紹- exec管理
執行外部命令,通常建議減少使用或者盡量避免exec資源,Puppetlabs也不建議使用,創建exec資源是為完成一些Puppet無法完成的事情。
盡量少使用exec資源,同時在使用exec資源時盡量使用refreshonly和creates屬性,少用onlyif和unless屬性。即使要使用exec資源也要用簡單的系統命令,因為每次Puppet執行時候所編譯的Catalog中的命令都會去執行,這樣會帶來大量的胸痛開銷與不必要的資源浪費。
exec常用的屬性:
creates: 文件不存在才執行
refreshonly:收到同時時才執行
onlyif: 命令執行成功返回0執行
unless: 命令執行不成功返回非0時執行
exec資源常用的參數:
command: 執行的命令,必須是完整的,合法的命令
creates: 指定命令生成的文件;如果提供了這個參數,那么命令只會在所指定的文件不存在情況下才會被執行
cwd: 指定命令執行的當前目錄,如果目錄不存在,則會被執行失敗
environment:為命令設置額外的環境變量,指定path,會覆蓋path的定義,多個環境變量應該
group: 運行命令的用戶組
logoutput:是否記錄輸出,默認為on_failure,還可以定義為true或false
onlyif: 參數中設置的命令返回0才執行
path: 執行命令的搜索路徑,如果不指定時命令必須是全部路徑,可以采用全路徑數組,使用冒號進行分隔
refresh: 定義如何更新此命令,在exec接收到其他資源並通知刷新,默認在執行一次,但可以定義一個不同的命令
refreshonly:該參數可以使命令變成僅刷新觸發的,也就是說只有在一個依賴的對象被改變時,命令才會被執行,僅當命令與其他對象有依賴關系,這個參數才有意義。當要觸發某個行為時,這個參數會顯得很有用。
timeout: 命令執行超時時間,默認300s
returns: 命令返回碼,默認返回0,可指定返回碼或單個值的數組
tires: 嘗試執行次數,默認為1,如果命令返回值與returns返回碼不一致將會重試
unless: 結束代碼,正常情況下命令返回值是標准輸出內容,為0才執行
user: 定義執行命令的用戶
例子1:在Linux下執行echo “foo” 輸出
[root@puppet-master manifests]# vim install.pp
exec {'echo foo':
command => 'echo "foo"',
path => "/usr/bin:/usr/sbin:/bin", ###需要指定path路徑,否則Puppet會找不到執行命令的路徑
}
}
例子2:解壓xxx.tar.gz文件到/tmp目錄,如果“/tmp/myfile”,文件不存在,則執行exec命令;如果文件存在,則不執行。
[root@puppet-master manifests]# vim install.pp
exec {'tar -zxf /tmp/nginx-1.3.8.tar.gz':
cwd => '/tmp', ###進入tmp目錄
creates => '/tmp/myfile', ###當/tmp/myfile不存在時候,執行exec命令
path => ['/usr/bin/','/usr/sbin','/bin'],
} }
例子3:當命令返回值為0時候,exec資源命令才會被執行
[root@puppet-master manifests]# vim install.pp
exec {'nginx -s reload':
path => '/usr/bin:/usr/sbin:/bin',
refreshonly => true,
onlyif => 'nginx -t /etc/nginx/nginx.conf',
tries => 3,
try_sleep => 5,
}
}
以上代碼定義一條命令“nginx -s reload”,只有當"nginx -t /etc/nginx/nginx.conf"命令返回0時,”nginx -s reload“ 才會執行,同樣定義了命令重復次數為3次,每次相隔5秒
例子4:當文件被更新觸發該資源被執行
[root@puppet-master manifests]# vim install.pp
file {'/etc/aliases':
source => 'puppet://server/modules/aliases',
}
exec {'newaliases':
path => ["/usr/bin","/usr/sbin"],
subscribe => File["/etc/aliases"],
refreshonly => true,
}
}
以上代碼中,只有當文件"/etc/aliases" 再次被更新時才會觸發newaliases動作,需要注意的是,只有subscribe和notify可以觸發行為,所有refreshonly需要配置subscribe和notify才有意義;
refreshonly屬性的默認值為false,可接受的值有true和false
(7)資源介紹- file管理
File資源也是我們最常用的資源之一,其配置方法具有多元化,它也是影響Puppet執行效率的關鍵。
File作用:
(1)管理文件,目錄,符號鏈接
(2)管理文件內容,屬性,權限
(3)通過屬性來指定文件來源,也可以通過source屬性從遠處服務器下載
(4)設置recurse屬性來true或local來直接傳輸整個目錄
常用屬性:
ensure;目標狀態(present,absent,file,directory)
backup:通過filebucket資源來備份文件,值通常為filebucket資源的名稱
content:文件內容,生成方式三種(content,source,target)
source:通過制定的url下載到本地,獲取方式通常為puppet url,格式為puppet://modules/MODULE_name/file_name
target:指定符號鏈接
link:文件為符號鏈接
path:文件路徑
mode:定義權限
owner:屬主
group:屬組
force:強制執行刪除文件
purge:清空指定目錄中的存在的,但未在資源中定義的文件
recurse:目錄遞歸,值為true,false,inf,remote
replace:替換,本地存在的文件與資源中指定的文件內容不同時是否執行替換,默認是否
例子1:file創建文件
方式1:
[root@puppet-master manifests]# cat install.pp
class mysql::install{
file{'/tmp/test':
ensure => file,
}
}
【Agent】下發catalog
[root@puppet-agent1 ~]# puppet agent -t
Info: Retrieving pluginfacts
Info: Retrieving plugin
Info: Caching catalog for puppet-agent1.nlf.com
Info: Applying configuration version '1483501191'
Notice: /Stage[main]/Mysql::Install/File[/tmp/test]/ensure: created
Notice: Finished catalog run in 0.10 seconds
方式2:
[root@puppet-master manifests]# cat install.pp class mysql::install{ file{'test': path => '/tmp/file', ensure => present, } }
以上代碼中的寫法為簡寫方式,也是相對比較規范的寫法,這種簡寫方式可以運用於其他資源;
在使用require等元參數進行資源依賴的時候可以直接指定資源的title,不用寫太長的path內容,例如代碼如下:
require => File['/tmp/test'],
例子2: 創建一個目錄
file {'/tmp/testdir':
ensure => directory,
}
例子3: 創建一個符號鏈接
file {'/tmp/test':
ensure => 'link',
target =>'/tmp/testlink',
}
定義ensure屬性代碼為link,代表該文件資源是軟鏈接,使用target屬性指定目標文件,即為軟鏈接
例子4:將服務器文件同步至本地
file {'test': name => ‘/tmp/test’, ensure => present, source => 'puppet://$fileserver/modules/test/test' } 在以上代碼中,定義了從Puppet Master服務器上讀取文件至本地,變量$fileserver在site.pp文件中定義“$fileserver=puppet.domain.com”.這個時候test文件需要創建在/etc/puppet/files/"{modules_name}"/test中
