1. 程式人生 > >Puppet 之 八大資源介紹

Puppet 之 八大資源介紹

puppet 核心資源

1 概述


資源是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 之 八大資源介紹