自動化運維工具—puppet詳解

轉載:
作者:珂兒吖
出處:http://www.cnblogs.com/keerya/
本文版權歸作者和博客園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接,否則保留追究法律責任的權利。
大家寫文都不容易,希望尊重勞動成果喲~

一、puppet 介紹

1、puppet是什麼

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

2、puppet的工作機制

1)工作模型

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

puppet三層模型

puppet三層模型

2)工作流程

工作流程

工作流程

3)使用模型

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

單機使用模型工作原理

單機使用模型工作原理

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

master/agent模式架構

master/agent模式架構

工作原理

master/agent模式工作原理

master/agent模式工作原理

3、puppet 名詞解釋

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

回到頂部

二、puppet 資源詳解

接下來,我們就以單機模式來具體介紹一下puppet的各個部分。

1、程序安裝及環境

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

	yum install -y puppet

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

2、puppet 資源簡介

1)資源抽象

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

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

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

2)資源定義

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

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

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

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

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

3、常用資源總結

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](https://imgconvert.csdnimg.cn/aHR0cHM6Ly91cGxvYWQtaW1hZ2VzLmppYW5zaHUuaW8vdXBsb2FkX2ltYWdlcy8xNjk1MjE0OS1iZjVmMjRiNmE4OWZlODc4LnBuZw?x-oss-process=image/format,png)
屬性:
	message:記錄的信息
	name:信息名稱

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


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

4、資源的特殊屬性

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驗證

驗證成功,實驗完成。

5、puppet 變量

puppet 變量以“=”開頭,賦值操作符爲“=”,語法爲`variable_name=value`。
數據類型:

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

正則表達式:

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

1)puppet的變量種類

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

6、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,
	}
發佈了176 篇原創文章 · 獲贊 50 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章