天天看點

Puppet擴充篇1-自定義fact結合ENC(hirea)的應用實踐一、先來解決節點與類結合的問題1、在Master端安裝hiera工具2、編輯hiera主配置檔案hiera.yaml3、應用hiera變量于Puppetmaster4、測試

零基礎學習Puppet自動化配置管理系列文檔

在大量節點加入Puppet之後,你至少會面臨兩個比較大的問題:

1、由于節點數的增多,site.pp檔案必然會編寫更多的節點條目,以及節點包含的類。假設你用Puppet管理500個節點,存在三種情況:1、所有節點有共同的類,也可以了解為子產品;2、所有節點分成了50組,每組節點有不同的應用,每組應用編寫一個子產品;3、每個節點也應該有一個自己的子產品,在這種環境下,可想而知,site.pp檔案是多麼的複雜,多麼的難以維護。

其實、節點與類之間的結合,更多時候是要借助ENC(外部節點分類器)來完成,因為puppet軟體本身并不具備此類功能。Puppet-dashboard企業版和Foreman已經具備了這方面的功能,而且是圖形界面操作,還是很友善的。衆所周知,Puppet-dashboard社群版目前最新版本為1.2.23,到目前為止已經有一年多未更新了,可見Puppetlabs的意圖很明确,逼着你用企業版。而Foreman部署和使用略複雜些,其次Foreman很重,它的内部并不僅僅是包含puppet還包含了很多其它管理工具,非常龐大,可以酌情考慮使用。接下來要介紹的是官方推薦的hiera軟體,一個很強大的ENC,編寫的檔案隻要遵循yaml格式即可,使用非常友善,可惜的是沒有圖形界面。但這并不代表你不會開發圖形界面哦。

hiera工具和Puppetmaster結合需要通過hiera-puppet工具完成,在puppet-server 3.0.*版本後,這個工具已經內建到了puppet-server安裝包中。而我們現在使用的環境仍然是puppet2.7版本,是以需要安裝hiera-puppet工具。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

<code>[root@puppetmaster RHEL6U4]</code><code># yum install hiera hiera-puppet #注意依賴關系</code>

<code>...</code>

<code>Dependencies Resolved</code>

<code>===========================================================================</code>

<code>Package          Arch       Version                 Repository       Size</code>

<code>Installing:</code>

<code>hiera            noarch     1.3.2-1.el6             rhel-puppet      23 k</code>

<code>hiera-puppet     noarch     1.0.0-1.el6             rhel-puppet      14 k</code>

<code>Installing fordependencies:</code>

<code>ruby-irb         x86_64     1.8.7.352-7.el6_2       rhel-base       311 k</code>

<code>ruby-rdoc        x86_64     1.8.7.352-7.el6_2       rhel-base       375 k</code>

<code>rubygem-json     x86_64     1.5.5-1.el6             rhel-puppet     763 k</code>

<code>rubygems         noarch     1.3.7-1.el6             rhel-puppet     206 k</code>

<code>Transaction Summary</code>

預設hiera.yaml主配置檔案在/etc目錄下,為了結合後期版本控制系統集中管理,建議将此檔案copy到/etc/puppet目錄下,然後建立軟連接配接指向/etc/hiera.yaml即可。

<code>[root@puppetmaster ~]# mv /etc/hiera.yaml /etc/puppet/</code>

<code>[root@puppetmaster ~]# ln -s /etc/puppet/hiera.yaml /etc/hiera.yaml</code>

<code>[root@puppetmaster ~]# ll /etc/hiera.yaml</code>

<code>lrwxrwxrwx 1root root 22Apr </code><code>2020</code><code>:</code><code>05</code><code>/etc/hiera.yaml -&gt; /etc/puppet/hiera.yaml</code>

添加全局變量common,注釋掉defaults、global和clientcert。

添加系統類型變量osfamily

添加主機名變量hostname

添加datadir路徑位置,中間用了puppet環境變量,這裡的環境變量和puppet應用的環境變量是一緻的。如果你隻有一種環境,隻需要将其中變量去掉即可。

備注: 以上變量其實就是fact變量。

<code>[root@puppetmaster ~]# vim /etc/puppet/hiera.yaml</code>

<code>---</code>

<code>:backends:</code>

<code>- yaml</code>

<code>:hierarchy:</code>

<code>#  - defaults</code>

<code>#  - </code><code>"%{clientcert}"</code>

<code>- common</code>

<code>- </code><code>"%{environment}"</code>

<code>- </code><code>"%{osfamily}"</code>

<code>- </code><code>"%{hostname}"</code>

<code>#  - global</code>

<code>:yaml:</code>

<code>:datadir:</code><code>"/etc/puppet/environments/%{environment}/hiera"</code>

hiera主配置檔案編寫完成之後,需要重新開機puppetmaster後方可生效。

<code>[root@puppetmaster hiera]# /etc/init.d/puppetmaster restart</code>

<code>Stopping puppetmaster:                                     [  OK  ]</code>

<code>Starting puppetmaster:                                     [  OK  ]</code>

<code>[root@puppetmaster hiera]# vim common.yaml</code>

<code>puppetserver:</code>

<code>- </code><code>'puppetmaster.kisspuppet.com'</code>

通過hiera指令測試

<code>[root@puppetmaster ~]# hiera puppetserver environment=kissprd</code>

<code>[</code><code>"puppetmaster.kisspuppet.com"</code><code>]</code>

<code>[root@puppetmaster ~]# hiera puppetserver environment=kissdev</code>

<code>nil</code>

通過以上指令可以得知在環境為kissprd的情況下,puppetserver的變量為puppetmaster.kisspuppet.com,值為nil的意思是不存在。

<code>[root@agent1 ~]# facter osfamily</code>

<code>RedHat</code>

<code>[root@puppetmaster hiera]# vim RedHat.yaml</code>

<code>classes:</code>

<code>- </code><code>'puppet'</code>

<code>- </code><code>'yum'</code>

<code>[root@puppetmaster hiera]# hiera classes environment=kissprd</code>

<code>[root@puppetmaster hiera]# hiera classes environment=kissprd osfamily=RedHat</code>

<code>[</code><code>"motd"</code><code>, </code><code>"puppet"</code><code>, </code><code>"yum"</code><code>]</code>

<code>[root@puppetmaster hiera]# hiera classes environment=kissprd osfamily=SLES</code>

通過以上指令可以得在環境為kissprd,系統為RedHat的情況下,classes的變量為三個值(puppet、yum)。

18

<code>[root@agent1 ~]# facter hostname</code>

<code>agent1</code>

<code>[root@puppetmaster hiera]# vim agent1.yaml</code>

<code>- </code><code>'motd'</code>

<code>certname:</code>

<code>- </code><code>'agent1_cert.kisspuppet.com'</code>

<code>[root@puppetmaster hiera]# vim agent2.yaml</code>

<code>- </code><code>'agent2_cert.kisspuppet.com'</code>

<code>[root@puppetmaster hiera]# vim agent3.yaml</code>

<code>- </code><code>'agent3_cert.kisspuppet.com'</code>

<code>[root@puppetmaster hiera]# hiera classes environment=kissprd hostname=agent</code>

<code>1</code>

<code>[</code><code>"motd"</code><code>]</code>

<code>2</code>

<code>3</code>

<code>[root@puppetmaster hiera]# hiera certname environment=kissprd hostname=agent1</code>

<code>[</code><code>"agent1_cert.kisspuppet.com"</code><code>]</code>

<code>[root@puppetmaster hiera]# hiera certname environment=kissprd hostname=agent2</code>

<code>[</code><code>"agent2_cert.kisspuppet.com"</code><code>]</code>

<code>[root@puppetmaster hiera]# hiera certname environment=kissprd hostname=agent3</code>

<code>[</code><code>"agent3_cert.kisspuppet.com"</code><code>]</code>

通過以上指令測試可以得知,系統fact變量hostname為agent1和agent2的情況下,hiera變量classes為motd。certname變量為各自的certname變量。

以前的寫法:

<code>[root@puppetmaster ~]# vim /etc/puppet/environments/kissprd/manifests/site.pp</code>

<code>$puppetserver = </code><code>'puppetmaster.kisspuppet.com'</code>

<code>classenvironments{</code>

<code>includepuppet,yum</code>

<code>}</code>

<code>node </code><code>'puppetmaster_cert.kisspuppet.com'</code><code>{</code>

<code>includeenvironments</code>

<code>node </code><code>'agent1_cert.kisspuppet.com'</code><code>{</code>

<code>includeenvironments,motd</code>

<code>node </code><code>'agent2_cert.kisspuppet.com'</code><code>{</code>

<code>node </code><code>'agent3_cert.kisspuppet.com'</code><code>{</code>

應用了hiera之後的寫法:

<code>$puppetserver = hiera(</code><code>'puppetserver'</code><code>)  #引用了hiera中common.yaml中的全局變量puppetserver</code>

<code>node </code><code>default</code><code>{</code>

<code>hiera_include(</code><code>'classes'</code><code>)  #引用了hiera中osfamily和hostname變量</code>

備注:以後添加節點,隻需要編寫yaml檔案即可,而site.pp檔案無需在進行修改。

未使用hiera之前的編寫方式

<code>[root@puppetmaster hiera]# vim /etc/puppet/environments/kissprd/environment/modules/puppet/manifests/params.pp</code>

<code>classpuppet::params {</code>

<code>$certname = </code><code>"${::hostname}_cert.kisspuppet.com"</code>

<code>case</code><code>$operatingsystemmajrelease{</code>

<code>5</code><code>: {</code>

<code>$puppet_release = </code><code>'2.7.23-1.el5'</code>

<code>$facter_release = </code><code>'1.7.3-1.el5'</code>

<code>6</code><code>: {</code>

<code>$puppet_release = </code><code>'2.7.23-1.el6'</code>

<code>$facter_release = </code><code>'1.7.3-1.el6'</code>

<code>default</code><code>: {</code>

<code>fail(</code><code>"Module puppet is not supported on ${::operatingsystem}"</code><code>)</code>

應用了hiera變量之後的編寫方式

<code>$puppetserver = hiera(</code><code>'puppetserver'</code><code>)  #應用了hiera全局檔案common.yaml中的puppetserver變量</code>

<code>$certname = hiera(</code><code>'certname'</code><code>)  #應用了hiera中變量hostname對應的節點檔案$hostname.yaml中的certname變量</code>

<a href="http://s3.51cto.com/wyfs02/M00/24/94/wKiom1NTlcjjAV6pAAKZUI7BbXg874.jpg" target="_blank"></a>

<a href="http://s3.51cto.com/wyfs02/M02/24/94/wKioL1NTlZ6y6BnwAAF_ezwx_eI983.jpg" target="_blank"></a>

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

<code>[root@agent3 ~]# vim /etc/puppet/puppet.conf</code>

<code>### config by  puppet ###</code>

<code>[main]</code>

<code>logdir = /</code><code>var</code><code>/log/puppet</code>

<code>rundir = /</code><code>var</code><code>/run/puppet</code>

<code>ssldir = $</code><code>var</code><code>dir/ssl</code>

<code>pluginsync = </code><code>true</code>

<code>[agent]</code>

<code>classfile = $</code><code>var</code><code>dir/classes.txt</code>

<code>localconfig = $</code><code>var</code><code>dir/localconfig</code>

<code>#    server = puppetmaster.kisspuppet.com   #注釋掉進行測試</code>

<code>#    certname = agent3_cert.kisspuppet.com</code>

<code>runinterval = </code><code>10</code>

<code>[root@agent3 ~]# puppet agent -t --environment=kissprd --server=puppetmaster.kisspuppet.com --certname=agent3_cert.kisspuppet.com</code>

<code>info: Retrieving plugin</code>

<code>info: Loading facts </code><code>in</code><code>/</code><code>var</code><code>/lib/puppet/lib/facter/hwclock.rb</code>

<code>info: Caching catalog foragent3_cert.kisspuppet.com</code>

<code>info: Applying configuration version </code><code>'1398008880'</code>

<code>notice: /Stage[main]/Puppet::Config/File[/etc/puppet/puppet.conf]/content:</code>

<code>--- /etc/puppet/puppet.conf    </code><code>2014</code><code>-</code><code>04</code><code>-</code><code>2023</code><code>:</code><code>46</code><code>:</code><code>05.839948111</code><code>+</code><code>0800</code>

<code>+++ /tmp/puppet-file20140420-</code><code>5618</code><code>-45rytg-</code><code>02014</code><code>-</code><code>04</code><code>-</code><code>2023</code><code>:</code><code>48</code><code>:</code><code>01.653944253</code><code>+</code><code>0800</code>

<code>@@ -</code><code>7</code><code>,</code><code>6</code><code>+</code><code>7</code><code>,</code><code>6</code><code>@@</code>

<code>-#    server = puppetmaster.kisspuppet.com</code>

<code>-#    certname = agent3_cert.kisspuppet.com</code>

<code>+    server = puppetmaster.kisspuppet.com</code>

<code>+    certname = agent3_cert.kisspuppet.com</code>

<code>info: FileBucket adding {md5}13430e5962e7584c9422e5adc1f3ba43</code>

<code>info: /Stage[main]/Puppet::Config/File[/etc/puppet/puppet.conf]: Filebucketed /etc/puppet/puppet.conf to puppet withsum 13430e5962e7584c9422e5adc1f3ba43</code>

<code>notice: /Stage[main]/Puppet::Config/File[/etc/puppet/puppet.conf]/content: content changed </code><code>'{md5}13430e5962e7584c9422e5adc1f3ba43'</code><code>to </code><code>'{md5}23545b7afd09af671920f122a20db952'</code>

<code>info: /Stage[main]/Puppet::Config/File[/etc/puppet/puppet.conf]: Scheduling refresh of Class[Puppet::Service]</code>

<code>info: Class[Puppet::Service]: Scheduling refresh of Service[puppet]</code>

<code>notice: /Service[puppet]: Triggered </code><code>'refresh'</code><code>from 1events</code>

<code>notice: Finished catalog run in0.54seconds</code>

<code>[root@agent3 ~]# cat /etc/puppet/puppet.conf</code>

<code>server = puppetmaster.kisspuppet.com</code>

<code>certname = agent3_cert.kisspuppet.com</code>

通過以上測試可以得知hiera變量certname和puppetserver傳輸正常。

特别說明: 由于hiera定義的變量需要通過轉換才能變為puppet能夠使用的變量,而這個轉換是需要耗費CPU資源的,筆者曾經測試過一組節點(50個)同時傳輸hiera的變量數超過2000個,出現CPU負載過高的性能瓶頸問題需要特别注意。其次hiera資料除了用yaml格式儲存外還可以存放在redis資料庫中,這樣查詢起來性能會高很多,具體可參考官網,《pro puppet 》第二版也有這方面的介紹,可參閱。

通過以上測試至少解決了兩個問題:

site.pp編寫繁瑣複雜的問題。

certname名定義問題(可以不适用其他fact變量進行定義,比如不再使用hostname變量,這樣做的好處是即使節點hostname名變化也不會影響puppet通信)

之前facts子產品中的結構

<code>[root@puppetmaster modules]# tree facts/</code>

<code>facts/</code>

<code>├── files</code>

<code>├── lib</code>

<code>│   └── facter</code>

<code>│       └── hwclock.rb   #通過pluginsync模式釋出的自定義fact變量,無需修改</code>

<code>├── manifests</code>

<code>└── templates</code>

<code>5directories, 1file</code>

<code>[root@puppetmaster manifests]# vim config.pp #定義file資源</code>

<code>classfacts::config{</code>

<code>file{ </code><code>"/etc/facter/facts.d/$hostname.txt"</code><code>:   #檔案名稱通過變量hostname擷取</code>

<code>owner   =&gt; </code><code>"root"</code><code>,</code>

<code>group   =&gt; </code><code>"root"</code><code>,</code>

<code>mode    =&gt; </code><code>0400</code><code>,</code>

<code>source  =&gt; </code><code>"puppet:///modules/facts/facts.d/$hostname.txt"</code><code>,  #檔案名稱通過節點變量hostname擷取</code>

<code>require =&gt; Class[</code><code>'facts::exec'</code><code>],</code>

<code>[root@puppetmaster manifests]# vim exec.pp  #定義可執行資源保證目錄 /etc/facter/facts.d 存在</code>

<code>classfacts::exec{</code>

<code>exec {</code><code>"create fact external"</code><code>:</code>

<code>command =&gt; </code><code>"mkdir -p /etc/facter/facts.d "</code><code>,</code>

<code>path    =&gt; [</code><code>"/usr/bin"</code><code>,</code><code>"/usr/sbin"</code><code>,</code><code>"/bin"</code><code>,</code><code>"/sbin"</code><code>],</code>

<code>creates =&gt; </code><code>"/etc/facter/facts.d"</code><code>,</code>

<code>[root@puppetmaster manifests]# vim init.pp</code>

<code>classfacts{</code>

<code>includefacts::config,facts::exec</code>

<code>[root@puppetmaster facts.d]# pwd</code>

<code>/etc/puppet/environments/kissprd/environment/modules/facts/files/facts.d</code>

<code>[root@puppetmaster facts.d]# vim agent1.txt</code>

<code>env=prd</code>

<code>app=weblogic</code>

<code>[root@puppetmaster facts.d]# vim agent2.txt</code>

<code>env=qa</code>

<code>app=db2</code>

<code>[root@puppetmaster facts.d]# vim agent3.txt</code>

<code>app=nginx</code>

由于子產品facts屬于全局的,應用于common.ymal或者RedHat.ymal中即可。

<code>- </code><code>'facts'</code>

<code>[root@agent3 ~]# ll /etc/facter/facts.d</code>

<code>ls: cannot access /etc/facter/facts.d: No such file or directory</code>

<code>[root@agent3 ~]# puppet agent -t --environment=kissprd</code>

<code>info: Applying configuration version </code><code>'1398010573'</code>

<code>notice: /Stage[main]/Facts::Exec/Exec[create fact external]/returns: executed successfully</code>

<code>notice: /Stage[main]/Facts::Config/File[/etc/facter/facts.d/agent3.txt]/ensure: defined content </code><code>as</code><code>'{md5}3330b8efe95f6747de47a9eca3a5411e'</code>

<code>notice: Finished catalog run in0.66seconds</code>

<code>[root@agent3 ~]# cat /etc/facter/facts.d/agent3.txt</code>

<code>[root@agent3 ~]# facter env</code>

<code>prd</code>

<code>[root@agent3 ~]# facter app</code>

<code>nginx</code>

其它節點測試略

注意:以上方法隻是提供給你一種集中管理自定義fact的思路,并不是最好的解決方案,隻不過這種方法目前筆者用于上産環境中感覺還不錯,特此分享。

本文轉自淩激冰51CTO部落格,原文連結:http://blog.51cto.com/dreamfire/1399014,如需轉載請自行聯系原作者

繼續閱讀