Puppet 之 八大資源介紹
資源是puppet最基本的元素,每個資源的定義都具有標題、類型以及一系列的屬性。puppet的特性就是處理資源與資源之間的依賴關系。任何相同類型的資源都會具有一些相同的屬性。
資源定義有如下的特性:
a.puppet使用title在編譯時期區分每個資源,使用命名變量(namevar)在執行時區分資源。
b.在同一類資源中title和namevar都是唯一的。
c.每個類型都有部分屬性有默認值
d.如果不指定namevar,則默認賦予其title的值。
在puppet 3.6.2版本中,通過命令puppet describe --list可以查看到目前有49種資源類型,本文將結合例子介紹puppet的8種核心資源類型,如下
group: 組
user:用戶
packge:程序包
service:服務
file:文件
exec:執行自定義命令,要求冪等
cron:周期性任務計劃
notify:通知
其他類型的解釋見如下的文檔
https://docs.puppet.com/puppet/5.2/cheatsheet_core_types.html#notify
2 八大核心資源
group:管理組
屬性:
name:組名;
gid:GID;
system:是否為系統組,true OR false;
ensure:目標狀態,present/absent;
members:成員用戶;
例子,定義資源清單,最後一個逗號可以寫也可以省略
vim group.pp group{'mygrp': ensure => present, name => mygrp66, system => true, }
測試資源情況
puppet apply -v --noop group.pp
如果測試通過,執行資源
puppet apply group.pp
註意:type必須使用小寫字符;title是一個字符串,在同一類型中必須惟一;
user:管理用戶
Manage users.
屬性:
name:用戶名;
uid: UID;
gid:基本組ID;
groups:附加組,不能包含基本組;
comment:註釋;
expiry:過期時間 ;
home:家目錄;
shell:默認shell類型;
system:是否為系統用戶 ;
ensure:present/absent;
password:加密後的密碼串;
例子
例子,創建一個用戶,同時指定多個附加組,用列表實現,這裏假設組testgrp不存在,執行會報錯,所以可以定義依賴關系,用require來定義依賴關系,這裏引用的是資源,所以對應的資源要存在,假設sunnygrp組已經存在,但是還是要定義mygrp這個資源
vim user.pp group{'testgrp': ensure => present, } user{'myuser': ensure => present, name => 'sunny66', uid => 3333, shell => '/sbin/nologin', groups => [sunnygrp,testgrp], require => [Group['sunnygrp'],Group['testgrp']], } group{'sunnygrp': ensure => present, system => true, name => 'sunnygrp', }
關系元參數:before/require
A before B: B依賴於A,定義在A資源中;
{ ... before => Type['B'], ... }
B require A: B依賴於A,定義在B資源中;
{ ... require => Type['A'], ... }
例子
依賴關系的第二種定義方法
vim user.pp group{'testgrp1': ensure => present, before => User['myuser1'], } user{'myuser1': ensure => present, name => 'sunny666', uid => 2222, shell => '/sbin/nologin', groups => [sunnygrp1,testgrp1], } group{'sunnygrp1': ensure => present, system => true, name => 'sunnygrp1', before => User['myuser1'], }
package:管理程序包
屬性:
ensure:installed, present, latest, absent, any version string (implies present)
name:包名;註意,如果不指定name,name這個名字默認就是title的名稱
source:程序包來源,僅對不會自動下載相關程序包的provider有用,例如rpm或dpkg;不同操作系統的安裝方法,一般不需要指定,因為會自動安裝
例子,安裝redis包
package{'redis': ensure => latest, }
service:管理運行服務
屬性:
ensure:服務是否應該運行。 有效值為“stopped”(也稱為“false”),“runnig”(也稱為“true”)。
enable:是否應開機啟用服務。 有效值為“true”,“false”,“manual”。
name:啟動的服務名稱
path:用於查找init腳本的搜索路徑。 多個值應該用冒號分隔或作為數組提供..腳本的搜索路徑,默認path為/etc/init.d/;
hasrestart:是否支持啟動功能,如果是true,則直接restart,如果如false,就執行stop後執行start來重啟,默認false
hasstatus:默認true
start:手動定義啟動命令;
stop:停止服務
status:服務狀態
restart:手動指定*restart*命令。 如果未指定,服務將被停止,然後啟動。 通常用於定義reload操作;
binary:啟動服務,啟動程序的路徑
path:啟動服務腳本路徑
例子
啟動redis,有依賴關系,假設卸掉redis,但是測試還是正常,真正執行的時候卻失敗了,因此啟動服務腳本中定義資源package
vim service.pp service{'redis': ensure => running, enable => true, hasrestart => true, restart => 'systemctl restart redis', require => Package['redis'], } package{'redis': ensure => latest, }
file:管理文件
管理文件其內容,所有權和權限。
ensure:文件是否應該存在,如果是,應該是什麽類型的文件。 可能的值是“present”,“absent”,“file”,“directory”和“link”。
file:類型為普通文件,其內容由content屬性生成或復制由source屬性指向的文件路徑來創建;
link:類型為符號鏈接文件,必須由target屬性指明其鏈接的目標文件;
directory:類型為目錄,可通過source指向的路徑復制生成,recurse屬性指明是否遞歸復制;
path:文件路徑;
source:源文件;
content:文件內容;
target:符號鏈接的目標文件;
owner:屬主
group:屬組
mode:權限;
atime/ctime/mtime:時間戳;
例子
復制文件,先復制一份redis配置文件,並進行修改,然後通過puppet的file進行復制到對應主機
cp /etc/redis.conf /root、 vim file.pp file{'/etc/redis.conf': ensure => file, source => '/root/redis.conf', owner => 'redis', group => 'root', mode => '0644', }
例子
復制目錄,註意,以下recurse對應的true是布爾值,不能加引號
vim file.pp file{'yumfile': ensure => directory, path => '/tmp/yum.repos.d/', source => '/etc/yum.repos.d/', recurse => true, }
復制文件到目錄下,那麽ensure為directory配置就不會生效,直接復制為一個文件,而不生成目錄,即如下的例子中,只會在/tmp下生成一個名為test的文件,內容是/etc/issue的內容,而不會在/tmp/test這個目錄下生成issue這個文件
file{'test': ensure => directory, path => '/tmp/test', source => '/etc/issue', }
如果有多個源文件,那麽只會復制一個文件,如下例子,只會復制/etc/issue這個文件,新生成的文件名為/tmp/test
file{'test': ensure => directory, path => '/tmp/test', source => ['/etc/issue','/etc/group'], }
例子
創建鏈接
file{'redis.conf': ensure => link, path => '/tmp/redis.conf', target => '/etc/redis.conf', }
通知元參數:訂閱或者通知關系
A notify B:B依賴於A,接受由A觸發refresh;
B subscribe A:B依賴於A,接受由A觸發refresh;B監控A資源的內容變化,一定A變化,B要跟著發送對應變化
在一資源中,notify和suscribe只需要二者選一個即可
通知關系:通知相關的其它資源進行“刷新”操作;
notify
A notify B:B依賴於A,且A發生改變後會通知B;
{ ... notify => Type['B'], ... }
subscribe
B subscribe A:B依賴於A,且B監控A資源的變化產生的事件;
{ ... subscribe => Type['A'], ... }
例子:
安裝redis,並啟動redis服務,當redis的配置文件更改時,重啟服務,用通知鏈表示表示依賴關系
vim service.pp service{'redis': ensure => running, enable => true, hasrestart => true, restart => 'systemctl restart redis', subscribe => File['redis.conf'], } package{'redis': ensure => latest, } file{'redis.conf': path => '/etc/redis.conf', source => '/root/redis.conf', ensure => file, mode => '0644', owner => redis, group => root, # notify => Service['redis'], } Package['redis'] -> File['redis.conf'] ~> Service['redis']
以上例子,可以改成如下,->表示package先於file,~>表示file先於service,同時service訂閱了file
#service with notify or subscribe package{'redis': ensure => latest, } -> file{'redis.conf': path => '/etc/redis.conf', source => '/root/redis.conf', ensure => file, mode => '0644', owner => redis, group => root, } ~> service{'redis': ensure => running, enable => true, hasrestart => true, restart => 'systemctl restart redis', }
依賴關系:當某個條件執行後,才會執行
before
require
例子:
以下例子,File['test.symlink']依賴於File['test.txt'],只有當File['test.txt']資源執行,File['test.symlink']才會被執行
file{'test.txt': path => '/tmp/test.txt', ensure => file, source => '/etc/fstab', } file{'test.symlink': path => '/tmp/test.symlink', ensure => link, target => '/tmp/test.txt', require => File['test.txt'], }
以上例子可以調整如下,資源File['test.txt']執行後才會執行File['test.symlink']
file{'test.txt': path => '/tmp/test.txt', ensure => file, source => '/etc/fstab', before => File['test.symlink'], } file{'test.symlink': path => '/tmp/test.sysmlink', target => '/tmp/test.txt', ensure => link, }
exec:執行外部命令
exec資源中的任何命令必須能夠運行多次而不會造成危害,即它必須是冪等的。
**command** (*namevar*):要運行的命令;
cwd:運行該命令的目錄。
creates:文件路徑,僅此路徑表示的文件不存在時,command方才執行;
user/group:運行命令的用戶身份;
path:用於命令執行的搜索路徑。 如果沒有指定路徑,則命令必須是絕對路徑。
onlyif:此屬性指定一個命令,此命令正常(退出碼為0)運行時,當前command才會運行;
unless:此屬性指定一個命令,此命令非正常(退出碼為非0)運行時,當前command才會運行;
refresh:重新執行當前command的替代命令;
refreshonly:僅接收到訂閱的資源的通知時方才運行;
例子:
創建目錄
mkdir不冪等,因此定義creates,只有/tmp/hi.dir/不存在時才執行command
vim exec.pp exec{'makedir': command => 'mkdir /tmp/hi.dir', path => '/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin', creates => '/tmp/hi.dir', }
創建用戶
其中,unless表示只有id sunny88失敗,那麽command命令才會執行,如果id sunny88成功了,那麽command命令就不會執行,即只有sunny88用戶不存在的時候才會執行command命令
exec{'createuser': command => 'useradd sunny88', path => '/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin', unless => 'id sunny88', }
安裝包
安裝tree服務包,只有查找到sunny倉庫時才會執行command
exec{'installpkg': command => 'yum -y install tree', path => '/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin', onlyif => 'yum repolist | grep -i sunny', }
newaliases是一個命令,只有當/etc/aliases文件發送變化後才會執行newaliases
file{'/etc/aliases': path => '/etc/aliases', ensure => file, before => Exec['newaliases'], } exec{'newaliases': path => ["/usr/local/sbin","/usr/local/bin","/usr/local","/usr/bin"], subscribe => File["/etc/aliases"], refreshonly => true, }
例子
為redis服務器生成配置文件,當模板配置文件改變時,通知exec['backupfile'],並且將本次變化後的配置文件備份到指定路徑下,這裏有個問題是,第一次的配置文件將不會被備份,因此要手動備份第一次的配置文件
註意,以下的cp命令不冪等,因此復制的時候,建議將備份的文件新增名字後加上時間為後綴。為redis.conf-$(date +%F-%H-%M-%S),防止沖突
file{'/etc/redis.conf': source => '/root/redis.conf', ensure => file, } exec{'mkdir': command => 'mkdir /backups', path => '/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin', unless => 'ls /backups', before => Exec['backupfile'], } exec{'backupfile': command => "cp /etc/redis.conf /backups/redis.conf-$(date +%F-%H-%M-%S)", path => '/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin', refreshonly => true, subscribe => File['/etc/redis.conf'], }
cron:安裝和管理cron作業
每個由Puppet創建的cron資源都需要一個命令和至少一個周期性屬性(小時,分鐘,月份,月份,工作日或特殊)。
command:要執行的任務;
ensure:present/absent;
hour:
minute:
monthday:
month:
weekday:
user:以哪個用戶的身份運行命令
target:添加為哪個用戶的任務
name:cron job的名稱;
示例:每隔三分鐘執行一次計劃任務
cron{'timesync': command => '/usr/sbin/ntpdate 172.18.50.61 &> /dev/null', ensure => present, minute => '*/3', user => 'root', }
notify:發送消息
將任意消息發送到代理運行時日誌。
屬性:
message:信息內容
name:信息名稱;
例子
發出通知消息
notify{'hello': message => 'hello everyone,I am sunny', name => 'Say hello', }
到這裏,8大核心資源的定義和使用介紹完成。
Puppet 之 八大資源介紹