零基礎學習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 -> /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 => </code><code>"root"</code><code>,</code>
<code>group => </code><code>"root"</code><code>,</code>
<code>mode => </code><code>0400</code><code>,</code>
<code>source => </code><code>"puppet:///modules/facts/facts.d/$hostname.txt"</code><code>, #檔案名稱通過節點變量hostname擷取</code>
<code>require => 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 => </code><code>"mkdir -p /etc/facter/facts.d "</code><code>,</code>
<code>path => [</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 => </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,如需轉載請自行聯系原作者