Puppet
基于puppet 可實作自動化重複任務, 快速部署關鍵性應用以及在本地或雲端完成主動管理變更和快速擴充架構規模.
基于master/agent 模型. 基于RPC 的通信, 基于xml 進行資料交換
define : 使用puppet 語言來定義資源的狀态
模拟 : 根據資源關系圖, puppet 可以模拟部署無損運作測試代碼
強制 : 對比用戶端主機狀态和定義的資源狀态是否一緻, 自動強制執行
report : 通過puppt API 可以将日志發送到第三方監控工具
puppet 工作模型 :
- 單機模型 : 手動應用清單
- master / agent : 基于RPC 的通信, 基于xml 進行資料交換
puppet 常用資源類型
資源抽象的次元, RAL 如何抽象資源的
三個層次 : 資源抽象層, 事物層, 配置語言層
類型 : 具有類似屬性的元件, 例如 package, service, file
将資源的屬性或狀态與其實作方式分離
僅描述資源的目标狀态, 也即實作的結果狀态, 而不是具體過程
RAL 由 “類型” 和”提供者” (“provider”) 共同實作
puppet 子指令 :
help :
顯示幫助
1 | puppet help <command> |
1 | puppet help <command> <action> |
apply :
手動控制如何應用清單
`puppet apply [-d | —debug] [-v | —verbose] [-e | —execute] [ —noop ]
describe :
顯示資源類型的幫助資訊
1 2 3 4 | -l : 列出所有的資源類型 -s : 顯示指定類型的簡要幫助資訊 puppet describe -s Command -m : 顯示指定類型的元參數, 一般與-s 一同使用 |
資源定義 : 向資源類型的屬性指派來實作, 可稱為資源類型的執行個體化
資源定義所在的檔案即為資源清單 manifest
定義資源的文法 :
type {"title": attribute => value1, attribute2 => value2, |
注意 ; type 必須使用小寫字母, title 是一個字元串, 在同一類型中必須唯一
status :
顯示server 的狀态
agent :
運作用戶端程式
master :
作為伺服器主機, 用于控制其他的用戶端和本機
module :
官方支援的子產品
資源類型
-
group :
建立和管理組
name : 組名
gid : 組ID
ensure : 狀态[present | absent]
system : 是否為使用者組 [true | false]
members : 成員使用者
-
user :
管理使用者
name : 使用者名
uid : UID
gid : 基于組ID
groups : 附加組
comment : 注釋
expiry : 過期時間
home : 家目錄
shell : 預設shell 類型
system : 是否為系統使用者
ensure : present | absent
password : 加密後的密碼串
-
package :
管理軟體包
name : 軟體包名
ensure : [ installed | present | absent]
source : 程式包來源 [rpm | yum]
-
service
服務管理
ensure : [ installed | present | latest | ]
path : 啟動服務的腳本
name : 服務名稱
enable : 是否開機啟動
restart : 通常用于重定義為 reload
hasrestart : 有重新開機指令 [true | false]
hasstatus : 有狀态查詢指令
-
file :
管理檔案
ensure : 檔案類型的确認 [file | directory | link | present | absent ]
path : 檔案路徑
source : 源檔案
content : 檔案内容
target : 符号連接配接的目标檔案
owner : 屬主
group : 屬組
mode : 權限
atime/ctime/mtime : 時間戳
-
exec :
執行指令
cwd : 指令執行的目錄
command : 要運作的程式
creates : 檔案路徑不存在即建立
user/group : 運作指令的使用者身份
onlyif : 此屬性指定一個指令, 此指令正常(退出碼為0)運作時, 目前command 才會運作
unless : 此屬性指定一個指令, 此指令非正常(退出碼為0)運作時, 目前command 才會運作
refresh : 重新執行目前command 的替代指令
refreshonly : 僅接收到訂閱資源的通知時方才運作
-
cron :
設定定時任務
command:要執行的任務;
ensure:present/absent;
hour:
minute:
monthday:
month:
weekday:
user:添加在哪個使用者之上;
name:cron job的名稱;
1 2 3 4 5 6 cron{"timesync": command => "/usr/sbin/ntpdate 10.1.0.1 &> /dev/null", ensure => present, minute => "*/3", user => "root", } -
notify :
在日志中追加記錄資訊
message : 資訊内容
name : 資訊名稱
1 2 3 4 notify {"hello" message => 'hello guys' name => 'hello message' }
資源引用 :
Type[‘title’]
類型的首字母必須大寫
資源有特殊屬性 :
- 名稱變量 : (namevar) : name 可省略, 此時将由title表示
- ensure : 定義資源的目标狀态
- 元參數 : metaparameter :
- 依賴關系 : before | require
- 通知關系 : 通知相關其他資源進行重新整理操作 notify | subscribe
補充 : before 是表明必須在某個操作之前進行, require 是要求在某個操作執行完後進行
定義的時候, 隻需要在意的是目标的狀态, 不需要在乎目标的過程
變量
資料類型 :
字元型:引号可有可無;但單引号為強引用,雙引号為弱引用;
數值型:預設均識别為字元串,僅在數值上下文才以數值對待;
數組:[]中以逗号分隔元素清單;
布爾型值:true, false;
hash:{}中以逗号分隔k/v資料清單; 鍵為字元型,值為任意puppet支援的類型;{ ‘mon’ => ‘Monday’, ‘tue’ => ‘Tuesday’, };
undef:未指派型 ;
正規表達式:
(?[ENABLED OPTION]:[PATTERN])
(?-[DISABLED OPTION]:[PATTERN])
OPTIONS:
i:忽略字元大小寫;
m:把 ‘.’ 當換行符;
x:忽略[PATTERN]中的空白字元
變量類型:
-
facts:agent向master 傳遞資訊之前收集的資訊
由facter提供;top scope;将主機資訊收集并規範化
-
内建變量:
master端變量 $servername, $serverip, $serverversion
agent端變量 $environment, $clientcert(用戶端證書), $clientversion
parser變量 $module_name(目前應用的子產品名稱)
-
使用者自定義變量:
$parameter_value
變量的作用範圍
作用域 : top scope | node scope | class scope
任何給定的scope 都可以通路它自己的内容, 以及接收來自于其父scope, 節點scope 以及top scope 的内容
如果要通路非目前scope中的變量, 則需要通過完全限制名稱進行, 如 $vhostdir = $apache::params::vhostdir
需要注意的是, top scope 的名稱為空, 是以, 如若引用其變量, 則需要使用類似$::osfamily 進行
自己作用域的變量是不需要使用完全限制名稱解析進行通路
操作符
=~ : 左側的字元串能夠被右側的字元所比對
!~ : 左側的字元串不能被右側的字元所比對
in : 左側的字元串在右側的清單中能被比對到
Puppet 中的if 語句
條件判斷, 其中CONDITION 可以有各宗
1 2 3 4 5 6 7 8 9 | if CONDITIONS { ... } elsif CONDITIONS{ ... } else { ... } |
示例 :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | if $osfamily =~ /(?i-mx:debian)/ { $webserver = "apache2" } else { $webserver = "httpd" } package{'$webserver': ensure => installed, before => [ File["httpd.conf"], Service["httpd"] ], } file{"httpd.conf": path => "/etc/httpd/conf/httpd.conf", source => "/root/manifests/httpd.conf", ensure => file, } |
Puppet 中的case 語句
使用方法:
1 2 3 4 5 6 7 | case CONTROL_EXPRESSION { case1: { ... } case2: { ... } case3: { ... } ... default: { ... } } |
CONTROL_EXPRESSION:
- 變量
- 表達式
- 有傳回值的函數
各case的給定方式:
- 直接字串;
- 變量
- 有傳回值的函數
- 正規表達式模式;
- default
注意:不能使用清單格式;但可以是其它的selecor;
示例 :
1 2 3 4 5 | $webserver = $osfamily ? { 'Redhat' => "httpd", /(?i-mx:debian)/ => "apache2", default => "httpd", } |
Puppet 的類
類 : puppet 中命名的代碼子產品, 常用于定義一組通用目标的資源, 可在puppet 全局調用, 類可以被繼承, 也可以包含子類
1 2 3 4 5 6 | class NAME { ...puppet code... } class NAME(parameter1, parameter2) { ...puppet code... } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | class nginx { package{"nginx": ensure => installed, } service{"nginx": ensure => running, enable => true, require => Package["nginx"], } } class nginx::web inherits nginx { file{"ngx-web.conf": path => "/etc/nginx/conf.d/ngx-web.conf", ensure => file, require => Package["nginx"], source => "/root/manifests/nginx/ngx-web.conf", } file{"nginx.conf": path => "/etc/nginx/nginx.conf", ensure => file, content => template("/root/manifests/nginx.conf.erb"), require => Package["nginx"], } Service["nginx"] { subscribe => [ File["ngx-web.conf"], File["nginx.conf"] ], } } include nginx::web |
Puppet 的子產品
子產品就是一個按約定的, 預定義的結構存放了多個檔案或子目錄的目錄, 目錄裡的這些檔案遵循一定格式的命名規範
puppet 會在配置的路徑下查找所需要的子產品
1 2 3 4 5 6 7 8 | MODULES_NAME: |-manifests/ | |_init.pp |-files/ |-lib/ |-templates/ |-spec/ |_tests/ |
子產品名隻能以小寫字母開頭,可以包含小寫字母、數字和下劃線;但不能使用”main”和”settings“;
manifests/ init.pp:必須一個類定義,類名稱必須與子產品名稱相同; files/:靜态檔案; puppet URL: puppet:///modules/MODULE_NAME/FILE_NAME templates/: tempate("MOD_NAME/TEMPLATE_FILE_NAME") lib/:插件目錄,常用于存儲自定義的facts以及自定義類型; spec/:類似于tests目錄,存儲lib/目錄下插件的使用幫助和範例; tests/:目前子產品的使用幫助或使用範例檔案; |
mariadb子產品中的清單檔案示例:
class mariadb($datadir="/var/lib/mysql") { package{"mariadb-server": ensure => installed, } file{'$datadir': ensure => directory, owner => mysql, group => mysql, require => [ Package["mariadb-server"], Exec["createdir"], ], } exec{"createdir": command => 'mkdir -pv $datadir', require => Package["mariadb-server"], path => "/bin:/sbin:/usr/bin:/usr/sbin", } file{"my.cnf": path => "/etc/my.cnf", content => template("mariadb/my.cnf.erb"), require => Package["mariadb-server"], notify => Service["mariadb"], } service{"mariadb": ensure => running, enable => true, require => [ Exec["createdir"], File['$datadir'], ], } } |