puppet是一種開源的、新一代的集中化的配置管理工具。可管理的平臺有windows,Linux,Unix等。有本身的配置語言(資源申報語言),可管理文件、軟件包、系統服務、用戶等。這些統稱爲puppet的資源。puppet是採用ruby語言研發的。php
以下圖:html
單機模型:實現定義多個manifests --> complier --> catalog --> applynode
master/agent模型:集中式管理mysql
架構:linux
工做原理:nginx
資源:是puppet的核心,經過資源申報,定義在資源清單中。web
類:一組資源清單。正則表達式
模塊:包含多個類。sql
站點清單:以主機爲核心,應用哪些模塊。shell
puppet的安裝可使用源碼安裝,也可使用rpm(官方提供)、epel源、官方提供的yum倉庫來安裝(經過下載官方提供的rpm包能夠指定官方的yum倉庫)。
這裏使用的是2.7系列的,使用epel倉庫
yum install puppet -y
puppet從如下三個維度來都資源完成抽象:
一、類似的資源被抽象成同一種資源「類型,」如程序包資源、用戶資源及服務資源等 二、將資源屬性或狀態的描述與其實現方式剝離開來,如僅說明安裝一個程序包而不用關係其具體 是yum、pkgadd、prots或其餘方式實現 三、僅描述資源的目標狀態,也即指望其實現的結果,而不是其具體過程,如「肯定nginx運行起來」 而不是具體描述爲「運行nginx命令將啓動起來」
這三個也被稱爲puppet的資源抽象層(RAL)。RAL由type(類型)和provide(提供者,即不一樣的OS上的特定實現)組成。
資源是puppet用於模型化系統配置的基礎單元,每一個資源都從某個角度描述了系統屬性,如某程序包必須安裝或某用戶必須移除等,在puppet,用於完成此類功能的代碼也即「資源申報」
type { ‘title’: atttibue => value, }
資源的文件統一以.pp結尾。在定義時,資源類型必須使用小寫字母,而資源名稱僅是一個字符串,但要求在同一類型中期必須惟一。
## 幫助查看: puppet describe [-s] package puppet支持使用的軟件包管理器:yum,rpm,apt,prots,gem,msi,dpkg,pkg 經常使用的參數: ensure:程序包的目標狀態,值有present(installed)、absent(不存在)、purged、held、 latest name:資源的名稱,即軟件包的名字,能夠省略,若是省略,將繼承title的值 provide:軟件包管理器,會自動識別 source:指定程序包文件路徑 install_options:安裝選項,最經常使用的是經過INATALLDIR來制定安裝目錄
## 幫助查看: puppet describe [-s] service 經常使用的參數: ensure:服務的額目標狀態,值有true(running)和false(stopped) enable:是否開機自動啓動,值有true和false name:服務名稱,能夠省略,若是省略,將繼承title的值 path:服務腳本路徑,默認爲/etc/init.d/下 start:定製啓動命令 stop:定製關閉命令 restart:定製重啓命令 status:定製狀態
## 幫助查看: puppet describe [-s] file ensuce:目標狀態,值有*absent*, *present*, *file*, 和*directory*. backup:經過filebacket資源來備份文件,值一般爲filebucket資源的名稱 content:文件內容,生成方式有三種(content,source,target),三者彼此互斥 source:經過制定的url下載文件至本地,獲取文件格式爲: puppet:///modules/MODULE_NAME/file_names,使用模塊時會用到 target:爲符號連接指定目標 links:文件爲符號鏈接,值爲「follow」,「manage」 path:文件路徑,必須使用雙引號 mode:定義權限,一般爲8進制數字 owner: 定義文件的屬主 group:定義文件的屬組 force:強制執行刪除文件、連接或目錄、僅用於ensure爲absent時 purge:清除指定目錄中存在的,但未在資源中定義的文件 resurce:目錄遞歸,值爲true,false,inf,remote replace:替換,本地存在的文件與資源中指定的文件內容不一樣時是否執行替換,默認爲否
package { ["httpd",'mysql-server','php']: ensure => present } service { ["httpd",'mysqld']: ensure => true, enable => false } file{'my.cnf': ensure => file, source => '/root/my.cnf', path => '/etc/my.cnf', }
## 幫助查看: puppet describe [-s] exec 經常使用的參數: command:要執行的命令,經過爲命令文件的完整路徑 path:命令搜索路徑 group:執行命令的組 user:執行命令的用戶 onlyif:0,表示僅在命令的狀態返回值爲0時才執行此命令 refresh:定義接受的其餘資源的通知時,則要從新執行此命令 refreshonly:僅被當被依賴的資源發生改變時才被觸發 tries:嘗試次數,默認爲1 try_sleep:屢次嘗試之間的時間間隔
## 幫助查看: puppet describe [-s] group 經常使用參數: ensure:目標狀態,present,absent name:組名 gid:GID system:系統組
## 幫助查看: puppet describe [-s] user 經常使用參數: ensure:目標狀態,present,absent name:用戶名 uid:用戶uid system:系統用戶 home:用戶家目錄 shell:用戶默認shell gid:用戶的gid password:密碼,使用加密後密碼 managehome: 是否建立家目錄,默認爲false
常見屬性 ensure:目標狀態,present,absent command:命令或腳本 environment:運行時的環境變量 hour:小時 mouth:月 monthday:日 weekday:周 minute:分 name:名稱 user: 默認爲root
經常使用參數: message:信息 name:信息名稱
常見的資源就是這些。更詳細的可使用puppet describe命令查看。
使用Type['title'],首字母必須大寫
puppet提供了before、require、notify、subscribe四個元參數來定義資源之間的相關性。
require:表示須要依賴於某個資源 before:表示應該先執行本資源,在執行別的資源 notify: 表示將當前資源的變更信息通知給別的資源,爲通知的發出者 subscribe:表示定義某資源的變更信息,爲通知的接收者
依賴關係還可使用->和~>來表示
-> 表示後資源須要依賴前資源 ~> 表示前資源變更通知後資源調用
例如:
package{'nginx': ensure => installed, } file{'nginx.conf': ensure => file, source => '/root/nginx.conf', require => Package['nginx'], path => '/etc/nginx/nginx.conf', } service{'nginx': ensure => true, enable => true, require => Package['nginx'], subscribe => File['nginx.conf'], }
六、puppet變量
puppet的變量名稱以「$」開頭,賦值操做符爲「=」
puppet的變量類型: 布爾型:true和false,不能加引號,if語句的測試條件和比較表達式都會返回布爾型值, 另外,其餘數據類型也能夠自動轉換爲布爾型,如空字符串爲false等 undef:從未聲明的變量的值類型即爲undef,也能夠手動爲某變量賦予undef值, 即直接使用不加引號的undef字符串 字符型:非結構化的文本字符串,可使用引號,也能夠不用。單引號中的變量不會替換, 而雙引號中的可以進行變量替換;字符型也支持使用轉移符 數值型:可爲整數或浮點數,不過,puppe只有在數值上下文才把數值當數值對待, 其餘清理下一概以字符型處理 數組:數組值爲中括號「[]」中的以逗號分隔的項目列表,最後一個項目後面能夠有逗號; 數組中的袁術能夠爲任何可用數據類型,包括hash或其餘數組,屬組索引爲從0開始的整數, 也可使用負數索引 hash:即爲外鍵值數據類型,鍵和值之間使用「=>」分隔,鍵值對定義在「{ }」中, 彼此間以逗號分隔;其鍵位字符型數據,而值能夠爲puppet支持的任意數據類型, 訪hash類型的數據元素要使用「鍵」看成索引進行。實際上和關聯數組應屬於同一數據類型 正則表達式:屬於puppet的非標準數據類型,不能賦值給變量,僅能用於有限的幾個接收正則 表達式的地方,即接受使用「=~」及「!~」匹配操做符的位置,一般包括case語句中的 selector,已經節點名稱匹配的位置,他們不能傳遞給函數或用於資源屬性的定義 facter變量:能夠經過facter查看 內置變量: 例如:agent端:$environment,$clientcert,$clentbversion server端:$servername,$serverip,$serverversion
puppet中的正則表達式支持使用(?<ENABLED OPTION>:<SUNPATTERN>)和(?-<DISABLED OPTION>:<SUNPATTERN>)兩個特殊的符號,以下面的示例,表示作正則表達式匹配時啓用選項「i(忽略字符大小寫)」,但不支持使用「m(把.看成換行符)」和啓用「x(忽略模式中的空白字符和註釋)」
$packages = $operatingsystem ? { /(?i-mx:ubuntu|debian)/ => 'apache2', /(?i-mx:centos|fedora|redhat)/ => 'httpd', }
puppet的判斷語句主要有三種分別爲if,case,selector puppet的操做符有:比較操做符,布爾操做符,算術操做符 if語句分爲單分支,雙分支和多分支 單分支: if CONDITION { statement ... } 雙分支: if CONDITION { statement ... } else { statement ... } 多分支: if CONDITION { statement ... } elsif CONDITION { statement ... } else { statement ... } case語句的語法 case CONTROL_EXPRESS { case1,...: { statement... } case2,...:{ statement... } ... ... default:{ statement... } } selector語句的用法 CONTROL_VARIABLE ? { case1 => value1 case2 => value2 ... default => valueN }
例如:判斷一個系統的OS的類型,並輸出「welcome to OS」的信息
if $operatingsystem == /^(?i-mx:centos|fedora|redhat)/ { notice "welcome to redhat OS Family" }elsif $operatingsystem == ubuntu { notice "welcome to ubuntu server" }else { notice "unkown server" } ################################################################# case $operatingsystem { 'Solaris': { notice("Welcome to Solaris") } 'RedHat', 'CentOS': { notice("Welcome to RedHat OSFamily") } /^(Debian|Ubuntu)$/:{ notice("Welcome to $1 linux") } default: { notice("Welcome, alien *_*") } } ################################################################# $welcome =$operatingsystem ? { /^(?i-mx:centos|fedora|redhat)/ => 'redhat OS Family', /^(?i-mx:ubuntu)/ => 'ubuntu', /^(?i-mx:debian)/ => 'debebian', } notify { "$welcome": message => "welcome to $welcome", }
class my_class { ...puppet code ... }
class nginx { package { 'nginx': ensure => installed, name => nginx, } service { 'nginx': ensure => true, enable => true, subscribe => Package['nginx'], } }
以上是類的定義,相似於函數。須要使用的話,要調用。調用時,使用關鍵在include便可。
類能夠基於父類調用,在調用時,應該指定經過inherits關鍵字調用父類。例如:
class nginx { package { 'nginx': ensure => installed, name => nginx, } } class nignx::web inherits nginx { service { 'nginx': ensure => true, enable => true, } } include nignx::web
也支持類的覆蓋和重寫:
=>:在子類中覆蓋父類中的資源 +>:在子類中爲父類中的資源新增額外的屬性
puppet模塊:爲了實現某種完備功能而組織成的一個獨立的、自我包含的目錄結構
模塊名:目錄名
目錄結構: Module_name: manifests init.pp: 必須聲明一個類,類名與模塊名相同; *.pp: MODULE_NAME::[SUBDIR_NAME]::MANIFESTS_FILE_NAME files:靜態文件 puppet url:puppet:///modules/MODULE_NAME/[SUBDIR_NAME]/FILE_NAME file{'nginx.conf': source => puppet:///modules/nginx/nginx.conf } templates: 模板文件:*.erb template('MODULE_NAME/TEMPLATE_FILE_NAME'); file{'nginx.conf': content => template('模板文件'), } lib: 插件 tests: 模塊使用說明文檔 spec: lib目錄下的插件使用說明文檔
3、使用maste/agent模式,部署LAMP平臺
Master/Agent模型之間通訊是靠主機名通訊的,大體步驟是:
一、master啓動時會爲本身的key,自籤 二、agent啓動前要生成本身的key,生成簽署請求 三、master收到請求書,驗證合法性,簽署證書
實驗環境:
Master端:172.16.10.9 server.magedu.com Agent端:172.16.10.77 basic.example.com 172.16.10.122 node2.example.com
### 安裝軟件 在172.16.10.9: yum install puppet puppet-server -y 在172.16.10.77,172.16.10.122: yum install puppet -y ### 提供主機名解析名文件 # 172.16.10.9 172.16.10.77 172.16.10.122 # /etc/hosts 127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4 ::1 localhost localhost.localdomain localhost6 localhost6.localdomain6 172.16.10.77 basic.example.com 172.16.10.9 server.magedu.com 172.16.10.122 node2.example.com ### 配置3臺機器時間同步
## Master端 目錄文件,以下: [root@server modules]# pwd /etc/puppet/modules [root@server modules]# tree . ├── mysql │ ├── file │ │ └── my.cnf │ └── manifests │ └── init.pp └── nginx ├── files │ └── nginx.conf └── manifests └── init.pp 6 directories, 4 files [root@server modules]# cat mysql/manifests/init.pp class mysql { package{'mysql-server': ensure => installed, } file{'my.cnf': ensure => file, source => 'puppet:///modules/mysql/my.cnf', path => '/etc/my.cnf', require => Package['mysql-server'], } service{'mysqld': ensure => true, enable => true, require => Package['mysql-server'], subscribe => File['my.cnf'], } } [root@server modules]# cat nginx/manifests/init.pp class nginx { package{'nginx': ensure => installed, } file{'nginx.conf': ensure => file, source => 'puppet:///modules/nginx/nginx.conf', require => Package['nginx'], path => '/etc/nginx/nginx.conf', } service{'nginx': ensure => true, enable => true, require => Package['nginx'], subscribe => File['nginx.conf'], } } ## 說明:my.cnf nginx.cnf是配置文件 [root@server manifests]# pwd /etc/puppet/manifests [root@server manifests]# tree . ├── server │ ├── basic.pp │ └── node2.pp └── site.pp 1 directory, 3 files [root@server manifests]# cat server/node2.pp node 'node2.example.com' { include nginx,mysql } [root@server manifests]# cat server/basic.pp node 'basic.example.com' { include nginx, } [root@server manifests]# cat site.pp import "server/*.pp"
建立好目錄清單後,此時須要啓動服務。第一次啓動時,可手動啓動。
Master端啓動:
[root@server ~]# puppet master -v -d --no-daemonize debug: Failed to load library 'rubygems' for feature 'rubygems' debug: Puppet::Type::User::ProviderUser_role_add: file roleadd does not exist debug: Puppet::Type::User::ProviderPw: file pw does not exist debug: Puppet::Type::User::ProviderDirectoryservice: file /usr/bin/dscl does not exist debug: Puppet::Type::User::ProviderLdap: true value when expecting false debug: /File[/var/lib/puppet/yaml]: Autorequiring File[/var/lib/puppet] debug: /File[/var/lib/puppet/ssl/private]: Autorequiring File[/var/lib/puppet/ssl] debug: /File[/etc/puppet/auth.conf]: Autorequiring File[/etc/puppet] debug: /File[/var/lib/puppet/lib]: Autorequiring File[/var/lib/puppet] debug: /File[/var/lib/puppet/facts]: Autorequiring File[/var/lib/puppet] debug: /File[/var/lib/puppet/ssl/certificate_requests]: Autorequiring File[/var/lib/puppet/ssl] debug: /File[/etc/puppet/manifests/site.pp]: Autorequiring File[/etc/puppet/manifests] debug: /File[/var/lib/puppet/rrd]: Autorequiring File[/var/lib/puppet] debug: /File[/var/log/puppet/masterhttp.log]: Autorequiring File[/var/log/puppet] debug: /File[/var/lib/puppet/ssl/private_keys]: Autorequiring File[/var/lib/puppet/ssl] debug: /File[/var/lib/puppet/reports]: Autorequiring File[/var/lib/puppet] debug: /File[/etc/puppet/puppet.conf]: Autorequiring File[/etc/puppet] debug: /File[/var/lib/puppet/state]: Autorequiring File[/var/lib/puppet] debug: /File[/etc/puppet/fileserver.conf]: Autorequiring File[/etc/puppet] debug: /File[/var/lib/puppet/server_data]: Autorequiring File[/var/lib/puppet] debug: /File[/etc/puppet/manifests]: Autorequiring File[/etc/puppet] debug: /File[/var/lib/puppet/bucket]: Autorequiring File[/var/lib/puppet] debug: /File[/var/lib/puppet/ssl/public_keys]: Autorequiring File[/var/lib/puppet/ssl] debug: /File[/var/lib/puppet/ssl]: Autorequiring File[/var/lib/puppet] debug: /File[/var/lib/puppet/ssl/certs]: Autorequiring File[/var/lib/puppet/ssl] debug: /File[/var/lib/puppet/yaml]/ensure: created debug: /File[/var/lib/puppet/rrd]/ensure: created debug: /File[/var/lib/puppet/reports]/ensure: created debug: /File[/var/lib/puppet/facts]/ensure: created debug: /File[/var/lib/puppet/ssl]/ensure: created debug: /File[/var/lib/puppet/ssl/private_keys]/ensure: created debug: /File[/var/lib/puppet/ssl/public_keys]/ensure: created debug: /File[/var/lib/puppet/ssl/certs]/ensure: created debug: /File[/var/lib/puppet/state]/ensure: created debug: /File[/var/lib/puppet/ssl/private]/ensure: created debug: /File[/var/lib/puppet/lib]/ensure: created debug: /File[/var/lib/puppet/bucket]/ensure: created debug: /File[/var/lib/puppet/ssl/certificate_requests]/ensure: created debug: /File[/var/lib/puppet/server_data]/ensure: created debug: Finishing transaction 70003525843560 debug: /File[/var/lib/puppet/ssl/ca/signed]: Autorequiring File[/var/lib/puppet/ssl/ca] debug: /File[/var/lib/puppet/ssl/ca/requests]: Autorequiring File[/var/lib/puppet/ssl/ca] debug: /File[/var/lib/puppet/ssl/ca/private]: Autorequiring File[/var/lib/puppet/ssl/ca] debug: /File[/var/lib/puppet/ssl/ca]/ensure: created debug: /File[/var/lib/puppet/ssl/ca/signed]/ensure: created debug: /File[/var/lib/puppet/ssl/ca/private]/ensure: created debug: /File[/var/lib/puppet/ssl/ca/requests]/ensure: created debug: Finishing transaction 70003525749380 info: Creating a new SSL key for ca info: Creating a new SSL certificate request for ca info: Certificate Request fingerprint (md5): E4:F9:A5:7C:CD:DC:D5:F4:30:C5:97:D4:4B:75:E2:1A notice: Signed certificate request for ca notice: Rebuilding inventory file debug: Using cached certificate for ca info: Creating a new certificate revocation list info: Creating a new SSL key for server.magedu.com debug: Using cached certificate for ca info: Creating a new SSL certificate request for server.magedu.com info: Certificate Request fingerprint (md5): EC:52:9E:3B:8A:92:A3:E2:82:FB:D6:EF:7B:36:50:1F notice: server.magedu.com has a waiting certificate request debug: Using cached certificate for ca debug: Using cached certificate_request for server.magedu.com notice: Signed certificate request for server.magedu.com notice: Removing file Puppet::SSL::CertificateRequest server.magedu.com at '/var/lib/puppet/ssl/ca/requests/server.magedu.com.pem' notice: Removing file Puppet::SSL::CertificateRequest server.magedu.com at '/var/lib/puppet/ssl/certificate_requests/server.magedu.com.pem' notice: Starting Puppet master version 2.7.25 debug: Finishing transaction 70003524197780 debug: No modules mount given; autocreating with default permissions debug: No plugins mount given; autocreating with default permissions
出現以上信息時,證實測試沒有問題,此時可使用:
service puppetmaster start
以172.16.10.122爲例:
[root@node2 ~]# puppet agent --server=server.magedu.com --no-daemonize -d ### 會出現如下信息: info: Creating a new SSL key for node2.example.com info: Caching certificate for ca info: Creating a new SSL certificate request for node2.example.com info: Certificate Request fingerprint (md5): 1B:D4:E5:D9:15:A8:87:5B:67:C0:4B:C2:72:\ 15:45:BA ############################################################### 此時在Master端: [root@server ~]# puppet cert --list "node2.example.com" (1B:D4:E5:D9:15:A8:87:5B:67:C0:4B:C2:72:15:45:BA) 簽名: [root@server ~]# puppet cert --sign node2.example.com notice: Signed certificate request for node2.example.com notice: Removing file Puppet::SSL::CertificateRequest node2.example.com at \ '/var/lib/puppet/ssl/ca/requests/node2.example.com.pem' ##################################################################### 此時Agent端出現: debug: Using cached certificate for node2.example.com notice: Starting Puppet client version 2.7.25 代表簽署成功。 #################################################################### 確保上述agent相關操做不存在問題後,即可以將--server選項指定的信息存儲與agent的配置文件中 ,並以服務的方式啓動puppet agent了。 其配置文件爲/etc/puppet/puppet.conf echo "server=server.magedu.com" >> /etc/puppet/puppet.conf #################################################################### service puppet start
172.16.10.77一樣的配置。
puppet客戶端默認每30分鐘很服務器通信一次,可是有時,咱們但願服務器可以給客戶端緊急推送一些任務,因而就有了puppet kick(puppet 2.6之前叫puppetrun)。
1)編輯客戶端配置文件/etc/puppet/puppet.conf在[agent]端中添加以下 listen=true 2)在客戶端編輯或建立新文件/etc/puppet/namespaceauth.conf,包含下面內容 [puppetrunner] allow *.magedu.com 3)在客戶端編輯文件auth.conf,添加以下內容 path /run method save auth any allow server.magedu.com## 注意,這一項放到 path /前面 4)推送方法,在服務器端運行命令 [root@server puppet]# puppet kick -p 1 --host node2.example.com Triggering node2.example.com Getting status status is success node2.example.com finished with exit code 0 Finished
配置基本完成。