自動化運維工具-----puppet入門詳解

一.三大運維工具的比較

  • 下表是各大自動化工具的使用下載情況

  • 下表則是三大運維工具的簡介以及優缺點
名稱 簡介 優點 缺點
Puppet 是一個開源的軟件自動化配置和部署工具,它使用簡單且功能強大,很多大型IT公司均在使用puppet對集羣種的軟件進行管理和部署 能夠在web界面生成處理報表、資源清單、實時節點管理,push命令可即刻觸發變更 相對於其他工具較爲複雜,需要學習puppet的DSL或者Ruby,安裝過程缺少錯誤校驗和生成錯誤報表
SaltStack 是一種全新的基礎設施管理方式,部署輕鬆,在幾分鐘內可以運行起來,擴展性能好,很容易管理上萬臺服務器,速度夠快,服務器之間毫秒級通訊 可以使用簡單的配置模塊或者複雜的腳本,web界面可以看到運行和監控的工作狀態、事件日誌、擴展能力極強。 缺少生成深度報告的能力
Ansible 是新出現的運維工具,是基於Python開發的綜合了衆多老牌運維工具的優點實現了批量操作系統配置、批量程序的部署、批量運行命令等功能。 模塊可以用任何語言開發、被管理節點不需要安裝代理軟件、有web管理界面、安裝運行簡單 對windows被管理節點需要加強、執行效率相對較低

二.puppet簡介

  • puppet是一個IT基礎設施自動化管理工具,它能夠幫助系統管理員管理基礎設施的整個生命週期,包括:供應(provisioning)、配置(configuration)、聯動(orchestration)以及報告(reporting)。
  • 基於puppet,可以實現自動化重複任務、快速部署關鍵性的應用以及在本地或者雲端完成主動管理變更和快速擴展架構規模等。
  • puppet遵循GPL協議(2.7.-),基於ruby語言開發。2.7.0以後使用(Apache 2.0 license)
  • 對於系統管理員是抽象的,只依賴於ruby與facter。
  • 能夠管理多達40種資源,例如:file、user、group、host、package、service、cron、exec、yum repo等。
  • 如下爲puppet官網:https://puppet.com/

三.puppet的工作機制

puppet的工作模型

  • puppet通過聲明性、基於模型的方法進行IT自動化管理。
  • 定義:通過puppet的聲明性配置語言定義基礎設置配置的目標狀態;
  • 模擬:強制應用改變的配置之前先進行的模擬性應用;
  • 強制:自動、強制部署達成目標狀態,糾正任何偏離的配置;
  • 報告:報告當下狀態以及目標狀態的不同,以及達成目標狀態所進行的任何強制性改變。
  • puppet的三層模型如下所示:

puppet的工作流程

puppet的使用模型

  • puppet的使用模型分爲單擊使用模型和master/agent使用模型,下面我們來看看這兩個模型的原理

單機模型

  • 實現定義了多個manifests--》complier--》catalog--》apply

master/Agent模型

  • master/Agent模型實現的是集中式管理,即agent端週期性向master端發起請求,請求自己需要的數據,然後在自己的機器上運行,並且將結果返回給master端
  • master/Agent模型的架構如下:

  • master/Agent模型的工作原理

puppet相關名詞解釋

  • 資源:是puppet的核心,通過資源申報,定義在資源清單之中。
  • 類:一組資源清單。
  • 模塊:包含多個類
  • 站點清單:以主機爲核心,應用哪些模塊

四.puppet的資源詳解

pupet的安裝

  • puppet的安裝可以使用源碼安裝,也可以使用rpm(官方提供)、epel源、官方提供的yum倉庫來安裝(通過下載官方提供的rpm包可以指定官方的yum倉庫)
  • 以下使用yum安裝puppet
[root@cloud ~]# yum install -y puppet
  • 安裝完成之後,可以查看puppet下載後都有什麼包,其中/etc/puppet/puppet.conf爲主配置文件,使用的主程序爲/usr/bin/puppet
[root@cloud ~]# rpm -ql puppet | grep etc
/etc/NetworkManager
/etc/NetworkManager/dispatcher.d
/etc/NetworkManager/dispatcher.d/98-puppet
/etc/logrotate.d/puppet
/etc/puppet
/etc/puppet/auth.conf
/etc/puppet/modules
/etc/puppet/puppet.conf
/usr/share/doc/puppet-3.6.2/examples/hiera/etc
/usr/share/doc/puppet-3.6.2/examples/hiera/etc/hiera.yaml
/usr/share/doc/puppet-3.6.2/examples/hiera/etc/hieradb
/usr/share/doc/puppet-3.6.2/examples/hiera/etc/hieradb/common.yaml
/usr/share/doc/puppet-3.6.2/examples/hiera/etc/hieradb/dc1.yaml
/usr/share/doc/puppet-3.6.2/examples/hiera/etc/hieradb/development.yaml
/usr/share/doc/puppet-3.6.2/examples/hiera/etc/puppet.conf
[root@cloud ~]# 

pupet資源簡介

資源抽象

  • puppet可以從以下三個維度來對資源完成抽象:

1.相似的資源被抽象成同一種資源“類型”,如程序包資源、用戶資源以及服務資源等;

2.將資源屬性或者狀態的描述與其實現方式剝離開來,如僅僅說明安裝一個程序包而不用關心其具體是通過yum、pkgadd、ports或是其他方式實現;

3.僅僅描述資源的目標狀態,也即期望其實現的結果,而不是具體過程,如確定nginx運行起來而不是具體描述爲“運行nginx命令將其啓動起來”;

  • 這三個也被稱爲puppet的資源抽象層(RAL)
  • RAL由type(類型)和provider(提供者,即不同OS上的特定實現)組成

資源定義

  • 資源定義通過向資源的屬性複製來實現,可以稱爲資源類型實例化;
  • 定義了資源實例的文件即清單,manifest;
  • 定義資源的語法如下:
type {'title':
        attribute1   => value1,
        attribute2   => value2,
        ...

}

注意:type必須使用小寫字母;title是一個字符串,在同一類型中必須唯一,每一個屬性之間要用逗號隔開,最後一個逗號可以省略。

例如,可以同時有名爲nginx的“service資源”和“package”資源,但是在“package“類型的資源中只能有一個名爲”nginx“的資源。

資源屬性

  • Namevar:可以簡稱爲name;
  • ensure:資源的目標狀態
  • Provider:指明資源的管理接口

puppet常用資源

  • 我們可以使用puppet describe來打印有關的puppet資源類型,提供者和元參數的幫助,使用的語法如下:
puppet decribe [-h|--help] [-s|--short] [-p|--providers] [-l | --list] [-m | --meta] [type]

-s:顯示指定類型的簡要幫助信息;
-m:顯示指定類型的元參數,一般與-s一起使用
-l:列出所有資源的類型

group:管理系統上的用戶組

  • 查看group的幫助信息
[root@cloud ~]# puppet describe group -s -m

group
=====
Manage groups. On most platforms this can only create groups.
Group membership must be managed on individual users.
On some platforms such as OS X, group membership is managed as an
attribute of the group, not the user record. Providers must have
the feature 'manages_members' to manage the 'members' property of
a group record.


Parameters
----------
    allowdupe, attribute_membership, attributes, auth_membership, ensure,
    forcelocal, gid, ia_load_module, members, name, system

Meta Parameters
---------------
    alias, audit, before, loglevel, noop, notify, require, schedule, stage,
    subscribe, tag

Providers
---------
    aix, directoryservice, groupadd, ldap, pw, windows_adsi
[root@cloud ~]# 

##相關屬性
name:組名,可以省略。如果省略,將繼承title的值;
gid:組ID;
system:是否爲系統組,true OR false
ensure:目標狀態,present/absent;
members:成員用戶;


##簡單舉例如下
vi group.pp
    group{'mygroup':
    name => 'mygroup',
    ensure => present,
    gid => 2000,

    }
  • 試運行group.php
[root@cloud demo]# ls
group.pp
[root@cloud demo]# cat group.pp 
 group{'mygroup':
    name => 'mygroup',
    ensure => present,
    gid => 2000,

    }
##試運行
[root@cloud demo]# puppet apply -v  --noop group.pp 
Error: NetworkManager is not running.
Notice: Compiled catalog for cloud in environment production in 0.08 seconds
Info: Applying configuration version '1588746101'
Notice: /Stage[main]/Main/Group[mygroup]/ensure: current_value absent, should be present (noop)
Notice: Class[Main]: Would have triggered 'refresh' from 1 events
Notice: Stage[main]: Would have triggered 'refresh' from 1 events
Info: Creating state file /var/lib/puppet/state/state.yaml
Notice: Finished catalog run in 0.02 seconds
##正式運行
puppet apply -v group.pp

user:管理系統上的用戶

  • 查看使用幫助信息
[root@cloud demo]# puppet describe user -s -m

user
====
Manage users.  This type is mostly built to manage system
users, so it is lacking some features useful for managing normal
users.
This resource type uses the prescribed native tools for creating
groups and generally uses POSIX APIs for retrieving information
about them.  It does not directly modify `/etc/passwd` or anything.
**Autorequires:** If Puppet is managing the user's primary group (as
provided in the `gid` attribute), the user resource will autorequire
that group. If Puppet is managing any role accounts corresponding to the
user's roles, the user resource will autorequire those role accounts.


Parameters
----------
    allowdupe, attribute_membership, attributes, auth_membership, auths,
    comment, ensure, expiry, forcelocal, gid, groups, home, ia_load_module,
    iterations, key_membership, keys, managehome, membership, name,
    password, password_max_age, password_min_age, profile_membership,
    profiles, project, purge_ssh_keys, role_membership, roles, salt, shell,
    system, uid

Meta Parameters
---------------
    alias, audit, before, loglevel, noop, notify, require, schedule, stage,
    subscribe, tag

Providers
---------
    aix, directoryservice, hpuxuseradd, ldap, pw, user_role_add, useradd,
    windows_adsi
[root@cloud demo]# 

##相關屬性的解析
name:用戶名,可以省略,如果省略,將繼承title的值;
uid:UID;
gid:基本組ID;
groups:附加組,不能包含基本組;
comment:註釋;
expiry:過期時間;
home:用戶的家目錄;
shell:默認shell類型
system:是否爲系統用戶;
ensure:present/absent;
password:加密後的密碼串;
  • 簡單舉例如下:
vi user1.pp
    user{'keerr':
    ensure => present,
    system => false,
    comment => 'Test User',
    shell => '/bin/tcsh',
    home => '/data/keerr',
    managehome => true,
    groups => 'mygrp',
    uid => 3000,

    }

package:puppet的管理軟件包

  • 查看使用幫助信息:
[root@cloud demo]# puppet describe package -s -m

package
=======
Manage packages.  There is a basic dichotomy in package
support right now:  Some package types (e.g., yum and apt) can
retrieve their own package files, while others (e.g., rpm and sun)
cannot.  For those package formats that cannot retrieve their own files,
you can use the `source` parameter to point to the correct file.
Puppet will automatically guess the packaging format that you are
using based on the platform you are on, but you can override it
using the `provider` parameter; each provider defines what it
requires in order to function, and you must meet those requirements
to use a given provider.
**Autorequires:** If Puppet is managing the files specified as a
package's `adminfile`, `responsefile`, or `source`, the package
resource will autorequire those files.


Parameters
----------
    adminfile, allow_virtual, allowcdrom, category, configfiles,
    description, ensure, flavor, install_options, instance, name,
    package_settings, platform, responsefile, root, source, status,
    uninstall_options, vendor

Meta Parameters
---------------
    alias, audit, before, loglevel, noop, notify, require, schedule, stage,
    subscribe, tag

Providers
---------
    aix, appdmg, apple, apt, aptitude, aptrpm, blastwave, dpkg, fink,
    freebsd, gem, hpux, macports, msi, nim, openbsd, opkg, pacman, pip, pkg,
    pkgdmg, pkgin, pkgutil, portage, ports, portupgrade, rpm, rug, sun,
    sunfreeware, up2date, urpmi, windows, yum, zypper
[root@cloud demo]# 


##屬性
ensure:installd,present,latest,absent,any version string(implies present)
name:包名,可以省略,如果省略,將繼承title的值;
source:程序包來源,僅僅對不會自動下載相關程序包的provider有用,例如rpm或dpkg
provider:指明安裝方式


##簡單舉例如下:
vi package1.pp
    package {'nginx':
        ensure => installed,
        provider => yum
}

service:定義服務的狀態

  • 查看使用幫助信息:
[root@cloud demo]# puppet describe service -s -m

service
=======
Manage running services.  Service support unfortunately varies
widely by platform --- some platforms have very little if any concept of a
running service, and some have a very codified and powerful concept.
Puppet's service support is usually capable of doing the right thing, but
the more information you can provide, the better behaviour you will get.
Puppet 2.7 and newer expect init scripts to have a working status command.
If this isn't the case for any of your services' init scripts, you will
need to set `hasstatus` to false and possibly specify a custom status
command in the `status` attribute. As a last resort, Puppet will attempt to
search the process table by calling whatever command is listed in the `ps`
fact. The default search pattern is the name of the service, but you can
specify it with the `pattern` attribute.
**Refresh:** `service` resources can respond to refresh events (via
`notify`, `subscribe`, or the `~>` arrow). If a `service` receives an
event from another resource, Puppet will restart the service it manages.
The actual command used to restart the service depends on the platform and
can be configured:
* If you set `hasrestart` to true, Puppet will use the init script's restart
command.
* You can provide an explicit command for restarting with the `restart`
attribute.
* If you do neither, the service's stop and start commands will be used.


Parameters
----------
    binary, control, enable, ensure, flags, hasrestart, hasstatus, manifest,
    name, path, pattern, restart, start, status, stop

Meta Parameters
---------------
    alias, audit, before, loglevel, noop, notify, require, schedule, stage,
    subscribe, tag

Providers
---------
    base, bsd, daemontools, debian, freebsd, gentoo, init, launchd, openbsd,
    openrc, openwrt, redhat, runit, service, smf, src, systemd, upstart,
    windows
[root@cloud demo]# 
  • service的相關屬性
ensure:服務的目標狀態,只有true(running)和false(stopped)
enable:是否可以開機自動啓動,值有true和false
name:服務名稱,可以省略,如果省略,將繼承title的值
path:服務腳本路徑默認爲/etc/init.d下
start:定製啓動命令
stop:定製關閉命令
restart:定製重啓命令
status:定製狀態
  • service的舉例文件如下:
vi service1.pp
    service{'nginx':
    ensure => true,
    enable => false
    }

 

file:管理文件、目錄、軟連接

  • 查看使用幫助信息
[root@cloud ~]# puppet describe file -s -m

file
====
Manages files, including their content, ownership, and permissions.
The `file` type can manage normal files, directories, and symlinks; the
type should be specified in the `ensure` attribute. Note that symlinks
cannot
be managed on Windows systems.
File contents can be managed directly with the `content` attribute, or
downloaded from a remote source using the `source` attribute; the latter
can also be used to recursively serve directories (when the `recurse`
attribute is set to `true` or `local`). On Windows, note that file
contents are managed in binary mode; Puppet never automatically translates
line endings.
**Autorequires:** If Puppet is managing the user or group that owns a
file, the file resource will autorequire them. If Puppet is managing any
parent directories of a file, the file resource will autorequire them.


Parameters
----------
    backup, checksum, content, ctime, ensure, force, group, ignore, links,
    mode, mtime, owner, path, purge, recurse, recurselimit, replace,
    selinux_ignore_defaults, selrange, selrole, seltype, seluser, show_diff,
    source, source_permissions, sourceselect, target, type, validate_cmd,
    validate_replacement

Meta Parameters
---------------
    alias, audit, before, loglevel, noop, notify, require, schedule, stage,
    subscribe, tag

Providers
---------
    posix, windows
[root@cloud ~]# 
  • 相關屬性含義
#ensure:目標狀態,值有absent,present,file,directory和link
		file:類型爲普通文件,其內容由content屬性生成或複製由source屬性指向的文件路徑來創建;
		link:類型爲符號鏈接文件,必須由target屬性指明其鏈接的目標文件;
		directory:類型爲目錄,可通過source指向的路徑複製生成,recurse屬性指明是否遞歸複製;
#path:文件路徑;
#source:源文件;
#content:文件內容;
#target:符號鏈接的目標文件; 
#owner:定義文件的屬主;
#group:定義文件的屬組;
#mode:定義文件的權限;
#atime/ctime/mtime:時間戳;
  • 簡單舉例如下所示:
vi file1.pp
    file{'aaa':
        path => '/data/aaa',
        source => '/etc/aaa',
        owner => 'keerr',
        mode => '611',
    }

exec:執行命令,慎用。通常用來執行外部命令

  • 查看使用幫助信息
[root@cloud ~]# puppet describe exec -s -m

exec
====
Executes external commands.
...

Parameters
----------
    command, creates, cwd, environment, group, logoutput, onlyif, path,
    refresh, refreshonly, returns, timeout, tries, try_sleep, umask, unless,
    user

Meta Parameters
---------------
    alias, audit, before, loglevel, noop, notify, require, schedule, stage,
    subscribe, tag

Providers
---------
    posix, shell, windows
[root@cloud ~]# 
  • exec的屬性詳解
command(namevar):要運行的命令;
cwd:指定運行該命令的目錄;
creates:文件路徑,僅此路徑表示的文件不存在時,command方纔執行;
user/group:運行命令的用戶身份;
path:指定命令執行的搜索路徑;
onlyif:此屬性指定一個命令,此命令正常(退出碼爲0)運行時,當前command纔會運行;
unless:此屬性指定一個命令,此命令非正常(退出碼爲非0)運行時,當前command纔會運行;
refreshonly:僅接收到訂閱的資源的通知時方纔運行;
refresh:重新執行當前command的替代命令;
  • 簡歷舉例如下:
vi exec1.pp
    exec{'cmd':
        command => 'mkdir /data/testdir',
    path => ['/bin', '/sbin','/usr/bin','/usr/sbin'],
    #path => '/bin:/sbin:/usr/bin:/usr/sbin',
}

 

cron:定義週期性任務

  • 查看使用幫助信息:
[root@cloud ~]# puppet describe cron -s -m

cron
====
...


Parameters
----------
    command, ensure, environment, hour, minute, month, monthday, name,
    special, target, user, weekday

Meta Parameters
---------------
    alias, audit, before, loglevel, noop, notify, require, schedule, stage,
    subscribe, tag

Providers
---------
    crontab
[root@cloud ~]# 

##相關屬性信息
    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',
	}

notify:調式輸出

  • 查看使用幫助信息
[root@cloud ~]# 
[root@cloud ~]# puppet describe notify -s -m

notify
======
Sends an arbitrary message to the agent run-time log.


Parameters
----------
    message, name, withpath

Meta Parameters
---------------
    alias, audit, before, loglevel, noop, notify, require, schedule, stage,
    subscribe, tag
[root@cloud ~]# 


##屬性信息
message:記錄的信息
name:信息名稱
  • 該選項一般用於master/agent模式,來記錄一些操作時間,比如重新安裝一個程序,或者重啓應用等。會直接輸出到代理機的運行日誌中。

資源的特殊屬性

  • 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標籤:puppet可以定義標籤--》tag,打了標籤之後,我們在運行資源的時候,就可以只運行某個打過標籤的部分,而非全部,這就更加方便我們操作。

  • 一個資源中,可以有多個tag也可以有多個。具體用法如下:

type{'title1':
    ...
    tag => 'TAG1',    
}

type{'title2':
    ...
       tag => ['TAG1','TAG2',...],
}


##調用時的語法爲:
puppet apply --tags TAG1,TAG2,... FILE.pp
  • 實例如下:

#首先我們去修改一下redis.pp文件,添加一個標籤進去
vi redis.pp
    package{'redis':
        ensure => installed,
    }
    file{'/etc/redis.conf':

        source => '/root/manifest/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']

puppet變量

  • puppet變量以”$“ 開頭,賦值操作符爲”=“,語法爲$variable_name=value

數據類型

  • 字符型:引號可有可無,但是單引號爲強引用,雙引號爲弱引用;支持轉義符;
  • 數值型:默認均識別字符串,僅僅在數值上下文才以數值對待;
  • 數組:[]中以逗號分隔元素列表;
  • 布爾型值:true,false;不能加引號;
  • hash:{}中以逗號分隔k/v數據列表;鍵爲字符型,值爲任意puppet支持的類型;{‘mon’ => 'Monday','true' => 'Tuesday',};
  • undef:從未被聲明的變量的值裏類型;
  • 正則表達式
(?<ENABLED OPTION>:<PATTERN>)
(?<DISABLED OPTION>:<PATTERN>)
OPTIONS:
    i:忽略字符大小寫;
    m:把.當換行符;
    x:忽略<PATTERN>中的空白字符;
(?i-mx;PATTERN)
注意:不能賦值給變量,僅能用在接受=`或者!`操作符的位置

puppet的變量

  • facts:由facter提供;top scope;
  • 內建變量
mater端變量
    $severname,$serverip,$serverversion
agent端變量
    $client,$clientversion,$environment
parser變量
    $module_name
  • 用戶自定義變量

變量的作用域:不同的變量也有其不同的作用域。我們稱之爲Scope。

作用域有三種:top scope,node scope,class scope。

其生效範圍排序爲:top scope > node scope > class scope

其優先級排序爲:top scope < node scope < class scope

puppet流程控制語句

  • puppet支持if語句,case語句和selector語句

if語句

  • if語句分爲單分支,雙分支和多分支,具體語法如下:
單分支:

if CONDITION {
    statement
    ...
}

雙分支:

if CONDITION {
    statement
    ...
}
else {
    statement
    ...
}

多分支:
if CONDITION {
    statement
    ...
}
elsif CONDITION {
    statement
    ...
}
else {
    statement
    ...
}


##CONdITION的給定方式有如下三種:
1.變量
2.比較表達式
3.有返回值的函數


vi if.pp
    if $operatingsystemmajrelease == '7' {
        $db_pkg='mariadb-server'
}else{
        $db_pkg='mysql-server'
}
package{"$db_pkg":
        ensure => installed,
}

case語句

  •  類似if語句,case語句會從多個代碼塊中選擇一個分支執行,這跟其他編程語言中的case語句功能一致。
  • case語句會接受一個控制表達式和一組case代碼塊,並且執行第一個匹配到控制表達式的塊。
  • 使用語法如下:
case CONTROL_EXPRESSION {
    case1:{...}
    case2: {...}
    ....
    default: {...}
}
  • 其中,CONTROL_EXPRESSION的給定方式有如下三種

變量

表達式

有返回值的函數

  • 各個case的給定方式有如下五種:

直接字符串

變量

有返回值的函數

正則表達式模式

default

selector語句

  • selector只能用於期望出現直接值(plain value)的地方,這包括變量賦值、資源屬性、函數參數、資源標題、其他selector。
  • selector不能用於一個已經嵌套於selector的case中,也不能用於一個已經嵌套於case的case語句中。
CONTROL_VARIABLE ? {
    case1 => value1,
    case2 => value2,
    ...
    default => valueN,
}
  • 其中,CONTROL_EXPRESSION的給定方式有如下三種:

變量

表達式

有返回值的函數

  • 各個case的給定方式有如下五種

直接子串

變量

有返回值的函數

正則表達式模式

default

五.Class類

類的定義

  • 類是puppet中命名的代碼模塊,常用於定義一組通用目標的資源,可以在puppet全局調用
  • 類可以被繼承,也可以包含子類
  • 具體定義的語法如下:
class NAME {
    ...puppet code ...
}
  • 類的名稱只能以小寫字母,可以包含小寫字母、數字和下劃線。

  • 每個類都會引入一個新的變量scope,這意味着在任何時候訪問類中的變量,都得使用其完全限定的名稱。不過,在本地scope可以重新爲top scope中變量賦予一個新值。

  • 如下是一個簡單的例子:

vi class1.pp
    class redis {    #定義一個類
        packeage {'redis':
            ensure => installed,
    }    ->
        file{'/etc/redis.conf':
            ensure => file
            source => '/root/manifests/file/redis.conf',
            owner => 'redis',
            group => 'root',
            mode => '0604',
            tag => 'redisconf'
    } ~>
        service{'redis':
            ensure => running,
            enable => true,
            hasrestart => true,
            hasstatus => true
    }
}
include redis    #調用類

#類只有被調用纔會被執行。include後可以跟多個類,直接用","隔開即可。

帶有參數的類

  • 定義的類也可以進行參數設置,可以進行參數的傳遞
  • 具體的語法如下:
class NAME(parameter1,parameter2) {   #大括號前有空格
    ...pupet code...
}
  • 具體的實例如下:

vi class2.pp
    class instpkg($pkg) {
        package {"$pkg":
            ensure => installed,
    }
}
    class {"instpkg":            #給參數傳入值
        pkg => 'memcached',    
}

#單個主機不能被直接聲明兩次
  • 如果對應的參數爲未傳值的話,執行會報錯。但是我們可以在定義形參的時候,設定一個默認值,這樣的話,我們不傳入值的話,就會自動調用默認值

vi class3.pp
    class instpkg($pkg='wget') {
        package{"$pkg":
            ensure => installed,
        }
    }
    include instpkg
#這樣的話,我們直接使用include調用即可,就不需要給參數傳入值了。
  • 由上,我們可以得知,調用類的方式有兩種:

1.include CLASS_NAME1,CLASS_NAME2,...
2.class{'CLASS_NAME':
    attribute => value,
}
  • 下面舉一個比較全面的例子:首先我們判斷系統的版本是6還是7,由此來確定,是安裝mysql還是mariadb,同時,使用調用參數的方式來實現如上需求。

vi dbserver.pp
class dbserver($dbpkg='mariadb-server',$svc='mariadb') {	#定義類並給參數賦值
		package{"$dbpkg":
			ensure  => installed,
		}

		service{"$svc":
			ensure  => running,
			enable  => true,
			hasrestart  => true,
			hasstatus   => true,
		}
	}

	if $operatingsystem == 'CentOS' {
		if $operatingsystemmajrelease == '7' {
			include dbserver		#直接調用類
		} else {
			class{"dbserver":		#調用類並對參數重新賦值
				dbpkg   => 'mysql-server',
				svc     => 'mysqld'
			}
		}
	}

類的繼承

  • 類似其他編程語言中的類的功能,pupet的class可以被繼承,也可以包含子類。
  • 其定義的語法如下:
class SUB_CLASS_NAME inherits PARENT_CLASS_NAME {
	...puppet code...
}
  • 實例如下:

vim class4.pp
	class redis {		#定義class類
		package{'redis':
			ensure  => installed,
		}

		service{'redis':
			ensure  => running,
			enable  => true,
		}
	}

	class redis::master inherits redis {		#調用父類
		file {'/etc/redis.conf':
			ensure  => file,
			source  => '/root/manifests/file/redis-master.conf',
			owner   => 'redis',
			group   => 'root',
		} 

		Service['redis'] {						#定義依賴關係
			subscribe   => File['/etc/redis.conf']
		}
	}

	class redis::slave inherits redis {			#調用父類
		file {'/etc/redis.conf':
			ensure  => file,
			source  => '/root/manifests/file/redis-slave.conf',
			owner   => 'redis',
			group   => 'root',
		} 

		Service['redis'] {						#定義依賴關係
			subscribe   => File['/etc/redis.conf']
		}
	}

我們在類的調用的時候,可以實現修改原有值和額外新增屬性的功能。

1.新增屬性:繼承父類的時候,可以定義一些父類原本沒有的屬性;

2.新增原有值:繼承的類中,我們可以在屬性的原有值的基礎上,使用+>進行新增修改;

3.在繼承的類中,我們可以直接把原有的值進行覆蓋修改,使用=>進行覆蓋即可;

4.整體調用父類,並且重寫部分值:在繼承的類中,我們可以在整體調用的基礎上,根據不同的需求,把父類中的部分值進行修改;

六.模板與模塊

模板

#首先,我們先來定義一個file.pp文件,在該文件中調用我們的模板
vim file.pp
	file{'/tmp/redis.conf':		#僅用於測試模板是否生效,所以放在tmp目錄下
		ensure  => file,
		content => template('/root/manifests/file/redis.conf.erb'),		#調用模板文件
		owner   => 'redis',
		group   => 'root',
		mode    => '0640',
	}

#接着,修改配置文件的源,也就是我們的模板文件
vim file/redis.conf.erb
	bind 127.0.0.1 <%= @ipaddress_eth0 %>	#修改監聽端口

#修改完成以後,我們就可以執行查看結果
puppet apply -v file.pp

模塊

  • 實踐中,一般需要把manifest 文件分解成易於理解的結構,例如將類文件、配置文件甚至包括後面將提到的模塊文件等分類存放,並且通過某種機制在必要時將它們整合起來。
  • 這種機制即模塊,它有助於以結構化、層次化的方式使用puppet,而puppet 則基於“模塊自動裝載器”。
  • 從另一個角度來說,模塊實際上就是一個按約定的、預定義的結構存放了多個文件或子目錄的目錄,目錄裏的這些文件或子目錄必須遵循其命名規範

模塊的命名規範

  模塊的目錄格式如下:

目錄格式

  • 目錄格式

其中,每個文件夾中存放的內容及其要求如下:

MODULE NAME:模塊名稱,模塊名只能以小寫字母開頭,可以包含小寫字母、數字和下劃線;但不能使用"main"和"settings";

manifests/:必須要有

  • init.pp:必須一個類定義,類名稱必須與模塊名稱相同;

files/:靜態文件;

  • 其中,每個文件的訪問路徑遵循:puppet:///modules/MODULE_NAME/FILE_NAME

templates/

  • 其中,每個文件的訪問路徑遵循:tempate('MOD_NAME/TEMPLATE_FILE_NAME')

lib/:插件目錄,常用於存儲自定義的facts以及自定義類型;

spec/:類似於tests目錄,存儲lib/目錄下插件的使用幫助和範例;

tests/:當前模塊的使用幫助或使用範例文件;

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章