一、节点管理
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、个节点间要相互解析地址
[root@www.example.com ~]# cat /etc/hosts 192.168.1.8 www.example.com 192.168.1.9 node1.example.com 192.168.1.10 node2.example.com [root@node1.example.com ~]# cat /etc/hosts 192.168.1.8 www.example.com 192.168.1.9 node1.example.com 192.168.1.10 node2.example.com [root@node2.example.com ~]# 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证书:
[root@www.example.com ~]# puppet master --no-daemonize -d -v [root@www.example.com ~]# ls /var/lib/puppet/ssl/ ca certs private public_keys certificate_requests crl.pem private_keys
Master配置文件设置:
[root@www.example.com ~]# puppet master --genconfig >> /etc/puppet/puppet.conf
启动服务查看监听的端口:
[root@www.example.com ~]# service puppetmaster start 启动 puppetmaster: [确定] [root@www.example.com ~]# ss -tnlp |grep puppet LISTEN 0 5 *:8140 *:* users:(("puppetmasterd",3856,5))
4、agent端安装puppet
[root@node1.example.com ~]# yum install -y facter-1.7.6-1.el6.x86_64.rpm puppet-2.7.26-1.el6.noarch.rpm [root@node2.example.com ~]# yum install -y facter-1.7.6-1.el6.x86_64.rpm puppet-2.7.26-1.el6.noarch.rpm
5、配置agent端
在puppet配置文件添加master端地址:
[root@node1.example.com ~]# vim /etc/puppet/puppet.conf server = www.example.com 生成证书: [root@node1.example.com ~]# 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端签署证书:
[root@www.example.com ~]# puppet cert list "node1.example.com" (57:62:E0:23:B9:02:BC:29:27:B2:6B:CF:B5:30:3B:0E) [root@www.example.com ~]# 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主机添加模版:
[root@www.example.com ~]# vim /etc/puppet/manifests/node1.example.com.pp node 'node1.example.com'{ include nginx::web } [root@www.example.com ~]# vim /etc/puppet/manifests/site.pp import "*.example.com.pp" [root@www.example.com ~]# service puppetmaster reload
6、agent端测试
[root@node1.example.com ~]# puppet agent --server www.example.com -d -v --test [root@node1.example.com ~]# rpm -q nginx nginx-1.0.15-12.el6.x86_64 [root@node1.example.com ~]# service nginx status nginx (pid 2412) 正在运行...
7、为agent端添加puppet服务
[root@node1.example.com ~]# service puppet start 启动 puppet: [确定] [root@node1.example.com ~]# chkconfig puppet on
8、按相同方法添加node2节点为agent
[root@www.example.com ~]# vim /etc/puppet/manifests/node2.example.com.pp node 'node2.example.com' { include nginx::web } [root@node2.example.com ~]# vim /etc/puppet/puppet.conf server = www.example.com [root@node2.example.com ~]# service puppet start 启动 puppet: [确定]
Master端添加node2节点的证书:
[root@www.example.com ~]# puppet cert list "node2.example.com" (AD:5D:18:5F:6F:D6:24:36:5A:97:E4:21:57:5E:8B:10) [root@www.example.com ~]# 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'
可以手动请求服务端:
[root@node2.example.com ~]# 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服务;
转载于:https://blog.51cto.com/cuchadanfan/1700305