一、節點管理
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'
}
如果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