puppet 5.3簡介

參考:
https://puppet.com/docs/puppet/5.3/index.html (語法參考官網)
https://www.gitbook.com/download/pdf/book/kisspuppet/puppet(實例推薦參考這個
《puppet實戰》劉宇著 (原理參考這本書,版本比較舊)

簡介:
作爲一名苦逼的運維工程師,我們會遇到類似這種情況:有某款xxx軟件需要我們批量部署在不同系統的平臺上,這就要求我們懂得對每個平臺的xxx軟件的部署,類似的結果卻要求不同的操作,足以讓人鬱悶。 要是能夠描述下需求,每臺自動部署就好了。而puppet就是爲了滿足這種需求的一款軟件

puppet本質其實就是對catalog的配置進行編譯和應用。

那麼什麼是catalog呢?
我們前面說過,我們希望可以描述下需求,然後節點自動進行部署,catalog就是我們描述需求的文檔,我們的對象是主機,所以可以想象catalog裏面其實是對主機各種狀態的描述,而puppet負責解讀這個文件,並把主機配置爲catalog描述的狀態。
至於爲什麼需要編譯過程,其實也很好理解,類似於低級語言和高級語言的關係,低級語言高效,但是不好理解,於是封裝各種功能,弄成高級語言。高級語言無法被底層識別,所以最終還是要轉化爲低級語言執行,高級語言-->低級語言的過程就是編譯。catalog前面還有一個更爲高級的描述語言,在puppet中是在一堆.pp結尾的文件進行描述,編譯的過程在puppet中的體現就是(.pp文件的內容 轉化爲catalog的過程)但是catalog本身最終也還是要轉化爲機器能執行的低級語言(即二進制代碼)。

明白了這點後,就比較容易理解puppet的兩種架構:

agent/master架構:
所謂的agent/master,其實就是弄一臺主機專門負責配置和編譯.pp結尾文件生成catalog的,並把編譯好的catalog分發給對應的主機執行。這種架構的優點顯而易見,集中管理編譯分發,各個節點不需要浪費資源在編譯上,所以執行效率高,管理方便。缺點是master容易成爲整個架構的瓶頸,所以一般會結合負載均衡和高可用這類軟件進行更復雜的架構。

stand-alone架構:
這種架構其實就是把編譯的過程放到了各個節點上,優點是一個節點掛不會影響到其他節點,缺點就是浪費大量資源在編譯上,效率低下,不便於管理,因爲缺點比優點多,所以一般建議使用第一種架構。這篇文檔也基於agent/master架構。

1.安裝
master:

    sudo rpm -Uvh https://yum.puppet.com/puppet5/puppet5-release-el-6.noarch.rpm (配置puppet yum源)
    yum install puppetserver -y

agent:

    sudo rpm -Uvh https://yum.puppet.com/puppet5/puppet5-release-el-6.noarch.rpm  #centos 6系列
    (sudo rpm -Uvh https://yum.puppet.com/puppet5/puppet5-release-el-7.noarch.rpm)#centos 7系列
    yum install puppet-agent -y
    (puppetserver 依賴於puppet-agent,所以裝puppetserver也會自動裝上puppet-agent)

puppet 5.3的版本目錄對比之前的版本位置有了些變化,幾個核心的目錄如下:(linux下的目錄,其他系統參考官網)

/etc/puppetlabs/code:存放puppet代碼和數據的目錄,我們大部分的操作(對節點進行描述)就在這個目錄
/etc/puppetlabs/puppet: puppet的配置路徑,(設置puppet的工作環境,這也是核心的功能)
/etc/puppetlabs/puppetserver: puppetserver 的配置目錄(puppetserver可以簡單看成是對puppet進行任務分配的工具)
/etc/puppetlabs/mcollective: mcollective是一個運行框架,方便puppet的管理

現在,再來看看maste/agent架構下的幾個問題:
1.master如何知道節點的基本信息?
你可能會說,這些當然是自己寫到puppet的配置文件上去的。沒錯,有些信息是自己寫的,但是有些信息手動寫不僅繁瑣而且沒必要,比如節點的系統版本,內存大小,時區等等信息,事實上,puppet的客戶端利用一個叫facter的軟件收集了這些信息並傳遞給puppet master。

2.如果有多節點,master如何知道該把寫好的配置分配給哪些節點?
一種方法是master把寫好的配置羣發,讓客戶端進行判斷,另一種方法是master先判斷該發給誰,並只發送該節點對應的配置。 puppet採用第二種方法,它是根據主機名進行節點分類,然後發送相關配置。

3.master根據主機名進行分配配置,那麼如果有人冒充客戶端的主機名,master不就可能把一些重要的配置發送出去了?而且客戶端收到配置的時候,如何知道這是靠譜的master發來的,而不是別的主機惡意行爲?
這裏就用到了非對稱密鑰的原理,事實上,master和agent在開始建立鏈接前有個認證過程,爲了高效地管理,master自建了個CA(5.3的CA配置目錄在/etc/puppetlabs/puppet/ssl/),然後對agent的主機進行簽發證書認證,利用ssl加密傳輸數據,這樣就保證了兩臺主機之間靠譜通信。
puppet 5.3簡介
所以,master/agent架構下,puppet的工作流程大概是這樣的:
<1>puppet 客戶端和服務端通過證書原理建立安全連接
<2>agent將facts信息發送給master
<3>master利用facts信息和自身的配置進行編譯生成catalog,併發送給agent
<4>agent對catalog進行代碼驗證(語法檢查等)並執行,將執行結果寫入日誌
<5>agent 最終達到最開始所定義的狀態,並且將結果及任何執行數據通過開放api的形式發送給master

瞭解了這些,就可以開始做實驗了,這個文檔只簡單介紹構建一個安裝包的過程

2.master和agent建立聯繫

master:

[root@cqhdtest httpd]# hostname  cqhdtest.com   #自己要修改自己的主機名
[root@cqhdtest httpd]# cat /etc/sysconfig/network
NETWORKING=yes
HOSTNAME=cqhdtest.com
[root@cqhdtest httpd]# cat  /etc/hosts
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
192.168.124.127 cqhdtest.com
192.168.124.138  node1.com
192.168.124.221  vhos-ftp.com
192.168.124.111  centos7.com

#puppet 根據主機名來識別身份,這裏做實驗,簡單用host綁定域名,效率高,如果架構大的話,建議自建個dns服務專門解析節點域名

vi /etc/sysconfig/puppetserver``
#JAVA_ARGS="-Xms2g -Xmx2g -Djruby.logger.class=com.puppetlabs.jruby_utils.jruby.Slf4jLogger" 
JAVA_ARGS="-Xms512m -Xmx512m -Djruby.logger.class=com.puppetlabs.jruby_utils.jruby.Slf4jLogger"

#修改這個是因爲我是虛擬機做的,puppetserver默認需要2G的內存才能啓動,這裏我改爲512m,想做實驗又發現一直提示內存不夠的,修改這個即可

[root@cqhdtest ~]# cat  /etc/puppetlabs/code/environments/production/manifests/site.pp 
node 'default'{                         #node是標記節點的資源,default代表默認,類似於httpd的默認主機
    notify { "i am running on node $fqdn":}    #notify在節點上打印{}裏面的內容,這裏的$fqdn就是節點上的facter傳遞給master的參數
}
#類似於c語言的main函數,puppetserver讀取配置文件是從一個叫site.pp的文件開始的,從這個文件用include之類的指令加入其它文件,生成最終的catalog,這裏,我們簡單地用一個notify資源作爲本實驗的開頭

/etc/init.d/puppetserver start  
netstat -tnlp|grep 8140  #查看是否服務有起來,默認監聽 8140

agent:

[root@centos7 ~]#hostname centos7.com
[root@centos7 ~]# cat /etc/sysconfig/network
NETWORKING=yes
HOSTNAME=centos7.com
[root@centos7 ~]# cat  /etc/hosts
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
192.168.124.127 cqhdtest.com
192.168.124.138  node1.com
192.168.124.221  vhos-ftp.com
192.168.124.111  centos7.com
#一樣的,客戶端需要知道主機在哪
[root@centos7 ~]# cat  /etc/puppetlabs/puppet/puppet.conf 
[main]
certname = centos7.com  #填寫客戶端的主機名
server = cqhdtest.com   #填寫master的主機名
environment = production  #這個是環境的版本,puppet可以支持多環境切換,比如測試環境測試成功後再轉到生產環境
runinterval = 1h        #這個是客戶端主動向服務端讀取更新配置時間,也可以在master端配置puppet  kick主動推送

[root@centos7 ~]# puppet  agent --test  
Info: Creating a new SSL key for centos7.com
Info: Caching certificate for ca
Info: csr_attributes file loading from /etc/puppetlabs/puppet/csr_attributes.yaml
Info: Creating a new SSL certificate request for centos7.com
Info: Certificate Request fingerprint (SHA256): 49:B7:9D:E6:1F:DF:08:EF:68:0E:F0:67:87:02:31:96:BD:B0:C7:C2:60:E6:E4:6E:99:C6:C9:4F:7B:5C:50:2A
Info: Caching certificate for ca
Exiting; no certificate found and waitforcert is disabled
#這個時候puppet 會生成csr文件,像master請求籤署,也就是相當於請求master的認可

master:
[root@cqhdtest httpd]# puppet cert list 
  "centos7.com" (SHA256) 49:B7:9D:E6:1F:DF:08:EF:68:0E:F0:67:87:02:31:96:BD:B0:C7:C2:60:E6:E4:6E:99:C6:C9:4F:7B:5C:50:2A
#接收到centos7的簽署請求
[root@cqhdtest httpd]# puppet cert sign centos7.com
Signing Certificate Request for:
  "centos7.com" (SHA256) 49:B7:9D:E6:1F:DF:08:EF:68:0E:F0:67:87:02:31:96:BD:B0:C7:C2:60:E6:E4:6E:99:C6:C9:4F:7B:5C:50:2A
Notice: Signed certificate request for centos7.com
Notice: Removing file Puppet::SSL::CertificateRequest centos7.com at '/etc/puppetlabs/puppet/ssl/ca/requests/centos7.com.pem'
#簽署請求,想取消可以puppet cert clean centos7.com,此時客戶端就必須重新生成證書再請求
[root@cqhdtest httpd]# tree  /etc/puppetlabs/puppet/ssl/ca/
/etc/puppetlabs/puppet/ssl/ca/
├── ca_crl.pem
├── ca_crt.pem
├── ca_key.pem
├── ca_pub.pem
├── inventory.txt
├── private
├── requests
├── serial
└── signed
    ├── centos7.com.pem
    ├── cqhdtest.com.pem
    ├── node1.com.pem
    └── vhos-ftp.com.pem
#這是puppet 5存放證書的目錄,關於證書的問題,可以通過這個目錄獲取到一些有用的信息

agent:
[root@centos7 ~]# puppet  agent --test  
Info: Caching certificate for centos7.com
...
...
Info: Caching catalog for centos7.com
Info: Applying configuration version '1514273497'
Notice: i am running on node centos7.com
Notice: /Stage[main]/Main/Node[default]/Notify[i am running on node centos7.com]/message: defined 'message' as 'i am running on node centos7.com' #執行成功
Notice: Applied catalog in 0.08 seconds

3.puppet上構建一個簡單的httpd安裝模塊
master:

[root@cqhdtest manifests]# cat site.pp
node  'centos7.com'{
    include  httpd      #給centos7這個節點加載httpd模塊
}
node 'default'{
    notify { "i am running on node $fqdn":}
}
[root@cqhdtest manifests]# cd /etc/puppetlabs/code/environments/production/modules/
[root@cqhdtest modules]# mkdir httpd  
#創建模塊目錄,這個目錄名字必須和site.pp裏面的include後面的參數一樣,puppet根據這個名稱加載模塊裏面的.pp文件
[root@cqhdtest modules]# cd httpd/
[root@cqhdtest httpd]# mkdir  manifests templates files
#這三個目錄都不是隨意起名字的
    manifests:存放的是.pp文件,當puppet加載模塊的時候,先從這個路徑下的init.pp文件加載
    templates:存放模板文件,裏面一般是利用facter傳遞過來的參數生成的配置文件的模板
    files:存放一般的文件,一些寫好的,各節點通用的文件可以放在這個目錄

    [root@cqhdtest httpd]# cd manifests/
[root@cqhdtest manifests]# cat init.pp 
class httpd{
    include httpd::install,httpd::config
}
#這個是第一個加載的.pp文件,對類的全局變量的初始化一般放在這裏,這裏我並沒做更多的操作,只是定義了兩個子類,用來對httpd的安裝和配置
[root@cqhdtest manifests]# cat install.pp 
class httpd::install{       
    yumrepo { "repo163":    
        descr =>"repo test",
        baseurl => "http://mirrors.163.com/centos/6/os/x86_64/",
        gpgcheck =>"0",
        enabled =>"1";
}

package {
        "httpd":                        #安裝包的名字,不同系統對應不同名字,可以利用case $os.name 進行判斷,這裏簡單實驗,不做判斷
        ensure => installed,            #狀態
        require => Yumrepo["repo163"];  #require指令會要求repo163這個yum源存在的時候才執行安裝操作,指定依賴的時候就用這個
}
}
#這裏的install.pp也不是隨便取名的,它是根據init.pp裏面的子類名 httpd::install 裏的install+.pp命名的,puppet的找名字就是根據這種規律來的,同理,我們還需要建個config.pp

[root@cqhdtest manifests]# cat config.pp 
class httpd::config{
    file{ '/etc/httpd/conf.d/vhost.conf':     #file指令可以對文件進行操作
        ensure => present,
        mode   => '0644',
        content=>template('httpd/vhost.conf.erb'), #這個代表file的內容根據模板來
        require=>Class['httpd::install'],       #這個代表要先裝httpd才生成配置文件
    }
}
#需要注意的是這裏template的路徑是比較詭異的,路徑中的httpd代表的是httpd這個模塊,vhost.conf.erb這個文件的真正路徑卻是在httpd模塊的templates下,也就是
/etc/puppetlabs/code/environments/production/modules/httpd/templates/vhost.conf.erb

[root@cqhdtest manifests]# cat  /etc/puppetlabs/code/environments/production/modules/httpd/templates/vhost.conf.erb 
<VirtualHost *:80>
    DocumentRoot /var/www/html
    ServerName <%= @hostname %>.com     
    ErrorLog logs/localhost.com-error_log
    CustomLog logs/localhost.com-access_log common
</VirtualHost>
#這裏唯一需要注意的是hostname這個facter傳遞過來的參數需要用<%= @hostname %>引用(裏面有個@,沒有@是自定義的變量)

agent:

[root@centos7 ~]# rpm -qa|grep httpd
[root@centos7 ~]# puppet  agent --test  
Info: Using configured environment 'production'
Info: Retrieving pluginfacts
Info: Retrieving plugin
Info: Loading facts
Info: Caching catalog for centos7.com
Info: Applying configuration version '1514280511'
Notice: /Stage[main]/Httpd::Install/Yumrepo[repo163]/ensure: created
Info: Yumrepo[repo163](provider=inifile): changing mode of /etc/yum.repos.d/repo163.repo from 600 to 644
Notice: /Stage[main]/Httpd::Install/Package[httpd]/ensure: created
Notice: /Stage[main]/Httpd::Config/File[/etc/httpd/conf.d/vhost.conf]/ensure: defined content as '{md5}8ad25542b2a4bb9f6d6037d8f7d04a8e'
Notice: Applied catalog in 24.99 seconds
[root@centos7 ~]# rpm -qa|grep httpd
httpd-2.4.6-67.el7.centos.6.x86_64
httpd-tools-2.4.6-67.el7.centos.6.x86_64
[root@centos7 ~]# cat  /etc/httpd/conf.d/vhost.conf 
<VirtualHost *:80>
    DocumentRoot /var/www/html
    ServerName centos7.com
    ErrorLog logs/localhost.com-error_log
    CustomLog logs/localhost.com-access_log common
</VirtualHost>

測試成功,這裏簡化了很多步驟,想要詳細的,推薦看https://www.gitbook.com/download/pdf/book/kisspuppet/puppet 基礎篇7

debug:

  1. Error: /File[/opt/puppetlabs/puppet/cache/facts.d]: Failed to generate additional resources using 'eval_generate': SSL_connect returned=1 errno=0 state=unknown state: sslv3 alert certificate unknown
    這個是客戶端和服務端直接的認證沒認證好,客戶端已有證書卻不能重新認證(原因待查明),解決方法:重新生成客戶端的證書,服務端重新簽署
    假設:客戶端的certname爲a.com
    服務端: puppet cert clean a.com
    客戶端: rm -rf /etc/puppetlabs/puppet/ssl (/etc/puppetlabs/puppet/ssl 爲客戶端存放證書的路徑)
    puppet agent --test
    服務端: puppet cert sign a.com

2.Error: Could not request certificate: SSL_connect returned=1 errno=0 state=error:r /CN=Puppet CA: cqhdtest.com]
這個錯誤是客戶端和服務端的時間沒同步,分別ntpdate同步下時間即可

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章