自動化運維工具——puppet詳解(一)

1、puppet 介紹

一、puppet是什麼

  puppet是一個IT基礎設施自動化管理工具,它可以幫助系統管理員管理基礎設施的整個生命週期: 供應(provisioning)、配置(configuration)、聯動(orchestration)及報告(reporting)。
  基於puppet ,可實現自動化重複任務、快速部署關鍵性應用以及在本地或雲端完成主動管理變動和快速擴展架構規模等。
  遵循GPL 協議(2.7.0-), 基於ruby語言開發。
  2.7.0 之後使用(Apache 2.0 license)
  對於系統管理員是抽象的,只依賴於rubyfacter
  能管理多達40 多種資源,例如:fileusergrouphostpackageservicecronexecyum repo等。html

二、puppet的工做機制

1)工做模型

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

puppet三層模型

puppet三層模型

2)工做流程

工做流程

工做流程

3)使用模型

  puppet的使用模型分爲單機使用模型master/agent模型,下面咱們來看看這兩個模型的原理圖。
單機使用模型
  實現定義多個manifests --> complier --> catalog --> applymysql

單機使用模型工做原理

單機使用模型工做原理

master/agent模型
  master/agent模型實現的是集中式管理,即 agent 端週期性向 master 端發起請求,請求本身須要的數據。而後在本身的機器上運行,並將結果返回給 master 端。
  架構和工做原理以下:
架構nginx

master/agent模式架構

master/agent模式架構

工做原理web

master/agent模式工做原理

master/agent模式工做原理

三、puppet 名詞解釋

  • 資源:是puppet的核心,經過資源申報,定義在資源清單中。至關於ansible中的模塊,只是抽象的更加完全。
  • :一組資源清單。
  • 模塊:包含多個類。至關於ansible中的角色
  • 站點清單:以主機爲核心,應用哪些模塊。

2、puppet 資源詳解

  接下來,咱們就以單機模式來具體介紹一下puppet的各個部分。正則表達式

一、程序安裝及環境

  首先,咱們仍是來安裝一下puppetpuppet的安裝可使用源碼安裝,也可使用rpm(官方提供)、epel源、官方提供的yum倉庫來安裝(經過下載官方提供的rpm包能夠指定官方的yum倉庫)。
  在這裏,咱們就是用 yum 安裝的方式。redis

yum install -y puppet

  安裝完成事後,咱們能夠經過rpm -ql puppet | less來查看一下包中都有一些什麼文件。
  其中主配置文件爲/etc/puppet/puppet.conf,使用的主程序爲/usr/bin/puppetsql

二、puppet 資源簡介

1)資源抽象

   puppet 從如下三個維度來對資源完成抽象:shell

  1. 類似的資源被抽象成同一種資源**「類型」** ,如程序包資源、用戶資源及服務資源等;
  2. 將資源屬性或狀態的描述與其實現方式剝離開來,如僅說明安裝一個程序包而不用關心其具體是經過yum、pkgadd、ports或是其它方式實現;
  3. 僅描述資源的目標狀態,也即指望其實現的結果,而不是其具體過程,如「肯定nginx 運行起來」 而不是具體描述爲「運行nginx命令將其啓動起來」;

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

2)資源定義

  資源定義經過向資源類型的屬性賦值來實現,可稱爲資源類型實例化;
  定義了資源實例的文件即清單,manifest;
  定義資源的語法以下:

type {'title':
	attribute1 	=> value1,
	atrribute2	=> value2,
	……
}

  注意:type必須使用小寫字符;title是一個字符串,在同一類型中必須唯一;每個屬性之間須要用「,」隔開,最後一個「,」可省略。
  例如,能夠同時有名爲nginx 的「service」資源和「package」資源,但在「package」 類型的資源中只能有一個名爲「nginx」的資源。

3)資源屬性中的三個特殊屬性:

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

三、經常使用資源總結

1)查看資源
  咱們可使用puppet describe來打印有關Puppet資源類型,提供者和元參數的幫助。使用語法以下:

puppet describe [-h|--help] [-s|--short] [-p|--providers] [-l|--list] [-m|--meta] [type]
	-l:列出全部資源類型;
	-s:顯示指定類型的簡要幫助信息;
	-m:顯示指定類型的元參數,通常與-s一同使用;

2)group:管理系統上的用戶組。
  查看使用幫助信息:

enter description here

group使用幫助
屬性:
	name:組名,能夠省略,若是省略,將繼承title的值;
	gid:GID;
	system:是否爲系統組,true OR false;
	ensure:目標狀態,present/absent;
	members:成員用戶;

  簡單舉例以下:

vim group.pp
	group{'mygrp':
        name => 'mygrp',
        ensure => present,
        gid => 2000,
	}

  咱們能夠來運行一下:

enter description here

運行寫好的group資源

  
3)user:管理系統上的用戶。
  查看使用幫助信息:

enter description here

user使用幫助
屬性:
	name:用戶名,能夠省略,若是省略,將繼承title的值;
	uid: UID;
	gid:基本組ID;
	groups:附加組,不能包含基本組;
	comment:註釋; 
	expiry:過時時間 ;
	home:用戶的家目錄; 
	shell:默認shell類型;
	system:是否爲系統用戶 ;
	ensure:present/absent;
	password:加密後的密碼串;

  簡單舉例以下:

vim user1.pp
	user{'keerr':
        ensure => present,
        system => false,
        comment => 'Test User',
        shell => '/bin/tcsh',
        home => '/data/keerr',
        managehome => true,
        groups => 'mygrp',
        uid => 3000,
	}

4)package:puppet的管理軟件包。
  查看使用幫助信息:

enter description here

package使用幫助
屬性:
	ensure:installed, present, latest, absent, any version string (implies present)
	name:包名,能夠省略,若是省略,將繼承title的值;
	source:程序包來源,僅對不會自動下載相關程序包的provider有用,例如rpm或dpkg;
	provider:指明安裝方式;

  簡單舉例以下:

vim package1.pp
	package{'nginx':
   		ensure  => installed,
    	procider    =>  yum
	}

5)service:定義服務的狀態
  查看使用幫助信息:

puppet describe service -s -m
enter description here

service使用幫助
屬性:
	ensure:服務的目標狀態,值有true(running)和false(stopped) 
	enable:是否開機自動啓動,值有true和false
	name:服務名稱,能夠省略,若是省略,將繼承title的值
	path:服務腳本路徑,默認爲/etc/init.d/下
	start:定製啓動命令
	stop:定製關閉命令
	restart:定製重啓命令
	status:定製狀態

  簡單舉例以下:

vim service1.pp
	service{'nginx':
  	  	ensure  => true,
    	enable  => false
	}

6)file:管理文件、目錄、軟連接
  查看使用幫助信息:

enter description here

file使用幫助
屬性:
	ensure:目標狀態,值有absent,present,file,directory和link
		file:類型爲普通文件,其內容由content屬性生成或複製由source屬性指向的文件路徑來建立;
		link:類型爲符號連接文件,必須由target屬性指明其連接的目標文件;
		directory:類型爲目錄,可經過source指向的路徑複製生成,recurse屬性指明是否遞歸複製;
	path:文件路徑;
	source:源文件;
	content:文件內容;
	target:符號連接的目標文件; 
	owner:定義文件的屬主;
	group:定義文件的屬組;
	mode:定義文件的權限;
	atime/ctime/mtime:時間戳;

  簡單舉例以下:

vim file1.pp
	file{'aaa':
   	 	path    => '/data/aaa',
    	source  => '/etc/aaa',
    	owner   => 'keerr',
    	mode    => '611',
	}

7)exec:執行命令,慎用。一般用來執行外部命令
  查看使用幫助信息:

puppet describe exec -s -m
enter description here

exec使用幫助
屬性:
	command(namevar):要運行的命令;
	cwd:指定運行該命令的目錄;
	creates:文件路徑,僅此路徑表示的文件不存在時,command方纔執行;
	user/group:運行命令的用戶身份;
	path:指定命令執行的搜索路徑;
	onlyif:此屬性指定一個命令,此命令正常(退出碼爲0)運行時,當前command纔會運行;
	unless:此屬性指定一個命令,此命令非正常(退出碼爲非0)運行時,當前command纔會運行;
	refresh:從新執行當前command的替代命令;
	refreshonly:僅接收到訂閱的資源的通知時方纔運行;

  簡單舉例以下:

vim exec1.pp
	exec{'cmd':
   	 	command => 'mkdir /data/testdir',
    	path => ['/bin','/sbin','/usr/bin','/usr/sbin'],
	#   path => '/bin:/sbin:/usr/bin:/usr/sbin',
	}

8)cron:定義週期性任務
  查看使用幫助信息:

enter description here

cron使用幫助
屬性:
	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',
	}

  咱們能夠運行一下,查看咱們的crontab,來看看該任務是否已經被添加:

[root@master manifests]# puppet apply -v --noop cron1.pp 		#試運行
[root@master manifests]# puppet apply -v  cron1.pp 				#運行
[root@master manifests]# crontab -l				#查看計劃任務
# HEADER: This file was autogenerated at 2017-12-14 15:05:05 +0800 by puppet.
# HEADER: While it can still be managed manually, it is definitely not recommended.
# HEADER: Note particularly that the comments starting with 'Puppet Name' should
# HEADER: not be deleted, as doing so could cause duplicate cron jobs.
# Puppet Name: timesync
*/3 * * * * /usr/sbin/ntpdata 172.16.0.1

9)notify:調試輸出
  查看使用幫助信息:

enter description here

 

屬性:
	message:記錄的信息
	name:信息名稱

 該選項通常用於master/agent模式中,來記錄一些操做的時間,好比從新安裝了一個程序呀,或者重啓了應用等等。會直接輸出到代理機的運行日誌中。


  以上,就是咱們常見的8個資源。其他的資源咱們可使用puppet describe -l來列出,上文中也已經說過了~

四、資源的特殊屬性

  puppet中也提供了beforerequirenotifysubscribe四個參數來定義資源之間的依賴關係和通知關係。

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 標籤

  如同 anssible 同樣,puppet 也能夠定義「標籤」——tag,打了標籤之後,咱們在運行資源的時候就能夠只運行某個打過標籤的部分,而非所有。這樣就更方便於咱們的操做。
 一個資源中,能夠有一個tag也能夠有多個。具體使用語法以下:

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

  調用時的語法以下:

puppet apply --tags TAG1,TAG2,... FILE.PP

實例
  首先,咱們去修改一下redis.pp文件,添加一個標籤進去

vim redis.pp
	package{'redis':
		ensure  => installed,
	}

	file{'/etc/redis.conf':
		source  => '/root/manifets/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']

  而後,咱們手動先開啓redis服務:

systemctl start redis

  如今,咱們去修改一下file目錄下的配置文件:

vim file/redis.conf 
	requirepass keerya

  接着,咱們就去運行redis.pp,咱們的配置文件已經修改過了,如今想要實現的就是重啓該服務,實現,須要使用密碼keer登陸:

puppet apply -v --tags instconf redis.pp
enter description here

redis.pp運行結果

  如今,咱們就去登陸一下redis看看是否生效:

redis-cli -a keerya
enter description here

redis驗證

  驗證成功,實驗完成。

五、puppet 變量

  puppet 變量以「$」開頭,賦值操做符爲「=」,語法爲$variable_name=value
數據類型:

  字符型:引號無關緊要;但單引號爲強引用雙引號爲弱引用;支持轉義符;
  數值型:默認均識別爲字符串,僅在數值上下文才以數值對待;
  數組:[]中以逗號分隔元素列表;
  布爾型值:true, false;不能加引號
  hash:{}中以逗號分隔k/v數據列表; 鍵爲字符型,值爲任意puppet支持的類型;{ ‘mon’ => ‘Monday’, ‘tue’ => ‘Tuesday’, };
  undef:從未被聲明的變量的值類型;

正則表達式:

  (?<ENABLED OPTION>:<PATTERN>)
  (?-<DISABLED OPTION>:<PATTERN>)
  OPTIONS:
    i:忽略字符大小寫;
    m:把.當換行符;
    x:忽略<PATTERN>中的空白字符;
  (?i-mx:PATTERN)
注意:不能賦值給變量,僅能用在接受=~!~操做符的位置;

1)puppet的變量種類

  puppet 種類有三種,爲facts內建變量用戶自定義變量
facts:
  由facter提供;top scope;
內建變量:
  master端變量
    $servername, $serverip, $serverversion
  agent端變量
    $clientcert, $clientversion, $environment
  parser變量
    $module_name
用戶自定義變量

2)變量的做用域

  不一樣的變量也有其不一樣的做用域。咱們稱之爲Scope
  做用域有三種,top scope,node scope,class scope。
  其生效範圍排序爲:top scope > node scope > class scope

enter description here

變量生效範圍

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

六、puppet 流程控制語句

  puppet 支持if 語句case 語句selector 語句

1)if 語句

  if語句支持單分支,雙分支和多分支。具體語法以下:

單分支:
	if CONDITION {
		statement
		……
	}

雙分支:
	if CONDITION {
		statement
		……
	}
	else{
		statement
		……		
	}

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

  其中,CONDITION的給定方式有以下三種:

  • 變量
  • 比較表達式
  • 有返回值的函數

舉例

vim if.pp
	if $operatingsystemmajrelease == '7' {
		$db_pkg='mariadb-server'
	}else{
		$db_pkg='mysql-server'
	}

	package{"$db_pkg":
		ensure => installed,
	}

2)case 語句

  相似 if 語句,case 語句會從多個代碼塊中選擇一個分支執行,這跟其它編程語言中的 case 語句功能一致。
  case 語句會接受一個控制表達式和一組 case 代碼塊,並執行第一個匹配到控制表達式的塊。
  使用語法以下:

case CONTROL_EXPRESSION {
	case1: { ... }
	case2: { ... }
	case3: { ... }
	……
	default: { ... }
}

  其中,CONTROL_EXPRESSION的給定方式有以下三種:

  • 變量
  • 表達式
  • 有返回值的函數

  各case的給定方式有以下五種:

  • 直接字串;
  • 變量
  • 有返回值的函數
  • 正則表達式模式;
  • default

舉例

vim case.pp
	case $osfamily {
		"RedHat": { $webserver='httpd' }
		/(?i-mx:debian)/: { $webserver='apache2' }
		default: { $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,
	}

	service{'httpd':
		ensure  => running,
		enable  => true,    restart => 'systemctl restart httpd.service',
		subscribe => File['httpd.conf'],
	}

3)selector 語句

  Selector 只能用於指望出現直接值(plain value) 的地方,這包括變量賦值、資源屬性、函數參數、資源標題、其它 selector。
  selector 不能用於一個已經嵌套于于selector 的case 中,也不能用於一個已經嵌套於case 的case 語句中。
  具體語法以下:

CONTROL_VARIABLE ? {
	case1 => value1,
	case2 => value2,
	...
	default => valueN,
}

  其中,CONTROL_EXPRESSION的給定方式有以下三種:

  • 變量
  • 表達式
  • 有返回值的函數

  各case的給定方式有以下五種:

  • 直接子串;
  • 變量;
  • 有返回值的函數;
  • 正則表達式模式;
  • default

  selectors 使用要點:

  1. 整個selector 語句會被看成一個單獨的值,puppet 會將控制變量按列出的次序與每一個case 進行比較,並在遇到一個匹配的 case 後,將其值做爲整個語句的值進行返回,並忽略後面的其它 case。
  2. 控制變量與各 case 比較的方式與 case 語句相同,但若是沒有任何一個 case 與控制變量匹配時,puppet 在編譯時將會返回一個錯誤,所以,實踐中,其必須提供default case。
  3. selector 的控制變量只能是變量或有返回值的函數,切記不能使用表達式。
  4. 其各 case 能夠是直接值(須要加引號) 、變量、能調用返回值的函數、正則表達式模式或 default。
  5. 但與 case 語句所不一樣的是,selector 的各 case 不能使用列表。
  6. selector 的各 case 的值能夠是一個除了 hash 之外的直接值、變量、能調用返回值的函數或其它的 selector。

舉例

vim selector.pp
	$pkgname = $operatingsystem ? {
		/(?i-mx:(ubuntu|debian))/       => 'apache2',
		/(?i-mx:(redhat|fedora|centos))/        => 'httpd',
		default => 'httpd',
	}
	package{"$pkgname":
		ensure  => installed,
	}

寫在後面

  以上,咱們本次的介紹就告一段落,剩餘的部分,請看下回分解。

相關文章
相關標籤/搜索