Puppet 之 Master/agent配置與實現多環境
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模塊目錄機構如下
[root@master 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上環境準備完成
此時各個環境的目錄樹結構如下
[root@master ~]#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配置與實現多環境