我通過伯樂在線翻譯了一個Puppet簡明教程,一共分為四部分,這是第二部分。
原文地址:http://blog.jobbole.com/87680/
本文由伯樂在線-Wing翻譯,黃利民校稿。未經許可,禁止轉載!英文出處:Manue Kiessling。歡迎加入翻譯組。
關于在第一部分中,我們已經建立了兩個linux系統虛擬機:puppetserver和puppetclient。我們已經實現了一個重要的里程碑:在虛擬機上分別安裝了Puppet服務器和Puppet客戶端軟件,并且在Puppet服務器端對Puppet客戶端進行了認證。接下來我們要在此基礎上,開始通過在puppetserver虛擬機上的Puppet服務器,來配置puppetclient虛擬機系統。
你好,Puppet我們以一個非?;镜氖纠_始。在這個示例中,我們為puppetclient虛擬機建立一個非常簡單的配置:在puppetclient虛擬機系統的/home/Ubuntu目錄下創建一個名為helloworld.txt文件,文件的內容是”Hello World!”。
Puppet自帶一個功能強大的聲明式配置語言。我們使用這種語言來編寫的內容被稱為清單(manifest)。Puppet清單是一個文件,它描述了目標系統中的某些方面應該是什么樣的。在這個系列教程中,我們會編寫很多不同的清單:其中一些會在目標系統上創建一些文件;一些會創建用戶賬戶;一些會安裝軟件包。
清單會被應用到目標系統上。對Puppet來說,目標系統被稱為節點(node)。我們的puppetclient虛擬機系統就是這樣一個節點。我們已經為它做了Puppet服務器認證,這樣可以保證Puppet服務器來管理這個節點。但我們的服務器還沒有任何信息,可以用來管理這個節點。我們可以通過編寫一個清單并將其放在節點上來改變它。
為此,我們會創建一個非常簡單的清單定義,這個定義會被放在puppetserver虛擬機系統的主清單文件中,文件的路徑是/etc/puppet/manifests/site.pp:
/etc/puppet/manifests/site.pp on puppetserver
12345678910 | node "puppetclient" {
file { "/root/helloworld.txt" :
ensure => file,
owner => "root" ,
group => "root" ,
mode => 0644
} } |
我們稍后會看到,清單可以通過模塊化的方式放到任意數目的不同文件中(這樣可以幫助我們針對大型復雜的站點建立清單結構)。但是一切都還是從site.pp開始。
我們來仔細分析一下這個最簡化的清單,它包含兩部分:一個包含file定義的node,因為file部分包含在node部分中,這樣file部分的定義產生的結果會應用到名為puppetclient的節點上。
通過在puppetclient虛擬機系統上運行Puppet代理,我們可以很容易理解上面描述的內容。
On the puppetclient VM
1234 | ~ # sudo puppet agent --verbose --no-daemonize --onetime info: Caching catalog for puppetclientinfo: Applying configuration version '1395862307' notice: /Stage [main] //Node [puppetclient] /File [ /home/ubuntu/helloworld .txt] /ensure : created notice: Finished catalog run in 0.03 seconds |
或許這看上去沒有什么大驚小怪:puppetclient虛擬機上的Puppet代理聯系到puppetserver虛擬機上的Puppet master。然后它接收目錄,這個目標就是在master上定義的所有和這個指定客戶端有關的清單。如果你感興趣的話,這個目錄被存在一個yaml結構中,它存儲在/var/lib/puppet/client_yaml/catalog/puppetclient.yaml中,這不僅僅是復制了我們的.pp清單,而是通過對清單進行解析,生成的一個關于目標配置信息的編譯版本。
接下來,Puppet代理開始采取行動——當且僅當滿足以下條件才會采取行動:Puppet代理會比較清單中期望的狀況和目標節點上清單的狀況,如果其中有一些不同(如果目標節點上找到的狀況并沒有同步到期望達到的狀況)——那么代理就會做任何必需的操作來移除這些區別,來實現目標狀況。
在我們這個特定的示例中,代理知道在目標節點的/home/ubuntu目錄下,應該有一個名為helloworld.txt的文件,這個文件的所有者和所在組是ubuntu,用戶對該文件的訪問權限是0644。然而,當檢查本地系統時,發現并沒有發現這個文件。代理會采取行動,來創建這個期待中的文件。
我們可以通過再次運行代理來驗證這個行為:
On the puppetclient VM
1234 | ~ # sudo puppet agent --verbose --no-daemonize --onetime info: Caching catalog for puppetclient info: Applying configuration version '1395862542' notice: Finished catalog run in 0.03 seconds |
如我們所見,這次代理并沒有做任何事情,這是因為目標節點的狀況已經滿足了。那如果我們修改目標節點上的狀況會怎么樣呢?讓我們來修改這個文件的訪問模式:
在 puppetclient VM 上
~#chmod 0640 /home/ubuntu/helloworld.txt
然后再次運行代理:
在 puppetclient VM 上
123456 | ~# sudo puppet agent --verbose --no-daemonize --onetime info: Caching catalog for puppetclient info: Applying configuration version '1395862307' notice: /Stage[main] //Node[puppetclient]/File[/home/ubuntu/helloworld.txt]/ensure: created notice: Finished catalog run in 0.03 seconds |
代理注意到了區別,然后通過修改文件訪問模式來移除了這個區別。
如果我們修改了文件的內容,會發生什么呢?
在 puppetclient VM 上
~#echo "This is a test" > /home/ubuntu/helloworld.txt
…這時運行代理?
在 puppetclient VM 上
12345 | ~ # sudo puppet agent --verbose --no-daemonize --onetime info: Caching catalog for puppetclient info: Applying configuration version '1395862542' notice: Finished catalog run in 0.03 seconds |
沒有發生任何事情。為什么?因為在清單中,我們沒有對文件內容進行任何描述。我們所做的是讓Puppet來保證這個指定名字的文件是存在的,并且這個文件的一些元數據(擁有者、用戶組、訪問模式)應該有指定設置。Puppet只會關心那些我們讓它去關心的事情。
我們在之前示例中看到的行為,正好表明了Puppet哲學的核心。在我們的清單中,我們不告訴Puppet做什么,我們也不告訴它怎么去做,我們只告訴Puppet最終的結果應該是什么樣子。
這種哲學帶來了巨大的能量,因為它對配置系統所需要的繁重的工作進行了抽象。它撫平了不同的操作系統帶來的差別??紤]下面一個場景,你有一個由不同的Linux系統構成的網絡:有些運行Red Hat Linux,有些在運行Ubuntu Linux。我們進一步假設你希望在所有的系統上安裝htop包。如果我們需要告訴Puppet做什么和怎么做,那么我們不得不編寫一個清單,它在Ubuntu上使用apt-get,在Red Hat上使用yum。相反,我們所需要放到清單中的內容如下所示:
123 | package { "htop" :
ensure => installed } |
目標節點中的puppet代理會去搞清楚如何做,才能實現清單中描述的目標場景。Red Hat系統中的代理會使用yum來安裝包,而Ubuntu系統中的代理則會使用apt-get。
我們在稍后會回來討論包安裝,讓我們繼續之前的文件示例。通過Puppet來創建一個空文件,通常都不是特別有用——當然我們更喜歡部署一些帶內容的文件。Puppet可以很容易做到:我們可以將文件放在puppetserver虛擬機上,然后通過Puppet將其傳輸到puppetclient虛擬機上。
首先,我們在puppetserver虛擬機上創建源文件:
在 puppetserver VM 上
123 | ~ # sudo -s ~ # mkdir /etc/puppet/files ~ # echo "Hello World." > /etc/puppet/files/helloworld.txt |
然后,我們需要允許Puppet客戶端來訪問這個文件,為此,我們需要修改puppetserver虛擬機上的/etc/puppet/fileserver.conf文件,添加一個allow *語句:
/etc/puppet/fileserver.conf on puppetserver
123456789101112131415161718 | # This file consists of arbitrarily named sections/modules # defining where files are served from and to whom # Define a section 'files' # Adapt the allow/deny settings to your needs. Order # for allow/deny does not matter, allow always takes PRecedence # over deny [files]
path /etc/puppet/files
allow * # allow *.example.com # deny *.evil.example.com # allow 192.168.0.0/24 [plugins] # allow *.example.com # deny *.evil.example.com # allow 192.168.0.0/24 |
現在我們可以修改/etc/puppet/manifest/site.pp清單文件,擴展其中已有的file塊:
/etc/puppet/manifests/site.pp on puppetserver
1234567891011 | node "puppetclient" {
file { "/root/helloworld.txt" :
ensure => file,
owner => "root" ,
group => "root" ,
mode => 0644 ,
source => "puppet://puppetserver/files/helloworld.txt"
} } |
讓我們再次運行客戶端系統上的代理:
在 puppetclient VM 上
12345678 | ~ # sudo puppet agent --verbose --no-daemonize --onetime info: Caching catalog for puppetclient info: Applying configuration version '1395878127' info: FileBucket adding {md5}ff22941336956098ae9a564289d1bf1b info: /Stage [main] //Node [puppetclient] /File [ /home/ubuntu/helloworld .txt]: Filebucketed /home/ubuntu/helloworld .txt to puppet with sum ff22941336956098ae9a564289d1bf1b notice: /Stage [main] //Node [puppetclient] /File [ /home/ubuntu/helloworld .txt] /content : content changed '{md5}ff22941336956098ae9a564289d1bf1b' to '{md5}770b95bb61d5b0406c135b6e42260580' notice: Finished catalog run in 0.09 seconds |
現在Puppet代理的確會關心文件的內容,它會使用從puppetserver虛擬機上得到的文件,來覆蓋現有文件。
在第三部分中,我們會看一個更復雜的清單,以及如何將清單組織成不同的模塊。
新聞熱點
疑難解答