天天看點

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子產品目錄機構如下

[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服務直接激活

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

└── testing

    │   └── 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服務,則實驗成功

繼續閱讀