一、節點管理
1、什麼是節點
我們將Puppet的每個客戶端都稱爲節點( node) 。 每個節點件定義主機名時可以是個、 組 ( 正則或繼承) 。 所有的節點都需要在站點件( site.pp) 中進定義, 採import的式進引。 Puppet在進認證時都是以主機名( hostname) 進。 因此每臺服務器在上線使時都需要規範主機名。 節點的配置有多種, 以下爲採個或組主機名定義個節點的法。
1) 以主機名命名節點配置件。 此節點配置只包含該主機, 配置件只定義該主機需要應的類 及變量。 代碼如下:
$ vim /etc/puppet/manifests/nodes/test.domain.com.pp node 'test.domain.com' { #節點名, 即主機名 include nginx #加載ningx模塊 $vhost = 'linuxtone.org' #定義虛擬主機變量vhost }
同時需要在站點件( site.pp) 中進如下定義:
$ vim /etc/puppet/manifests/site.pp import "nodes/test.domain.com.pp"
2) 定義組功能相似的主機名配置件。 例如有3臺主機, 它們的配置都完全相同, 只是主機名 不同, 我們就可以通過代碼清單8-1進指定。
定義組主機名配置件 :
$ vim /etc/puppet/manifests/nodes/testgroups.pp node 'test.domain.com' { include nginx $vhost ='linuxtone.org' } node 'test1.domain.com' { include nginx $vhost = 'linuxtone.org' } node 'test2.domain.com' { include nginx $vhost = 'linuxtone.org' }
在Puppet 0.25.0及以後的版本中, 也可以使正則表達式來指定這些節點:
node /^test\d+\.domain\.com$/{ include nginx $vhost = 'linuxtone.org' }
同時需要在站點件( site.pp) 中進如下定義:
如果nodes錄下存在多個節點配置件時, 可以在站點件( site.pp) 中import所有節點件, 然 後採通配符匹配, 具體如下:
$ vim /etc/puppet/manifests/site.pp import "nodes/*.pp"
如果存在多個錄, 只需要將節點件存放在import的不同錄即可, 具體如下:
$ vim /etc/puppet/manifests/site.pp import "nodes/cnc/*.pp" import "nodes/ctc/*.pp"
同理, Puppet也持多級錄正則, 以上cnc、 ctc錄可以採“*”代替, 具體如下:
$ vim /etc/puppet/manifests/site.pp import "nodes/*/*.pp"
2、主機名命名規範
Puppet限制主機名可以包含字母、 數字、 句點、 下劃線、 破折號, 並且符合以下正則表達式:
/\A[a-z0-9._-]+\Z/
通常我們在對主機名命名時不會以“.”和“-”開頭, 因此主機名正則表達式只允許在主機名中出現以 上字符。 在第5章時筆者就已經建議主機名命名遵循以下規範:
role-isp-idc-ip.centos.domain.com
#名-運營商-機房名-機器IP.管理域名.com
例如:
web-cnc-bj-174.129.158.192.centos.linuxtone.org
在規範好主機名後, 就可以根據服務器的部署進合理的歸檔管理。 例如要在全國10個IDC、 跨3個運營商上線100臺服務器, 這些服務器擁有相同的, 因此可以按照規範進匹配命名。 在採節點組管理主機時可以利這特性的正則表達式進匹配, 從減少量節點管理件的編寫作。 這對於維護節點管理件提供了極的便。 利這特性我們也可以充分利節點繼承來處理組相同的主機。
規範主機名的好處有如下個:
管理便: 機器上線時通過MAC獲取主機名。
DNS管理便: 通過開源DNS管理主機名。
維護便: 主機的所有信息瞭然。
3、 節點繼承
節點繼承關係
如前面模擬的場景: 上線的服務存在相同的絡環境, 所有服務器都需要應同配置並定義同 變量, 類似於系統環境統初始化。 這種配置邏輯較簡單, 可以採定義個basenode默認節點的法進配置, 其他主機節點採"inherits"繼承basenode的配置信息, 具體如下:
node basenode { $my_puppet_server = "10.42.0.10" $my_local_network = "10.42.0.0/24" $my_syslog_server = "10.42.0.11" $my_ntp_server = "10.42.0.12" } node 'www.domain.com' inherits basenode { include general include httpd::php }
以上代碼中定義了basenode默認節點, 包含4個變量, 每個變量都賦予個值。 其中節 點"www.domain.com"採inherits繼承的式繼承basenode默認節點的所有屬性, 4個變量將直接應 該節點內, 同時www.domain.com節點包含( include) 兩個類: general和httpd: : php。
繼承變量覆蓋
如果另個節點ntp.domain.com。 所繼承的變量$my_ntp_server的值與默認basenode定義的值不 同, 可以直接在節點內進重新聲明, 這時節點內定義的值將覆蓋basenode定義的原值, 具體如下:
node 'ntp.domain.com' inherits basenode { $my_ntp_server = "0.pool.ntp.org" include general }
通過上代碼, 變量$my_ntp_server的值將由“10.42.0.12”變爲"0.pool.ntp.org"。
默認類與默認節點
定義默認節點配置與定義默認類baseclass的的相同: 爲所有節點應相同全局變量並進系統環 境初始化。 定義默認類general, 並將所有節點需要引的類通過include式添加到默認類general中。 我們也稱默認類general爲公共類。 general類的定義如下:
class general { include yum include hosts include puppet include iptables include sysctl include nrpe include ntp include syslog }
除了可以定義basenode, 我們還可以定義個default, 如果沒有明確定義個節點, 將默認按 default進操作。 default的定義存在Puppet每次都會編譯Catalog的問題, 也就是說不管所定義的default 有沒有在使, Puppet都會將它編譯到Catalog, 如果default沒有使就會導致Puppet性能下降。 如果沒 有特殊需求, 筆者建議採basenode或baseclass( general) 公共類的法實現。
定義個default節點, 包含兩個變量, 並加載個類, 具體代碼如下:
node default { $my_puppet_server = "10.42.0.10" $my_local_network = "10.42.0.0/24" include ntp }
節點繼承的判斷
如果有了相同功能的各個節點, 卻又想給這些節點添加不同的, 可以將相同部分的配置定義到 basenode, 節點都繼承basenode的信息, 然後分別增加不同功能的類引。 這的概念並不在Puppet中體現, 是抽象成種彙總的形式來表現。 定義節點www.domain.com與節點lb.domain.com繼承同個節點basenode, 幷包含( include) 不同的模塊, 具體如下:
node basenode { $my_puppet_server = "10.42.0.10" $my_ntp_server = "10.42.0.12" } node 'www.domain.com' inherits basenode { include role_webserver } node 'lb.domain.com' inherits basenode { include role_loadbalancer }
通過以上代碼可以看到兩個節點繼承了basenode的信息, 並且沒有做變量修改操作, 只是向www 添加了role_webserver類, 向lb添加了role_loadbalancer類。 在進類的配置時, 可以針對role_webserver和role_loadbalancer這兩個抽象出來的進聲明。
主機www.domain.com抽象的是webserver即include nginx。 主機lb.domain.com抽象的是 loadbalancer即include lvs。 其中$my_role分別代表兩個主機的抽象名。 具體實現代碼如下:
class role_webserver { $my_role = "webserver" include nginx } class role_loadbalancer { $my_role = "loadbalancer" include lvs }
在件引時, 可以針對這些抽象出來的應不同的配置件, 例如webserver和loadbalancer 應的防牆配置件不同, 可以在iptables錄創建iptables-webserver和iptables-loadbalancer兩個件。 使source屬性定義件來源時可採$my_role進判斷。 具體實現如下:
source => [ "puppet://$server/iptables/iptables-$hostname" , "puppet://$server/iptables/iptables-$my_role" , "puppet://$server/iptables/iptables" ],
或者在ERB模塊件中進判斷, 具體實現如下:
# Role specific settings <% if my_role=="webserver" %> -A INPUT -p tcp --dport 80 -j ACCEPT -A INPUT -p tcp --dport 443 -j ACCEPT <% end %>
4、節點管理法
當節點越來越多時, 就需要採取定既有效又適合的節點管理法。 通過前的介紹我們瞭解 到Puppet節點管理持多種配置法。 Puppet節點管理的法可以是單主機、 正則、 繼承等。 下將講解每個節點管理的配置法及其優劣性。
每個主機名獨
每個獨的主機名可以是個節點配置件。 例如, 若主機名是test.domain.com, 那麼節點配置 件可以是test.domain.com.pp。 在站點管理( site.pp) 中採通配符匹配錄下的所有節點件, 不考慮 節點的、 加載的類等其他相關信息。 配置法如下:
$ vim /etc/puppet/manifests/nodes/test.domain.com.pp node 'test.domain.com' { $vhost = 'linuxtone.org' include nginx } $vim /etc/puppet/manifests/nodes/test2.domain.com.pp node 'test2.domain.com' { $vhost = 'linuxtone.org' include apache } …
上述代碼實現了: 所有節點配置件以主機名命名, 並存放在nodes錄。
對單錄下的件數並沒有明確的限制, 但是當個錄下件數達到定數量級( 1000以 內, 通過"ls"命令查看錄下的件時系統響應就會變得緩慢) 後會影響服務器性能, 何況涉及節點管理呢? 或通過程序來維護個錄下的超過定規模的件也不是明智的選擇。 筆者建議採級錄的式來實現。 在節點的錄下建需要管理的的級錄, 具體如下:
$ cd /etc/puppet/manifests/nodes $ mkdir {web,db,lvs,cache,mq,custom}
此法適於通過程序成節點管理件, 根據應的不同來固定所包含( include) 模塊與 變量。 此法不適合編寫節點管理件, 節點件過多時容易引發變更故障。
採正則匹配
代碼清單8-1定義了組主機配置件, 通過觀察可以發現所有主機都包含( include) 相同的模 塊, 並定義了相同的變量。 這個時候我們可以通過正則表達式來減少代碼。 代碼清單8-1的主機組定義可以簡寫爲:
node /^test\d+\.domain\.com/ { #正則匹配多個主機名 include nginx #加載ningx模塊 $vhost = 'linuxtone.org' #定義虛擬主機變量vhost }
此法適合系統管理員完全瞭解服務器所有的及定義, 並且不會發變化的情況。 缺點就 是當正則匹配內的服務器發改變時操作煩瑣。
Puppet節點配置也持正則匹配的覆蓋, 例如前正則匹配中所有test開頭的主機。 如果test2想要單獨加載不同的類, 可以將此主機單獨聲明, Puppet將單獨聲明節點覆蓋之前的正則匹配, 實現代碼如下:
node 'test2.domain.com' { include mysql }
使外部節點分類器
當Puppet運在個節點時, Master會根據節點名查找該節點都聲明瞭哪些類。 將類映射到節點中 的最簡單法就是在配置清單中聲明。 例如, 定義個節點web.domain.com聲明nginx類:
node 'web.domain.com' { include nginx }
除這種法外, 還可以ENC( External Node Classifiers, 外部節點分類器) 來完成這個任務。 個外部節點分類器是任何可執程序, 它可以接受個節點的名稱, 並返回該節點的類列表。 例如, 這 可能是個簡單的Shell腳本, 也可能是對個可以決定如何映射類到節點的更復雜的程序或API的封裝。
外部分類器的主要途是使Puppet可以連接LDAP錄服務。 許多型組織都有LDAP基礎設施, 可以於設置Puppet, 使它可以從LDAP錄服務中獲取信息, 並且其他LDAP客戶也可以通過Puppet獲得由其管理的節點的信息。
ENC外部節點分類器也可以使Puppet DashBoard或Foreman通過Web界管理節點和類之間的關 系? 。
接下來演如何使ENC創建節點。
1) 使ENC需要配置Puppet Master的主配置件puppet.conf, 增加如下參數:
[master] external_nodes = /tmp/test_enc.py node_terminus = exec
2) "/tmp/test_enc.py"爲可執的腳本, Puppet在調它時傳遞節點的名稱作爲命令參數。 腳本 的內容如下:
#!/usr/bin/env python import sys import yaml node_name = sys.argv[1] classes = ["basenode"] # Output must be a YAML document print(yaml.dump({ "classes": classes, }))
注意 :如果沒有yaml模塊, 可以通過yum install PyYAML命令進安裝。
3) 爲該腳本添加可執權限, 代碼如下:
$ sudo chmod 755 /tmp/test_enc.py $sudo chmod 755/tmp/test_enc.py
4) 在站點件( site.pp) 中配置basenode類信息, 代碼如下:
$ sudo vim /etc/puppet/manifests/site.pp class basenode { notify {"I am a basenode!":} }
5) 在客戶端運Puppet, 代碼如下:
# puppet agent --server puppet.domain.com --test Info: Retrieving plugin Info: Caching catalog for agent.domain.com Info: Applying configuration version '1358346582' Notice: I am a basenode! Notice: /Stage[main]/Basenode/Notify[I am a basenode!]/message: defined 'message' as 'I am a basenode!' Notice: Finished catalog run in 0.12 seconds
作原理: Puppet調在puppet.conf中由參數external_nodes指定的腳本, 並傳遞節點的名稱作爲 命令參數。
要使ENC創建節點管理, 需要學習external_nodes腳本的寫法。 筆者總結了個常的節點管理 配置與ENC配置的寫法異同。
( 1) 加載模塊
加載模塊的異同見下。
nodes.pp: node default { include puppet include ntp } ENC: classes: puppet: ntp:
( 2) 參數定義
參數定義的異同見下。
nodes.pp: class { 'ntp': ntpserver => ['0.pool.ntp.org','1.pool.ntp.org'] } ENC: classes: ntp: ntpserver: - 0.pool.ntp.org - 1.pool.ntp.org
( 3) 變量與數組
變量與數組的異同見下。
nodes.pp: $var1 = 1 $var2 = "test" $var3 = ["a", 1] $var4 = { 'ma_ref1' => { 'cle1' => 'valeur1', 'cle2' => 'valeur2' } } ENC: parameters: var1: 1 var2: test var3: - a - 1 var4: ma_ref1: cle1: valeur1 cle2: valeur2
二、應用舉例
1、個節點間要相互解析地址
[[email protected] ~]# cat /etc/hosts 192.168.1.8 www.example.com 192.168.1.9 node1.example.com 192.168.1.10 node2.example.com [[email protected] ~]# cat /etc/hosts 192.168.1.8 www.example.com 192.168.1.9 node1.example.com 192.168.1.10 node2.example.com [[email protected] ~]# cat /etc/hosts 192.168.1.8 www.example.com 192.168.1.9 node1.example.com 192.168.1.10 node2.example.com
2、環境介紹
3、服務端初始化
生成ssl證書:
[[email protected] ~]# puppet master --no-daemonize -d -v [[email protected] ~]# ls /var/lib/puppet/ssl/ ca certs private public_keys certificate_requests crl.pem private_keys
Master配置文件設置:
[[email protected] ~]# puppet master --genconfig >> /etc/puppet/puppet.conf
啓動服務查看監聽的端口:
[[email protected] ~]# service puppetmaster start 啓動 puppetmaster: [確定] [[email protected] ~]# ss -tnlp |grep puppet LISTEN 0 5 *:8140 *:* users:(("puppetmasterd",3856,5))
4、agent端安裝puppet
[[email protected] ~]# yum install -y facter-1.7.6-1.el6.x86_64.rpm puppet-2.7.26-1.el6.noarch.rpm [[email protected] ~]# yum install -y facter-1.7.6-1.el6.x86_64.rpm puppet-2.7.26-1.el6.noarch.rpm
5、配置agent端
在puppet配置文件添加master端地址:
[[email protected] ~]# vim /etc/puppet/puppet.conf server = www.example.com 生成證書: [[email protected] ~]# puppet agent --server www.example.com -d -v --noop --test info: Creating a new SSL key for node1.example.com info: Caching certificate for ca info: Creating a new SSL certificate request for node1.example.com info: Certificate Request fingerprint (md5): 57:62:E0:23:B9:02:BC:29:27:B2:6B:CF:B5:30:3B:0E
Master端簽署證書:
[[email protected] ~]# puppet cert list "node1.example.com" (57:62:E0:23:B9:02:BC:29:27:B2:6B:CF:B5:30:3B:0E) [[email protected] ~]# puppet cert sign node1.example.com notice: Signed certificate request for node1.example.com notice: Removing file Puppet::SSL::CertificateRequest node1.example.com at '/var/lib/puppet/ssl/ca/requests/node1.example.com.pem'
Master端爲node1主機添加模版:
[[email protected] ~]# vim /etc/puppet/manifests/node1.example.com.pp node 'node1.example.com'{ include nginx::web } [[email protected] ~]# vim /etc/puppet/manifests/site.pp import "*.example.com.pp" [[email protected] ~]# service puppetmaster reload
6、agent端測試
[[email protected] ~]# puppet agent --server www.example.com -d -v --test [[email protected] ~]# rpm -q nginx nginx-1.0.15-12.el6.x86_64 [[email protected] ~]# service nginx status nginx (pid 2412) 正在運行...
7、爲agent端添加puppet服務
[[email protected] ~]# service puppet start 啓動 puppet: [確定] [[email protected] ~]# chkconfig puppet on
8、按相同方法添加node2節點爲agent
[[email protected] ~]# vim /etc/puppet/manifests/node2.example.com.pp node 'node2.example.com' { include nginx::web } [[email protected] ~]# vim /etc/puppet/puppet.conf server = www.example.com [[email protected] ~]# service puppet start 啓動 puppet: [確定]
Master端添加node2節點的證書:
[[email protected] ~]# puppet cert list "node2.example.com" (AD:5D:18:5F:6F:D6:24:36:5A:97:E4:21:57:5E:8B:10) [[email protected] ~]# puppet cert sign node2.example.com notice: Signed certificate request for node2.example.com notice: Removing file Puppet::SSL::CertificateRequest node2.example.com at '/var/lib/puppet/ssl/ca/requests/node2.example.com.pem'
可以手動請求服務端:
[[email protected] ~]# puppet agent --server www.example.com -d -v --test
9、步驟總結
puppet master:
安裝puppet-master
# puppet master --genconfig >> /etc/puppet/puppet.conf
啓動puppetmaster服務
puppet agent:
安裝puppet
編輯配置文件/etc/puppet/puppet.conf,在[agent]添加 server=puppetmaster.magedu.com
啓動puppet服務
master簽署證書:
# puppet cert list
# puppet cert sign NODE_NAME
# puppet cert sign --all //簽署所有證書
注意:master端的任何修改,都要重新裝載puppetmaster服務;