puppet 是一個配置管理工具, 典型的, puppet 是一個 C/S 結構, 固然,這裏的 C 能夠有不少,因html
此,也能夠說是一個星型結構. 全部的 puppet 客戶端同一個服務器端的 puppet 通信. 每一個node
puppet 客戶端每半小時(能夠設置)鏈接一次服務器端, 下載最新的配置文件,而且嚴格按照配mysql
置文件來配置服務器. 配置完成之後,puppet 客戶端能夠反饋給服務器端一個消息. 若是出錯,linux
也會給服務器端反饋一個消息. 下圖展現了一個典型的 puppet 配置的數據流動狀況.nginx
穩定性puppet 與其餘手工操做工具備一個最大的區別就是 puppet 的配置具備穩定性,所以你能夠屢次執行 puppet, 一旦你更新了你的配置文件,puppet 就會根據配置文件來更改你的機配置,一般每 30 分鐘檢查一次. puppet 會讓你的系統狀態同配置文件所要求的狀態保持一致. 好比你配置文件裏面要求 ssh 服務必須開啓. 假如不當心 ssh 服務被關閉了,那麼下一次執行 puppet 的c++
時候,puppet 會發現這個異常,而後會開啓 ssh 服務. 以使系統狀態和配置文件保持一web
致.puppet 就象一個魔術師,會讓你的混亂的系統收斂到 puppet 配置文件所想要的狀態.sql
可使用 puppet 管理服務器的整個生命週期,從初始化到退役.不一樣於傳統的例如 sun 的shell
Jumpstart 或者 redhat 的 Kickstart, puppet 能夠終年讓服務器保持最新狀態.只要一開始就正數據庫
確的配置他們,而後不再用去管他們.一般 puppet 用戶只須要給機器安裝好 puppet 並讓他們
運行,而後剩餘的工做都由 puppet 來完成.
puppet 的細節和原理
1. 客戶端 Puppetd 向 Master 發起認證請求,或使用帶簽名的證書。
2. Master 告訴 Client 你是合法的。
3. 客戶端 Puppetd 調用 Facter,Facter 探測出主機的一些變量,例如主機名、內存大小、IP 地址
等。Puppetd 將這些信息經過 SSL 鏈接發送到服務器端。
4. 服務器端的 Puppet Master 檢測客戶端的主機名,而後找到 manifest 對應的 node 配置,並對該部份內容進行解析。Facter 送過來的信息能夠做爲變量處 理,node 牽涉到的代碼才解析,其餘沒牽涉的代碼不解析。解析分爲幾個階段,首先是語法檢查,若是語法錯誤就報錯;若是語法沒錯,就繼續解析,解析的結 果生成一箇中間的「僞代碼」(catelog),而後把僞代碼發給客戶端。
5. 客戶端接收到「僞代碼」,而且執行。
6. 服務器端把客戶端的執行結果寫入日誌,併發送給報告系統。
詳細配置過程:
系統環境:rhel6.5 selinux and iptables disabled
sever: 172.25.254.1 vm1.example.com puppet master
client:172.25.254.2 vm2.example.com puppet agent
client:172.25.254.3 vm3.example.com puppet agent
重要:server 與全部 client 之間須要解析,以及時間同步,否則會驗證失敗。
server 端:
puppetmaster的安裝:
a.若是主機能上網
# yum localinstall -y rubygems-1.3.7-1.el6.noarch.rpm
把如下條目加入 yum 倉庫:
[puppet]
name=puppet
baseurl=http://yum.puppetlabs.com/el/6Server/products/x86_64/
gpgcheck=0
[ruby]
name=ruby
baseurl=http://yum.puppetlabs.com/el/6Server/dependencies/x86_64/
gpgcheck=0
# yum install puppet-server -y
b.若是主機不能上網
需呀下載如下安裝包:
[root@vm1 update]# ls
facter-2.4.4-1.el6.x86_64.rpm ruby-augeas-0.4.1-3.el6.x86_64.rpm
hiera-1.3.4-1.el6.noarch.rpm rubygem-json-1.5.5-3.el6.x86_64.rpm
puppet-3.8.1-1.el6.noarch.rpm rubygems-1.3.7-5.el6.noarch.rpm
puppet-dashboard-1.2.23-1.el6.noarch.rpm ruby-shadow-2.2.0-2.el6.x86_64.rpm
puppet-server-3.8.1-1.el6.noarch.rpm
[root@vm1 update]# yum localinstall -y puppet-server-3.8.1-1.el6.noarch.rpm puppet-3.8.1-1.el6.noarch.rpm facter-2.4.4-1.el6.x86_64.rpm hiera-1.3.4-1.el6.noarch.rpm rubygem-json-1.5.5-3.el6.x86_64.rpm ruby*
/etc/puppet 配置目錄:
組織結構以下:
|-- puppet.conf #主配置配置文件,詳細內容可執行 puppet --genconfig
|-- fileserver.conf #文件服務器配置文件
|-- auth.conf #認證配置文件
|-- autosign.conf #自動驗證配置文件
|-- tagmail.conf #郵件配置文件(將錯誤信息發送)
|-- manifests #文件存儲目錄(puppet 會先讀取該目錄的.PP 文件<site.pp>)
|--nodes
| puppetclient.pp
|-- site.pp #定義 puppet 相關的變量和默認配置。
|-- modules.pp #加載 class 類模塊文件(include syslog)
|-- modules #定義模塊
|-- syslog #以 syslog 爲例
|-- file
|-- manifests
|-- init.pp #class 類配置
|-- templates #模塊配置目錄
|-- syslog.erb #erb 模板
puppet 的第一個執行的代碼是在/etc/puppet/manifest/site.pp,所以這個文件必須存在,而
且其餘的代碼也要經過該文件來調用。
[root@vm1 puppet]# touch /etc/puppet/manifest/site.pp #沒有此文件 puppet master 沒法啓動,配置後面再定義
[root@vm1 puppet]# service puppetmaster start #啓動 puppet master
[root@vm1 puppet]# netstat -antlp |grep ruby
tcp 0 0 0.0.0.0:8140 0.0.0.0:* LISTEN 1863/ruby
client 端:
只要安裝 puppet 便可,安裝方法同 server 端:
a.
# yum install puppet -y
b.
[root@vm2 ~]# yum localinstall -y puppet-3.8.1-1.el6.noarch.rpm puppet-3.8.1-1.el6.noarch.rpm facter-2.4.4-1.el6.x86_64.rpm hiera-1.3.4-1.el6.noarch.rpm rubygem-json-1.5.5-3.el6.x86_64.rpm ruby*
puppet 客戶端鏈接到 puppet master:
[root@vm2 ~]# puppet agent --server vm1.example.com --no-daemonize --verbose
Info: Creating a new SSL key for vm2.example.com
Info: Caching certificate for ca
Info: Creating a new SSL certificate request for vm2.example.com
Info: Certificate Request fingerprint (SHA256):
5C:72:77:D8:27:DF:5A:DF:34:EF:25:97:5A:CF:25:29:9F:58:83:A2:61:57:D9:20:7B:1E:C0:36:75:9D:
FB:FC
client 向 master 發出證書驗證請求,而後等待 master 簽名並返回證書。
參數--server 指定了須要鏈接的 puppet master 的名字或是地址,默認鏈接名爲「puppet」的主機
如要修改默認鏈接主機能夠修改/etc/sysconfig/puppet 文件中的 PUPPET_SERVER=puppet 選項
參數--no-daemonize 是 puppet 客戶端運行在前臺
參數--verbose 使客戶端輸出詳細的日誌
在 master 端:
[root@vm1 puppet]# puppet cert list #顯示全部等待簽名的證書
"vm2.example.com" (SHA256)
CD:BD:13:D0:B8:46:07:F2:B7:AE:00:C4:E6:E9:E1:A4:92:F6:A4:F1:AB:F7:FF:8D:BE:B0:B7:90:E1:
7B:A8:C0
[root@vm1 puppet]# puppet cert sign vm2.example.com #簽名證書
Signed certificate request for vm2.example.com
Removing file Puppet::SSL::CertificateRequest vm2.example.com at
'/var/lib/puppet/ssl/ca/requests/vm2.example.com.pem'
如要同時簽名全部證書,執行如下命令:
[root@vm1 puppet]# puppet cert sign --all
[root@vm1 puppet]# puppet cert clean vm2.example.com #刪除簽名證書
在對證書籤名後的兩分鐘後,在 agent 端上能夠看到以下輸出:
Info: Caching certificate for vm2.example.com
Starting Puppet client version 3.0.0
Info: Caching certificate_revocation_list for ca
Info: Retrieving plugin
Info: Caching catalog for vm2.example.com
Info: Applying configuration version '1349536603'
Finished catalog run in 0.13 seconds
自動驗證:
在 server 端, 編輯 puppet.conf 文件:
[root@vm1 puppet]# vim /etc/puppet/puppet.conf
[main]
autosign = true
#容許全部客戶端的認證
/etc/puppet 目錄下建立 autosign.conf 文件,內容以下:
# vim /etc/puppet/autosign.conf
*.example.com #表示容許全部 example.com 域的主機
[root@vm1 puppet]# service puppetmaster reload
在 client 端只需執行:
# puppet agent 或 # server puppet start
在實際中有時會修改 client 端的主機名,這樣就須要從新生成證書:
1)在 server 端執行:puppet cert --clean vm2.example.com #你要刪除的原 client 端主機名
2)在 client 端執行:rm -fr /var/lib/puppet/ssl/*
3)puppet agent --server vm1.example.com --no-daemonize --verbose
puppet 資源定義
如下資源均定義在/etc/puppet/manifest/site.pp 文件中,在沒有指定節點的狀況下,對全部
已經通過驗證的 client 都生效。
1. 建立文件
[root@vm1 puppet]# vim /etc/puppet/fileserver.conf 加入如下行:
[files]
path /etc/puppet/files
allow *.example.com
[root@vm1 puppet]# service puppetmaster reload #重啓服務
[root@vm1 manifests]# vim site.pp
file { "/mnt/testfile": #在/mnt下建立testfile文件
source => "puppet:///files/passwd" #來源:server端/etc/puppet/files/passwd
source => "/etc/passwd" #來源:client端/etc/passwd
}
2. 軟件包定義
package { "httpd": ensure => present; #安裝httpd
"vsftpd": ensure => absent #卸載vsftpd
}
3. 服務定義
service { "httpd": ensure => running; #啓動httpd
"vsftpd": ensure => stopped #關閉vsftpd
}
4. 組定義
group { "wonder": gid => 600 }
5. 用戶定義
user { "wonder": #建立wonder用戶
uid => 600,
gid => 600,
home => "/home/wonder",
shell => "/bin/bash",
password => westos
}
file { "/home/wonder":
owner => wonder,
group => wonder,
mode => 700,
ensure => directory
}
file { "/home/wonder/.bash_profile":
source => "/etc/skel/.bash_profile",
owner => wonder,
group => wonder
}
file { "/home/wonder/.bashrc":
source => "/etc/skel/.bashrc",
owner => wonder,
group => wonder
}
user { "test": uid => 900, #建立test用戶
home => "/home/test",
shell => "/bin/bash",
provider => useradd,
managehome => true,
ensure => present
}
exec { "echo westos | passwd --stdin test":
path => "/usr/bin:/usr/sbin:/bin",
onlyif => "id test"
}
6. 文件系統掛載
mount { "/mnt": #172.25.254.252主機須要開啓nfs服務
device => "172.25.254.252:/var/ftp/pub",
fstype => "nfs",
options => "defaults",
ensure => absent
}
自動掛載文件系統,並同步 fstab 文件,若是須要卸載,改成 absent
7. crontab 任務
cron { echo: #2點到4點每隔10分鐘,把時間導入/tmp/echo
command => "/bin/echo `/bin/date` >> /tmp/echo",
user => root,
hour => ['2-4'],
minute => '*/10'
}
# 任務會在 client 上/var/spool/cron 目錄中生成
不一樣節點的定義:
1. 在 puppetmaster 上編輯 site.pp
[root@vm1 puppet]# vim /etc/puppet/manifests/site.pp #寫上
import "nodes/*.pp"
2. 創建節點文件
[root@vm1 puppet]#vim /etc/puppet/manifests/nodes/vm2.pp
node 'vm2' {
package { "httpd": ensure=>present}
}
[root@vm1 puppet]#vim /etc/puppet/manifests/nodes/vm3.pp
node 'vm3' {
user { "test": uid => 900,
home => "/home/test",
shell => "/bin/bash",
provider => useradd,
managehome => true,
ensure => present
}
exec { "echo westos | passwd --stdin test":
path => "/usr/bin:/usr/sbin:/bin",
onlyif => "id test"
}
}
編寫模塊:
[root@vm1 puppet]# mkdir -p /etc/puppet/modules/httpd/{files,manifests,templates}
[root@vm1 puppet]# cd /etc/puppet/modules/httpd/manifests
[root@vm1 manifests]# vim install.pp
class httpd::install {
package { "httpd":
ensure => present
}
}
[root@vm1 manifests]# vim config.pp
class httpd::config {
file { "/etc/httpd/conf/httpd.conf":
ensure => present,
source => "puppet:///modules/httpd/httpd.conf",
#實際路徑在/etc/puppet/modules/httpd/files/httpd.conf
require => Class["httpd::install"],
notify => Class["httpd::service"]
}
}
[root@vm1 manifests]# vim service.pp
class httpd::service {
service { "httpd":
ensure => running,
require => Class["httpd::install","httpd::config"]
}
file { "/var/www/html/index.html": #添加web主頁
source => "puppet:///files/index.html"
}
}
[root@vm1 manifests]# vim init.pp
class httpd {
include httpd::install,httpd::config,httpd::service
}
[root@vm1 manifests]# vim /etc/puppet/manifests/nodes/vm2.pp
node 'vm2' {
include httpd
}
[root@vm1 manifests]# service puppetmaster reload
模板應用(添加虛擬主機配置):
文件存放在 templates 目錄中,以*.erb 結尾。
[root@vm1 manifests]# vim /etc/puppet/modules/httpd/manifests/init.pp #添加如下行
define httpd::vhost($domainname) {
#file { "/etc/httpd/conf/httpd.conf":
#
content => template("httpd/httpd.conf.erb")
#}
file { "/etc/httpd/conf.d/${domainname}_vhost.conf":
content => template("httpd/httpd_vhost.conf.erb"),
require => Class["httpd::install"],
notify => Class["httpd::service"]
}
file { "/var/www/$domainname":
ensure => directory
}
file { "/var/www/$domainname/index.html":
content => $domainname
}
}
[root@vm1 manifests]# vim /etc/puppet/modules/httpd/templates/httpd_vhost.conf.erb
<VirtualHost *:80>
ServerName <%= domainname %>
DocumentRoot /var/www/<%= domainname %>
ErrorLog logs/<%= domainname %>_error.log
CustomLog logs/<%= domainname %>_access.log common
</VirtualHost>
[root@vm1 manifests]# vi /etc/puppet/manifests/nodes/vm2.pp
node 'vm2' {
include httpd
httpd::vhost { 'server2.example.com':
domainname => "server2.example.com",
}
}
Puppet dashboard 安裝 (用以 web 方式管理 puppet)
依賴性:
* Ruby 1.8.7
* RubyGems
* Rake >= 0.8.3
* MySQL server 5.x
* Ruby-MySQL bindings 2.7.x or 2.8.x
所需安裝包 puppet-dashboard-1.2.12-1.el6.noarch.rpm rubygem-rake-0.8.7-2.1.el6.noarch.rpm ruby-mysql-2.8.2-1.el6.x86_64.rpm
[root@vm1 manifests]# yum localinstall -y puppet-dashboard-1.2.12-1.el6.noarch.rpm rubygem-rake-0.8.7-2.1.el6.noarch.rpm ruby-mysql-2.8.2-1.el6.x86_64.rpm
[root@vm1 manifests]# yum install -y mysql mysql-server
[root@vm1 manifests]# /etc/init.d/mysqld start
配置 mysql 數據庫:
mysql> CREATE DATABASE dashboard_production CHARACTER SET utf8;
Query OK, 1 row affected (0.00 sec)
mysql> CREATE USER 'dashboard'@'localhost' IDENTIFIED BY 'westos';
Query OK, 0 rows affected (0.01 sec)
mysql> GRANT ALL PRIVILEGES ON dashboard_production.* TO 'dashboard'@'localhost';
Query OK, 0 rows affected (0.00 sec)
mysql>
# cd /usr/share/puppet-dashboard/
[root@vm1 puppet-dashboard]# vim config/database.yml #只留下生產環境配置
production:
database: dashboard_production
username: dashboard
password: westos
encoding: utf8
adapter: mysql
[root@vm1 puppet-dashboard]# rake RAILS_ENV=production db:migrate
#創建 dashboard 所需的數據庫和表
puppet-dashboard 默認時區不正確,須要修改:
[root@vm1 puppet-dashboard]# vim /usr/share/puppet-dashboard/config/settings.yml
time_zone: 'Beijing'
啓動服務:
[root@vm1 puppet-dashboard]# service puppet-dashboard start
Starting Puppet Dashboard: => Booting WEBrick
=> Rails 2.3.14 application starting on http://0.0.0.0:3000
[ OK ]
[root@vm1 puppet-dashboard]# chmod 0666 /usr/share/puppet-dashboard/log/production.log
[root@vm1 puppet-dashboard]# service puppet-dashboard-workers start
實時報告彙總:
設置 server 端:
root@vm1 ~]# vim /etc/puppet/puppet.conf
[main]
#添加如下兩項
reports = http
reporturl = http://172.25.254.1:3000/reports
root@vm1 ~]# service puppetmaster reload
設置 client 端:
[root@vm1 puppet-dashboard]# vim /etc/puppet/puppet.conf #添加如下行
[agent]
report = true
[root@vm1 puppet-dashboard]# service puppet reload
在客戶端安裝完 puppet 後,而且認證完後,咱們能夠看到效果,那怎樣讓它自動與服務器同步
呢?默認多少分鐘跟服務器同步呢?怎樣修改同步的時間呢,這時候咱們須要配置客戶端:
(1) 配置 puppet 相關參數和同步時間:
[root@vm2 ~]# vim /etc/sysconfig/puppet
PUPPET_SERVER=puppet.example.com #puppet master 的地址
PUPPET_PORT=8140 #puppet 監聽端口
PUPPET_LOG=/var/log/puppet/puppet.log #puppet 本地日誌
#PUPPET_EXTRA_OPTS=--waitforcert=500 【默認同步的時間,我這裏不修改這行參數】
(2) 默認配置完畢後,客戶端會半個小時跟服務器同步一次,咱們能夠修改這個時間。
[root@vm2 ~]# vim /etc/puppet/puppet.conf
[agent]
runinterval = 60 #表明 60 秒跟服務器同步一次
[root@vm2 ~]# service puppet reload
對puppet的優化 經過nginx + passenger替換掉puppet的WEBRickHTTP,來處理HTTPS請求,並實現對puppet的負載均衡。
實驗步驟:master 端須要可以連上外網把如下條目加入 yum 倉庫:[puppet]name=puppetbaseurl=http://yum.puppetlabs.com/el/6Server/products/x86_64/gpgcheck=0[ruby]name=rubybaseurl=http://yum.puppetlabs.com/el/6Server/dependencies/x86_64/gpgcheck=0# yum install -y gcc gcc-c++ curl-devel zlib-devel openssl-devel ruby-devel# gem install rack passenger ##次過程須要等待一段時間# gem list*** LOCAL GEMS ***json (1.5.5)passenger (5.0.15)rack (1.6.4)rake (10.4.2)# passenger-config --root/usr/lib/ruby/gems/1.8/gems/passenger-5.0.15# ls /usr/lib/ruby/gems/1.8/gems/passenger-5.0.15/ext/ apache2 boost common libev libuv nginx oxt ruby #nginx 等許多支持# passenger-install-nginx-module腳本會自動安裝 nginx 支持,按提示操做,基本就是一路回車。 nginx 默認安裝在/opt/nginx 目錄: # vim /opt/nginx/conf/nginx.conf 1 #user nobody; 2 worker_processes 4; 3 4 #error_log logs/error.log; 5 #error_log logs/error.log notice; 6 #error_log logs/error.log info; 7 8 #pid logs/nginx.pid; 9 10 11 events { 12 use epoll; 13 worker_connections 1024; 14 } 15 16 17 http { 18 passenger_root /usr/lib/ruby/gems/1.8/gems/passenger-5.0.15; 19 passenger_ruby /usr/bin/ruby; 20 21 include mime.types; 22 default_type application/octet-stream; 23 24 #log_format main '$remote_addr - $remote_user [$time_local] "$request" ' 25 # '$status $body_bytes_sent "$http_referer" ' 26 # '"$http_user_agent" "$http_x_forwarded_for"'; 27 28 #access_log logs/access.log main; 29 30 sendfile on; 31 tcp_nopush on; 32 33 #keepalive_timeout 0; 34 keepalive_timeout 65; 35 36 #gzip on; 37 38 server { 39 listen 8140; 40 server_name benberba.example.com; 41 root /etc/puppet/rack/public; 42 passenger_enabled on; 43 passenger_set_header X_CLIENT_DN $ssl_client_s_dn; 44 passenger_set_header X_CLIENT_VERIFY $ssl_client_verify; 45 ssl on; 46 ssl_session_timeout 5m; 47 ssl_certificate /var/lib/puppet/ssl/certs/vm1.example.com.pem; 48 ssl_certificate_key /var/lib/puppet/ssl/private_keys/vm1.example.co m.pem; 49 ssl_client_certificate /var/lib/puppet/ssl/ca/ca_crt.pem; 50 ssl_crl /var/lib/puppet/ssl/ca/ca_crl.pem; 51 ssl_verify_client optional; 52 ssl_ciphers SSLv2:-LOW:-EXPORT:RC4+RSA; 53 ssl_prefer_server_ciphers on; 54 ssl_verify_depth 1; 55 ssl_session_cache shared:SSL:128m; 56 } 57 }# mkdir /etc/puppet/rack/{public,tmp} -p# cp /usr/share/puppet/ext/rack/config.ru /etc/puppet/rack/# chown puppet.puppet /etc/puppet/rack/config.ru# chkconfig puppetmaster off# service puppetmaster stop# /opt/nginx/sbin/nginx -t #檢測 nginx# /opt/nginx/sbin/nginx #啓動 nginxpuppetmaster 不須要啓動 , nginx 啓動時會自動調用 puppet。測試 master端 # netstat -antpl |grep 8140tcp 0 0 0.0.0.0:8140 0.0.0.0:* LISTEN 4245/nginx # /etc/init.d/puppetmaster status puppet is stoppedclient端 # puppet agent --server vm1.example.com --no-daemonize --verboseNotice: Starting Puppet client version 3.8.1Info: Retrieving pluginfactsInfo: Retrieving pluginInfo: Caching catalog for vm2.example.comInfo: Applying configuration version '1440218993'Notice: Finished catalog run in 0.21 seconds