自動化運維之puppet
puppet介紹
puppet是一種Linux、Unix、windows平臺的集中配置管理系統,使用自有的puppet描述語言,可管理配置文件、用戶、cron任務、軟件包、系統服務等。puppet把這些系統實體稱之爲資源,puppet的設計目標是簡化對這些資源的管理以及妥善處理資源間的依賴關係。
puppet採用C/S星狀的結構,所有的客戶端和一個或幾個服務器交互。每個客戶端週期的(默認半個小時)向服務器發送請求,獲得其最新的配置信息,保證和該配置信息同步。每個puppet客戶端每半小時(可以設置)連接一次服務器端, 下載最新的配置文件,並且嚴格按照配置文件來配置客戶端. 配置完成以後,puppet客戶端可以反饋給服務器端一個消息. 如果出錯,也會給服務器端反饋一個消息.
具體的工作流程:
- 客戶端puppet調用facter(facter是通過SSL加密收集及檢測分析客戶端配置信息的一個工具)。facter探測出主機的一些變量,如主機名,內存大小,IP地址等。Puppet將這些信息通過SSL連接發送到服務端
- 服務端的puppetmaster通過facter工具分析檢測客戶端的主機名,然後找到項目主配置文件manifest裏面對應的node配置,並對該部分內容進行解析。facter發送過來的信息可以作爲變量處理,node牽涉到的代碼才進行解析,其他沒牽涉的代碼不解析。解析分幾個階段,首先進行語法檢測,如果語法沒有錯,就繼續解析,解析的結果生成一箇中間的“僞代碼”,然後將“僞代碼”發送給客戶端。
- 客戶端接受到“僞代碼”並執行,然後將執行結果發送給服務端。
- 服務端把客戶端的執行結果寫入到日誌中去。
-
Puppet工作中以下兩點值得注意:
- 爲了保證安全,client和master之間是基於SSL和證書通信的,只有經過master證書認證的client纔可以和master通信。
- puppet會讓系統保持在人們期望的某種狀態並之一持續下去,如檢測某個文件並一直保證其一致存在,保證ssh服務始終開啓,如果文件被刪除或者ssh服務被關閉,puppet下次執行時(默認30分鐘),會重新創建該文件或者啓動ssh服務。
實驗環境
本實驗使用四臺服務器模擬搭建puppet環境,具體拓撲圖如下:
各服務器IP分佈如下表
主機 | IP地址 |
---|---|
puppetmaster | 192.168.58.146 |
puppetclient1 | 192.168.58.148 |
puppetclient2 | 192.168.58.149 |
ntp server | 192.168.58.147 |
實驗實施
搭建puppet master
- 規劃服務器主機名
在小規模的環境下,我們直接修改/etc/hosts和/etc/hostname兩個文件,以pupetmaster服務器爲例。
[root@master ~]# cat /etc/hostname #修改主機名
master.test.cn
[root@master ~]# cat /etc/hosts #將三臺服務器主機名和IP地址寫到/etc/hosts文件中去
192.168.58.146 master.test.cn
192.168.58.148 client1.test.cn
192.168.58.149 client2.test.cn
[root@master ~]# ping client1.test.cn
PING client1.test.cn (192.168.58.148) 56(84) bytes of data.
64 bytes from client1.test.cn (192.168.58.148): icmp_seq=1 ttl=64 time=0.846 ms
64 bytes from client1.test.cn (192.168.58.148): icmp_seq=2 ttl=64 time=0.477 ms
64 bytes from client1.test.cn (192.168.58.148): icmp_seq=3 ttl=64 time=0.438 ms
[root@master ~]# systemctl stop firewalld
[root@master ~]# setenforce 0
- 服務器時間同步
由於Puppet需要使用SSL證書,依賴時間同步,所以需要搭建NTP服務器。以下操作在NTP服務器上操作。
[root@promote ~]# yum install ntp -y
[root@promote ~]# systemctl start ntpd
[root@promote ~]# systemctl enable ntpd
[root@promote ~]# systemctl stop firewalld
[root@promote ~]# setenforce 0
[root@promote ~]# ntpstat
synchronised to NTP server (85.199.214.100) at stratum 2
time correct to within 191 ms
polling server every 64 s
- puppetmaster作爲NTP服務器客戶端進行配置
[root@master ~]# yum install ntpdate -y
#安裝NTP客戶端
[root@master ~]# ntpdate 192.168.58.147
5 Aug 16:54:55 ntpdate[2361]: adjust time server 192.168.58.147 offset -0.022671 sec
#與NTP服務器進行時間同步
- 安裝Puppet服務端
[root@master ~]# yum install epel-release -y #安裝epel第三方源 [root@master ~]# yum install puppet-server -y #安裝Puooet服務端 [root@master ~]# systemctl start puppetmaster.service #啓動puppetmaster服務
搭建puppetclient
兩臺puppetclient服務器配置類似,只有主機名注意區分
- 首先配置服務器主機名
[root@client1 ~]# cat /etc/hostname client1.test.cn [root@client1 ~]# cat /etc/hosts 192.168.58.146 master.test.cn 192.168.58.148 client1.test.cn 192.168.58.149 client2.test.cn [root@client1 ~]# ping master.test.cn PING master.test.cn (192.168.58.146) 56(84) bytes of data. 64 bytes from master.test.cn (192.168.58.146): icmp_seq=1 ttl=64 time=0.665 ms 64 bytes from master.test.cn (192.168.58.146): icmp_seq=2 ttl=64 time=0.504 ms ^C64 bytes from master.test.cn (192.168.58.146): icmp_seq=3 ttl=64 time=0.163 ms #可以通過域名ping通pupetmaster服務器
- 服務器時間同步
[root@client1 ~]# yum install ntpdate -y [root@client1 ~]# ntpdate 192.168.58.147 5 Aug 17:00:29 ntpdate[2249]: adjust time server 192.168.58.147 offset -0.052137 sec #和NTP服務器進行同步
- 安裝puppet客戶端
[root@client1 ~]# yum install epel-release -y #安裝epel第三方源 [root@client1 ~]# yum install puppet -y #安裝puppet客戶端
- 修改配置文件
兩臺puppetclient都是一樣的修改,指定Puppet Master服務器。[root@client1 ~]# vim /etc/puppet/puppet.conf
-
申請和註冊
分別在client1和client2上進行註冊。[root@client1 ~]# puppet agent --server=master.test.cn --no-daemonize --verbose #這個就是註冊命令,執行完後會有下面的提示 Info: Creating a new SSL key for client1.test.cn Info: Caching certificate for ca Info: csr_attributes file loading from /etc/puppet/csr_attributes.yaml Info: Creating a new SSL certificate request for client1.test.cn Info: Certificate Request fingerprint (SHA256): 92:9E:71:34:3C:A8:90:5B:68:77:44:5A:3A:15:26:C9:29:86:F9:60:D2:2D:61:D4:1A:79:C2:2F:C9:CF:C5:01 Info: Caching certificate for ca #等待一會兒後,可以自己Ctrl+C結束,然後到server中查看申請信息。
我們到master服務器中查看申請信息
[root@master ~]# puppet cert --list "client1.test.cn" (SHA256) 92:9E:71:34:3C:A8:90:5B:68:77:44:5A:3A:15:26:C9:29:86:F9:60:D2:2D:61:D4:1A:79:C2:2F:C9:CF:C5:01 "client2.test.cn" (SHA256) 9D:7E:22:85:1D:79:08:31:00:BE:2F:35:C2:F2:71:B9:DC:22:0D:24:8C:58:8E:7D:DA:79:9A:94:D5:C6:22:9A #可以看到兩臺客戶端提出了註冊申請
對未註冊的客戶端註冊
[root@master ~]# puppet cert sign --all Notice: Signed certificate request for client1.test.cn Notice: Removing file Puppet::SSL::CertificateRequest client1.test.cn at '/var/lib/puppet/ssl/ca/requests/client1.test.cn.pem' Notice: Signed certificate request for client2.test.cn Notice: Removing file Puppet::SSL::CertificateRequest client2.test.cn at '/var/lib/puppet/ssl/ca/requests/client2.test.cn.pem' #可以看到已經通過了申請
可以通過目錄去查看已經註冊的客戶端
[root@master puppet]# cd /var/lib/puppet/ssl/ca/signed/ [root@master signed]# ls client1.test.cn.pem client2.test.cn.pem master.test.cn.pem #可以看到已經完成了證書的請求和簽名
配置實例
這裏爲了保護Linux的ssh端口,修改客戶端client1的sshd端口,將端口22修改爲9922,並實現重啓工作。
- 首先創建ssh模塊,ssh模塊下面有三個文件:manifests,templates和files。
- 在manifests裏面包含一個init.pp文件,這是該模塊的初始入口文件,導入模塊時,會從init.pp開始執行。可以把所有的代碼都寫到init.pp裏面,也可以分成多個pp文件,init再去包含其他文件。定義class類名的時候必須是ssh,這樣才能調用
- file目錄是該模塊的文件發佈目錄,Puppet提供一個文件分發機制,類似於rsync的模塊。
- templates目錄包含erb模型文件,這個和file資源的template屬性相關,不過很少用。具體配置如下:
創建必要的目錄:[root@master signed]# cd /etc/puppet/ [root@master puppet]# mkdir -p modules/ssh/{manifests,templates,files} [root@master puppet]# mkdir manifests/nodes [root@master puppet]# mkdir modules/ssh/files/ssh [root@master puppet]# chown -R puppet modules/ #修改屬主
此時/etc/puppet/modules/ssh目錄下的結構如下:
[root@master puppet]# ll modules/ssh/ 總用量 0 drwxr-xr-x. 3 puppet root 17 8月 5 17:25 files drwxr-xr-x. 2 puppet root 6 8月 5 17:25 manifests drwxr-xr-x. 2 puppet root 6 8月 5 17:25 templates
創建模塊配置文件install.pp
[root@master puppet]# vim /etc/puppet/modules/ssh/manifests/install.pp class ssh::install{ package{"openssh": ensure=>present, } } ~
創建模塊配置文件config.pp
[root@master puppet]# vim /etc/puppet/modules/ssh/manifests/config.pp
class ssh::config{
file {"/etc/ssh/sshd_config": #配置客戶端需要同步的文件
ensure=>present, #確認客戶端中有此文件
owner=>"root", #文件屬主
group=>"root", #文件屬組
mode=>"0600", #文件權限屬性
source=>"puppet://$puppetserver/modules/ssh/ssh/sshd_config",
#從服務端同步文件
require=>Class["ssh::install"], #調用install.pp確認ssh已經安裝
notify=>Class["ssh::service"], #如果config.pp發生變化,通知service.pp
}
}
~
創建模塊配置文件service.pp
[root@master puppet]# vim /etc/puppet/modules/ssh/manifests/service.pp
class ssh::service{
service { "sshd":
ensure=>running, #確認ssh運行
hasstatus=>true, #puppet該服務支持status命令,類似於service sshd status
hasrestart=>true, #puppet該服務支持restart,類似於service sshd restart
enable=>true, #服務器是否開機啓動
require=>Class["ssh::config"] #確認config.pp調用
}
}
創建模塊主配置文件init.pp
[root@master puppet]# vim /etc/puppet/modules/ssh/manifests/init.pp
class ssh {
include ssh::install,ssh::config,ssh::service
#將配置文件加載到ssh類中去
}
~
現在/etc/puppet/modeles/ssh/mainfests目錄下有四個文件:
[root@master puppet]# ll /etc/puppet/modules/ssh/manifests/
總用量 16
-rw-r--r--. 1 root root 337 8月 5 17:34 config.pp
-rw-r--r--. 1 root root 67 8月 5 17:43 init.pp
-rw-r--r--. 1 root root 72 8月 5 17:28 install.pp
-rw-r--r--. 1 root root 203 8月 5 17:40 service.pp
建立服務端ssh同意維護文件,由於服務端和客戶端的sshs_config文件默認一樣,此時將服務端的/etc/ssh/sshd_config複製到模塊默認路徑中去。
[root@master puppet]# cp /etc/ssh/sshd_config /etc/puppet/modules/ssh/files/ssh/
[root@master puppet]# chown -R puppet /etc/puppet/modules/ssh/files/ssh/
#修改文件夾屬主
創建測試節點配置文件,並將ssh加載進去。
[root@master puppet]# vim /etc/puppet/manifests/nodes/ssh.pp
node 'client1.test.cn'{
include ssh
}
~
將測試節點載入puppet,即修改site.pp
[root@master puppet]# vim /etc/puppet/manifests/site.pp
import "nodes/ssh.pp"
~
修改服務器維護的sshd_config配置文件
[root@master puppet]# vim /etc/puppet/modules/ssh/files/ssh/sshd_config
Port 9922 #修改爲9922
重啓puppet
[root@master puppet]# systemctl restart puppetmaster.service
客戶端主動拉取,
[root@client1 ~]# puppet agent -t
...省略
Info: Applying configuration version '1533463512'
Notice: /Stage[main]/Ssh::Config/File[/etc/ssh/sshd_config]/content:
--- /etc/ssh/sshd_config 2017-08-07 10:28:25.000000000 +0800
+++ /tmp/puppet-file20180805-3493-173oey2 2018-08-05 18:05:13.550668088 +0800
@@ -14,7 +14,7 @@
SELinux about this change.
semanage port -a -t ssh_port_t -p tcp #PORTNUMBER
#
-#Port 22
+Port 9922
#AddressFamily any
#ListenAddress 0.0.0.0
#ListenAddress ::
...省略
此時在client端已經執行成功,現在就去客戶端驗證一下:
[root@client1 ~]# netstat -ntap | grep 9922
tcp 0 0 0.0.0.0:9922 0.0.0.0: LISTEN 3695/sshd
tcp6 0 0 :::9922 ::: LISTEN 3695/sshd