Puppet 之 Master/agent配置与实现多环境
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Puppet 之 Master/agent配置与实现多环境相关的知识,希望对你有一定的参考价值。
1 概述Puppet通过master/agent模型的方式,实现环境中的agent能主动同步master定义的状态。实现配置的统一。同时,我个人认为多环境是master/agent模型的扩展,因此放到到同一篇文章中介绍。
2 Master/agent模型的
2.1 概念介绍
默认agent端会每30分钟请求一次master以便来获取自己的catalog。master端这时候会根据agent端所持有的证书验证请求者的身份,并根据证书内嵌的使用者名称和请求者自己的名称进行解析验证,如果验证通过master端就根据节点定义找到属于请求者agent端的配置,并在本地编译成catalog,将编译完成的结果发送给agent端。
master端的一个固定位置放置模块。master模块是为了实现共享的,但是哪些主机能调用这些资源是定义在manifests的site.pp里。在puppet中,只要主机名有规律可寻,可以使用通配符或者正则表达式的模式来定义在mainfist里。所以可以用于定义匹配一台或者多台主机。
通过https的双向认证后通信的,puppet自己会维护CA,puppet有内建的私有CA。agent在第一次连接master的时候,会生成一个请求证书,发给master,这个证书需要人为审核是否信任的agent后签发完成证书的认证,也可以开启自动签发证书的功能,但是,出于安全考虑,不建议这么操作。
master和agent的相互识别是通过主机名来实现的,如果站点规模大,靠hosts文件解析不合适,所以就需要通过dns来解析主机名,这个dns仅需要为内网服务器提供解析,即需要建立私网内的dns。如果是双机房,那么机房间是通过专线来通信,一般可以用一个puppet server管理多机房里的主机。私有dns也可以仅在一个机房里创建。
master/agent:agent每隔30分钟到master端请求与自己相关的catalog。站点清单定义如下:
master: site manifest node 'node_name' { ...puppet code... } node_name
程序包下载路径:
https://yum.puppetlabs.com/
官方文档:
https://docs.puppet.com/puppet/3/reference/
内建函数:
https://docs.puppet.com/puppet/3/reference/function.html
配置参数列表:
https://docs.puppet.com/puppet/3/reference/configuration.html
部署master:
安装程序包:facter, puppet, puppet-server
初始化master:
puppet master --no-daemonize --verbose
生成一个完整的配置参数列表:
puppet master --genconfig #查看有效配置,有分段,可以覆盖配置文件,一般不用这个操作
puppet agent --genconfig
打印基于默认配置生效的各配置参数列表:
puppet config <action> [--section SECTION_NAME]
puppet config print #打印的是默认配置,这里打印出来的配置是没有分段的
基于命令行设定某参数的值:
puppet config set
格式:puppet config set [--section SECTION_NAME] [setting_name] [setting_value]
例子
puppet config set --section main master master.sunny.com
master端管理证书签署:
puppet cert <action> [--all|-a] [<host>]
action:
list
sign
revoke
clean:吊销指定的客户端的证书,并删除与其相关的所有文件;
证书可以自动签署,但是出于安全考虑,一般不开启该功能
注意,某agent证书手工吊销后重新生成一次,
在master端:执行如下命令吊销和清除证书
puppet cert revoke NODE_NAME puppet cert clean NODE_NAME
在agent端:清除客户端的/var/lib/puppet/ssl下的内容
执行
rm -rf /var/lib/puppet/ssl/*
客户端重启agent服务即可
systemctl restart puppetagent
在服务器查看到证书请求,然后签署即可完成证书的重新签署
如果要实现服务器端的自动签发证书,服务器端操作如下,
两种方法
方法一
在/etc/puppet下新加配置文件autosign.conf,将要自动签发的域名写入该文件
vim /etc/puppet/autosign.conf *.sunny.com
方法二
在配置文件的main端添加如下内容,但是会导致所有的主机都会被签发,不建议。
vim /etc/puppet/puppet.conf autosign = true
自动签发证书功能不建议打开,建议在第一次部署环境时使用,其他情况,建议关闭该功能,用手动签发证书操作。
在agent 端重新生成,重启服务即可
主机故障后,重新生成的主机系统,不需要做任何清理,只需要重启agent.
如果因私钥变更了,那么建议先清理/var/lib/puppet/ssl目录下的文件,然后在agent重启服务,服务器端再次签署证书,重新生成证书
站点清单的定义:
主机名定义:
主机名(主机角色)#-机架-机房-运营商-区域.域名
www1-rack1-yz-unicom-bj.magedu.com
/etc/puppet/manifests/site.pp模板
node 'base' { include ntp #假设有个类叫ntp } node 'HOSTNAME' { ...puppet code... } node /PATTERN/ { ...puppet code... } node /node[0-9]+\.magedu\.com/ #正则表达式,表示node节点后跟上1位以上的数字,都可以被匹配 #节点定义的继承: node NODE inherits PAR_NODE_DEF { ...puppet code... } nodes/
清单配置信息可模块化组织:
databases.d/
tomcatservers.d/
nodes.d/:可通过多个pp文件分别定义各类站点的清单;而后统一导入site.pp,方法如下:
site.pp文件使用中如下配置:
import 'nodes/*.pp'
主机节点可以跟类一样,可以继承,假如节点太多,写在一个文件里,管理也不方便,因此需要通过模块化管理。
模块化例子如下
在路径/etc/puppet/manifests下创建多个以.d结束的目录,用来存放模块化的配置文件
mkdir /etc/puppet/manifests/websvrs.d mkdir /etc/puppet/manifests/dbsvrs.d
然后在这些目录下模块化编写以.pp为后缀的文件
加载模块化,用import导入
node 'agent72.sunny.com' { include redis::master class{'tomcat': ajp_port => '8090', http_port => '8088', } } node 'agent75.sunny.com'{ $redismasterip = '172.18.50.72' $redismasterport = '6379' class{'redis::slave': masterip => "$redismasterip", masterport => "$redismasterport" } include tomcat } import 'websvrs.d/*.pp' import 'dbsvrs.d/*.pp'
2.2 例子
环境准备
服务器端安装puppet-server来实现server的角色
yum -y install puppet-server
安装server包后,对应目录/etc/puppet多了两个文件:fileserver.conf 和 manifests
在服务器端安装完成后,启动服务即可,不需要修改配置,默认监听端口是8140
systemctl restart puppetmaster.service
服务启动后,证书签署的目录 /var/lib/puppet/ssl会生成多个文件,这些文件是证书的相关文件
查看
ls /var/lib/puppet/ssl
该目录下的文件,即使删除了,下次重启服务的时候就会重新生成,但是,注意,不要随意删除该目录下的文件,否则删除重启服务后之前签发的证书失效
如果要查看启动,清掉/var/lib/puppet/ssl文件后,执行如下命令可以看到 证书签发的相关过程,但是以下命令是非守护进程的方式启动,一般不这么启动,直接用systemctl启动服务即可
puppet master --no-daemonize -v -d --server master.sunny.com
客户端安装puppet包,充当agent端
yum -y install puppet
agent端要指定server,编辑配置文件,在main段加入如下的配置
server = master.sunny.com
第一次启动
puppet agent --no-daemonize -v -d --noop --test
此时不能成功启动,但是会生成一个证书请求文件发往服务器端,要等待服务器端签发证书
服务器端需要颁发证书
先查看
puppet cert list
然后颁发
puppet cert sign agent72.sunny.com
服务器端颁发证书成功后,客户端再次启动,就可以成功启动
puppet agent --no-daemonize -v -d --test
注意,客户端可以执行如下命令进行启动
systemctl restart puppetagent.service
准备,这里仅仅是测试,没有搭建dns,编辑所有的主机的hosts,如下
172.18.50.73 master.sunny.com 172.18.50.72 agent72.sunny.com 172.18.50.75 agent75.sunny.com 172.18.50.63 agent63.sunny.com 172.18.50.65 agent65.sunny.com
这里利用ansible工具将如上的语句重定向到每台机器的/etc/hosts文件里。将以上语句写入文件/root/host1里
执行如下命令
ansible all -m copy -a "dest=/root/host1 src=/root/host1" ansible all -m shell -a "cat /root/host1 >> /etc/hosts"
完成所有hosts文件增加这5台服务器的解析
例1 配置redis主从服务器
agent72为redis 主服务器
agent75位redis从服务器
服务器端要有文件/etc/puppet/manifests/site.pp,声明对应主机使用的类
主节点编辑如下
vim /etc/puppet/manifests/site.pp node 'agent72.sunny.com' { include redis::master } node 'agent75.sunny.com'{ $redismasterip = '172.18.50.72' $redismasterport = '6379' class {'redis::slave': masterip => "$redismasterip", masterport => "$redismasterport" } }
从服务器上准备redis的模块,方法参加上文的例子:开发redis模块
注意,准备的文件需要有其他人读的权限,否则客户端来获取配置文件的时候会报错,没有权限
chmod 644 /etc/puppet/modules/redis/files/redis-master.conf chmod 644 /etc/puppet/modules/redis/templates/redis-slave.conf.erb
redis模块目录机构如下
[[email protected] modules]#tree
.
└── redis
├── files
│ └── redis-master.conf
├── lib
├── manifests
│ ├── init.pp
│ ├── master.pp
│ └── slave.pp
├── spec
├── templates
│ └── redis-slave.conf.erb
└── tests
模块准备完成后,master上配置就完成了
agent服务器启动
systemctl restart puppetagent.service
启动后,默认重启后会自动跟主服务器对比配置,如果和主服务器上定义的状态不一致,就会根据主服务器上site.pp的定义来配置本机。之后默认是每隔30分钟自动同步一次主服务器上的配置
注意第一次启动是,默认agent签署证书需要管理员手动在服务器端签发
测试
重启agent72和agent75两台服务器,如果redis都成功被安装,且实现了主从,则实验完成
如果重启不成功,建议通过命令puppet agent --no-daemonize -v --noop查看启动服务过程的信息,可以加-d查看更加详细的过程,方便排错
例2 安装tomcat主机
主服务器上
先开发一个模块
1 创建目录
mkdir -pv /etc/puppet/modules/tomcat/{manifests,files,templates}
2 准备配置文件
获取配置文件进行修改,可以找一台机器安装tomcat后生成相关配置再拷贝到对应目录下
cp /etc/tomcat/server.xml /etc/puppet/modules/tomcat/templates/server.xml.erb cp /etc/tomcat/tomcat-users.xml /etc/puppet/modules/tomcat/files/tomcat-users.xml chmod 644 /etc/puppet/modules/tomcat/templates/server.xml.erb chmod 644 /etc/puppet/modules/tomcat/files/tomcat-users.xml
这里的配置模板主要修改了如下的内容
vim /etc/puppet/modules/tomcat/templates/server.xml.erb <Connector port="<%= @http_port %>" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" /> <Connector port="<%= @ajp_port %>" protocol="AJP/1.3" redirectPort="8443" />
vim /etc/puppet/modules/tomcat/files/tomcat-users.xml <role rolename="admin-gui"/> <role rolename="manager-gui"/> <user username="tomcat" password="Pass1234" roles="manager-gui,admin-gui"/>
3.定义类,安装相关包和拷贝文件
vim /etc/puppet/modules/tomcat/mainfests/init.pp class tomcat($http_port='8080',$ajp_port='8009'){ package{['tomcat','tomcat-webapps','tomcat-admin-webapps', 'tomcat-docs-webapp']: ensure => latest, } -> file{'/etc/tomcat/server.xml': ensure => file, content => template('tomcat/server.xml.erb'), owner => 'root', group => 'tomcat', mode => '0644', } file{'/etc/tomcat/tomcat-users.xml': ensure => file, source => 'puppet:///modules/tomcat/tomcat-users.xml', owner => 'root', group => 'tomcat', mode => '0640', require => Package['tomcat'], } service{'tomcat': ensure => running, enable => true, subscribe => [File['/etc/tomcat/server.xml'],File['/etc/tomcat/tomcat-users.xml']], } }
#在site.pp里定义的变量优先级比init.pp里高
vim /etc/puppet/manifests/site.pp node 'agent72.sunny.com' { class{'tomcat': ajp_port => '8090', http_port => '8088', } } node 'agent75.sunny.com'{ include tomcat }
重启服务
master端
systemctl restart puppetmaster
agent端
systemctl restart puppetagent
此时主服务器已经配置完成
从服务器最长30分钟后同步,这里通过重启agent服务直接激活
如果重启不成功,建议通过命令puppet agent --no-daemonize -v --noop查看启动服务过程的信息,可以加-d查看更加详细的过程,方便排错
3 多环境配置
3.1 概念介绍
模块指明了要复用的代码,站点清单指明了哪些主机要用对应的代码。puppet默认是production(生产环境),要使用多环境,不一样的环境具有不一样的站点清单。
环境变量environmentpath默认是不存在的,查看变量命令如下
puppet config print environmentpath
puppet 3.4 之前的版本配置多环境的方法:
各环境配置:以下每一个子目录表示一种环境
/etc/puppet/environments/{production,development,testing}
master支持多环境:puppet.conf
[master] # modulepath= # manifest= environments = production, development, testing [production] modulepath=/etc/puppet/environments/production/modules/ manifest=/etc/puppet/environments/production/manifests/site.pp [development] modulepath=/etc/puppet/environments/development/modules/ manifest=/etc/puppet/environments/development/manifests/site.pp [testing] modulepath=/etc/puppet/environments/testing/modules/ manifest=/etc/puppet/environments/testing/manifests/site.pp
puppet 3.6(包含3.6)之后的版本配置多环境的方法:
master支持多环境:
(1) 配置文件puppet.conf
[master] environmentpath = $confdir/environments
$confdir一般指/etc/puppet这个目录
(2) 在多环境配置目录下为每个环境准备一个子目录
ENVIRONMENT_NAME/
manifests/
site.pp
modules/
额外配置文件:
文件系统:fileserver.conf,默认配置可用,不需要调整
认证(URL):auth.conf:在该文件中,method为find表示读请求,method为save为其他请求,默认没有指定任何操作,则默认表示拒绝所有,如最后的path /
查看master端日志
master端和agent的通信日志如下文件
/var/log/puppet/masterhttp.log
查看每台主机对应在服务器端操作的报告,见如下路径的文档。
/var/lib/puppet/reports/
该目录下会生成以主机名为目录的文件,在对应主机下一yaml格式记录各个文件
puppet kick:紧急修复的时候会用到这个功能
默认agent是周期性来获取配置的,那么可以考虑用服务器端推送请求来通知agent的方式,告知agent,使得agent可以及时同步新的配置文件
master端执行如下格式:
puppet kick [--host <HOST>] [--all]
agent端要监听在某一套接字上才能实现kick功能,默认端口是8139
3.2 例子
例1 不同环境下安装memcached
准备不同环境(testing,development,production)的目录
mkdir -pv /etc/puppet/environments/{development,production,testing}/manifests mkdir -pv /etc/puppet/environments/{development,production,testing}/modules/memcached/{manifests,files,templates}
服务器端配置如下
#新增一个配置端master
vim /etc/puppet/puppet.conf [master] environmentpath = $confdir/environments
查看特定段变量,如master段,如section端的变量,否则默认没有section变量,查看的是main段的配置
puppet config print environmentpath --section master
准备配置模板文件
注意,配置文件中,不同环境下,内存大小不一样,内存大小的值通过参数来传递
准备redis模块
#testing环境
vim /etc/puppet/environments/testing/modules/memcached/manifests/init.pp class memcached($maxmemory='64'){ package{'memcached': ensure => latest, provider => yum, } file{'/etc/sysconfig/memcached': ensure => file, content => template('memcached/memcached.erb'), owner => 'root', group => 'root', mode => '0644', } service{'memcached': ensure => running, enable => true, } Package['memcached'] -> File['/etc/sysconfig/memcached'] ~>Service['memcached'] }
#development环境
vim /etc/puppet/environments/development/modules/memcached/manifests/init.pp class memcached($maxmemory='128'){ package{'memcached': ensure => latest, provider => yum, } file{'/etc/sysconfig/memcached': ensure => file, content => template('memcached/memcached.erb'), owner => 'root', group => 'root', mode => '0644', } service{'memcached': ensure => running, enable => true, } Package['memcached'] -> File['/etc/sysconfig/memcached'] ~>Service['memcached'] }
production环境
vim /etc/puppet/environments/production/modules/memcached/manifests/init.pp class memcached($maxmemory='256'){ package{'memcached': ensure => latest, provider => yum, } file{'/etc/sysconfig/memcached': ensure => file, content => template('memcached/memcached.erb'), owner => 'root', group => 'root', mode => '0644', } service{'memcached': ensure => running, enable => true, } Package['memcached'] -> File['/etc/sysconfig/memcached'] ~>Service['memcached'] }
准备memcached配置模板文件
vim /etc/puppet/environments/production/modules/memcached/templates/memcached.erb PORT="11211" USER="memcached" MAXCONN="1024" CACHESIZE="<%= @maxmemory %>" OPTIONS=""
把该模板复制到其他两个环境下
在不同环境下定义site.pp
vim /etc/puppet/environments/production/manifests/site.pp node 'agent72.sunny.com'{ class {'memcached': maxmemory => '512', } }
vim /etc/puppet/environments/testing/manifests/site.pp node 'agent72.sunny.com'{ include memcached }
vim /etc/puppet/environments/production/manifests/site.pp node 'agent72.sunny.com'{ include memcached }
到这里,master上环境准备完成
此时各个环境的目录树结构如下
[[email protected] ~]#tree /etc/puppet/environments/
/etc/puppet/environments/
├── common
├── development
│ ├── manifests
│ │ └── site.pp
│ └── modules
│ └── memcached
│ ├── files
│ ├── manifests
│ │ └── init.pp
│ └── templates
│ └── memcached.erb
├── production
│ ├── manifests
│ │ └── site.pp
│ └── modules
│ └── memcached
│ ├── files
│ ├── manifests
│ │ └── init.pp
│ └── templates
│ └── memcached.erb
└── testing
├── manifests
│ └── site.pp
└── modules
└── memcached
├── files
├── manifests
│ └── init.pp
└── templates
└── memcached.erb
22 directories, 9 files
该实验建议在其他目录先准备模块,完成后,再将准备好的模块放在到对应环境下的模块里
cp -r /root/memcached /etc/puppet/environments/testing/modules cp -r /root/memcached /etc/puppet/environments/production/modules cp -r /root/memcached /etc/puppet/environments/development/modules
测试
服务器端重启服务
systemctl restart puppetmaster
agent72端
查看当前环境
puppet config print environment
每一站点拥有所有的环境拥有不同的站点资源,手动指定不同的环境进行安装,安装后的memcached的内存大小不一样
#开发
puppet agent --no-daemonize -v --environment=development
#生产环境
puppet agent --no-daemonize -v --environment=production
#测试环境
puppet agent --no-daemonize -v --environment=testing
在实际环境中,每台主机对应的环境是确定的,可以将环境配置在配置文件里
agent端:
[agent]
environment = { production|development | testing }
例子,在配置文件agent里指定当前机器为testing环境
vim /etc/puppet/puppet.conf [agent] environment = testing
配置更改完成后,重启agent服务,会自动匹配master定义的状态
systemctl restart puppetagent
到这里该例子完成
例2 kick 命令使用
agent端修改配置文件
vim /etc/puppet/puppet.conf puppet.conf [agent] listen = true vim /etc/puppet/auth.conf path /run method save auth any allow master.sunny.com #这里指明master的服务器地址
重启服务,agent会监听8139端口
systemctl restart puppetagent
服务器端配置
定义模块,安装nginx并启动nginx服务
mkdir -pv /etc/puppet/environments/testing/modules/nginx/{manifests,files,templates} vim /etc/puppet/environments/testing/modules/nginx/manifests/init.pp class nginx { package{'nginx': ensure => latest, } -> service{'nginx': ensure => running, } }
vim /etc/puppet/environments/testing/manifests/site.pp node 'agent72.sunny.com'{ include nginx }
到这里,新的模块已经添加完成
测试
服务器端执行
puppet kick agent72.sunny.com
在agent72.sunny.com上验证,如果已经成功安装nginx服务包,且能够启动nginx服务,则实验成功
以上是关于Puppet 之 Master/agent配置与实现多环境的主要内容,如果未能解决你的问题,请参考以下文章
Puppet-Master/Agent模式实现redis主从