💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。
推荐:Linux运维老纪的首页,持续学习,不断总结,共同进步,活到老学到老
导航剑指大厂系列:全面总结 运维核心技术:系统基础、数据库、网路技术、系统安全、自动化运维、容器技术、监控工具、脚本编程、云服务等。
常用运维工具系列:常用的运维开发工具, zabbix、nagios、docker、k8s、puppet、ansible等
数据库系列:详细总结了常用数据库 mysql、Redis、MongoDB、oracle 技术点,以及工作中遇到的 mysql 问题等
懒人运维系列:总结好用的命令,解放双手不香吗?能用一个命令完成绝不用两个操作
数据结构与算法系列:总结数据结构和算法,不同类型针对性训练,提升编程思维,剑指大厂
非常期待和您一起在这个小小的网络世界里共同探索、学习和成长。💝💝💝 ✨✨ 欢迎订阅本专栏 ✨✨
自动化运维之Puppet 部署应用
技能目标
-
熟悉 Puppet 工作原理
-
掌握 Puppet 部署应用配置方法
4.1 案例一分析
4.1.1 案例概述
作为一名系统管理员,维护服务器正常运行是最基本的职责。在管理几台到几十
台服务器时,大部分管理员喜欢写自己的小工具来维护。但是随着服务器数量的增多,
任务量也逐渐增加,这时就需要简洁的、强大的框架来完成系统管理任务。
为实现这一目的,引入一批工具。这批工具是“可编程”的,系统管理员只需要为
这批工具写上几行“代码”,它便会自动完成所有的工作,Puppet 就是这批运维自动化
工具中的其中一种。在一些大型互联网企业中,Puppet 运维自动化工具管理着几百
甚至上千台服务器,它可以针对多台服务器进行统一操作,如部署统一软件、进行统
一上线维护等,而且能够快速完成上线部署,减少人力并降低人力误操作风险。
4.1.2 案例前置知识点
1. Puppet 工作原理
Puppet 的目的是让管理员只集中于要管理的目标,而忽略实现的细节。Puppet 既
可以在单机上使用,也可以以 C/S 结构使用。在大规模使用 Puppet 的情况下,通常使
用 C/S 结构。在这种结构中 Puppet 客户端只运行 Puppet Client,Puppet 服务器端
只运行 Puppet Master。
Puppet 管理工具的工作流程如图 4.1 所示。
图 4.1 Puppet 工作流程
(1)客户端 Puppet 调用 Facter 工具(Facter 是通过 SSL 加密收集及检测分析
客户端配置信息的一个工具),Facter 探测出主机的一些变量,如主机名、内存大小、
IP 地址等。Puppet 把这些信息通过 SSL 连接发送到服务器端。
(2)服务器端的 Puppet Master 通过 Facter 工具分析检测客户端的主机名,然
后找到项目主配置文件 manifest 里面对应的 node 配置, 并对该部分内容进行解析。
Facter 发送过来的信息可以作为变量处理,node 牵涉到的代码才解析,其他没牵涉
的代码不解析。解析分为几个阶段,首先进行语法检查。如果语法没错,就继续解析。
解析的结果生成一个中间的“伪代码”,然后把伪代码发给客户端。
(3)客户端接收到“伪代码”并且执行,客户端把执行结果发送给服务器。
(4)服务器端把客户端的执行结果写入日志。
2. Puppet 工作中的注意事项
Puppet 工作过程中,有以下两点值得注意。
(1)为了保证安全,Client 和 Master 之间是基于 SSL 和证书的,只有经 Master
证书认证的 Client 才能与 Master 通信。
(2)Puppet 会让系统保持在人们所期望的某种状态并一直维持下去。例如检测
某个文件并保证其一直存在,保证 SSH 服务始终开启,如果文件被删除了或者 SSH
服务被关闭了,Puppet 下次执行时(默认 30 分钟),会重新创建该文件或者启动 SSH
服务。
4.1.3 案例环境
1. 本案例实验环境
本案例主要演示批量管理客户端 SSH 服务,案例实验中使用的四台服务器均采
用 CentOS7.3 系统版本且图形化安装,要求能上互联网,Selinux 和防火墙均已关闭。
本案例的拓扑图如下 4.2 所示。
图 4.2 实验拓扑
服务器具体信息如表 4-1 所示。
表 4-1 服务器具体配置信息
角色 | 主机名 | IP 地址 | 主要软件 |
master | master.puppet.com | 192.168.0.111 | Puppet-server |
client | client01.puppet.com | 192.168.0.112 | Puppet |
client | client02.puppet.com | 192.168.0.113 | Puppet |
ntp | ntp.puppet.com | 192.168.0.114 | ntp |
2. 案例需求
使用 Puppet 批量修改客户端 SSH 服务端口。
3. 案例实现思路(1)环境准备工作;
(2)安装 Puppet Master 和 Puppet Client;
(3)配置测试节点;
(4)客户端主动拉取和服务端主动推送。
4.2 案例一实施
4.2.1 Puppet 安装与部署
1. 规划服务器主机名
在小规模 Puppet 环境下,一般是修改/etc/hosts 文件实现服务通过主机名进行通
信,然而上千台服务器,需要搭建自己的 DNS 服务器来实现服务通过主机名进行通
信。此实验我们通过修改/etc/hosts 文件来实现。
[root@node1 ~]# hostnamectl set-hostname master.puppet.com
[root@node1 ~]# bash
[root@master ~]# hostname
master.puppet.com
另外,三台服务器上分别修改主机名。
[root@node2 ~]# hostnamectl set-hostname client01.puppet.com
[root@node3 ~]# hostnamectl set-hostname client02.puppet.com
[root@node4 ~]# hostnamectl set-hostname ntp.puppet.com
在 四 台 服 务 器 的 /etc/hosts 文 件 中 都 添 加 以 下 几 行 地 址 解 析 记 录 。 以
master.puppet.com 主机为例进行操作演示。
[root@master ~]# cat << EOF >> /etc/hosts
192.168.0.111 master.puppet.com
192.168.0.112 client01.puppet.com
192.168.0.113 client02.puppet.com
192.168.0.114 ntp.puppet.com
EOF
2. 搭建时间服务器
由于 Puppet 使用的 SSL 证书依赖时间同步,所以需要搭建 NTP 服务器。
(1)搭建 NTP Server
[root@ntp ~]# yum install -y ntp
[root@ntp ~]# vim /etc/ntp.conf
\\添加以下两行
server 127.127.1.0
fudge 127.127.1.0 stratum 8
上述配置的作用是当/etc/ntp.conf 中定义的 server 都不可用时,将使用 local 时
间作为 NTP 服务提供给 NTP 客户端。修改完/etc/ntp.conf 文件后,可启动 NTP 服务。
[root@ntp ~]# systemctl start ntpd
[root@ntp ~]# systemctl enable ntpd
//设置开机自启动
Created
symlink
from
/etc/systemd/system/multi-user.target.wants/ntpd.service
to
/usr/lib/systemd/system/ntpd.service.
[root@ntp ~]# ntpstat
//查看时间同步状态
synchronised to local net (127.127.1.0) at stratum 9
time correct to within 7948 ms
polling server every 64 s
(2)节点同步时间
其余三台主机都要执行时间同步操作,下面仅以在 master.puppet.com 主机为例
进行演示。
[root@master ~]# yum install -y ntp
[root@master ~]# ntpdate ntp.puppet.com
3 Jul 10:13:16 ntpdate[3853]: adjust time server 192.168.0.114 offset -0.004241 sec
3. 安装 Puppet Master
从 官 网 https://yum.puppetlabs.com/el/7/products/x86_64/ 下 载 Puppet 源
puppetlabs-release-7-12.noarch.rpm 软件包,上传到 master.puppet.com 服务器上。
(1)安装 puppetlabs 源
[root@master ~]# rpm -ivh puppetlabs-release-7-12.noarch.rpm
警 告 : puppetlabs-release-7-12.noarch.rpm: 头 V4 RSA/SHA1 Signature, 密 钥 ID 4bd6ec30:
NOKEY
准备中...
################################# [100%]
正在升级/安装...
1:puppetlabs-release-7-12
################################# [100%]
(2)安装并启动 Puppet 服务端
[root@master ~]# yum install -y puppet-server
[root@master ~]# systemctl start puppetmaster
[root@master ~]# systemctl enable puppetmaster
Created symlink from /etc/systemd/system/multi-user.target.wants/puppetmaster.service to
/usr/lib/systemd/system/puppetmaster.service.
4. 安装 Puppet Client
两台客户端安装并配置 Puppet,下面仅以 client01.puppet.com 主机为例进行操
作演示。从官网下载 Puppet 源 puppetlabs-release-7-12.noarch.rpm,上传到两台客
户端服务器上。
(1)安装 puppetlabs 源
[root@client01 ~]# rpm -ivh puppetlabs-release-7-12.noarch.rpm
警 告 : puppetlabs-release-7-12.noarch.rpm: 头 V4 RSA/SHA1 Signature, 密 钥 ID 4bd6ec30:
NOKEY
准备中...
################################# [100%]
正在升级/安装...
1:puppetlabs-release-7-12
################################# [100%]
(2)客户端安装 Puppet
[root@client01 ~]# yum install -y puppet
(3)修改客户端配置文件
在 /etc/puppet/puppet.conf 文 件 中 的 [main] 标 题 下 添 加 “server =
master.puppet.com”配置字段用于设置 Puppet Master 的域名。
[root@client01 ~]# vim /etc/puppet/puppet.conf
server = master.puppet.com
5. 注册
(1)客户端申请注册
在两台客户端上申请注册,下面以 client01.puppet.com 主机为例进行操作演示。
[root@client01 ~]# puppet agent --server=master.puppet.com --no-daemonize --verbose
Info: Creating a new SSL key for client01.puppet.com
Info: Caching certificate for ca
Info: csr_attributes file loading from /etc/puppet/csr_attributes.yaml
Info: Creating a new SSL certificate request for client01.puppet.com
Info:
Certificate
Request
fingerprint
(SHA256):
42:17:0F:38:2F:2E:71:43:45:36:57:C3:B2:B8:23:42:29:01:8F:60:B8:CC:4E:0E:5B:48:EA:9E:F9:86:
34:51
Info: Caching certificate for ca
等待一会儿,可以按 Ctrl+C 结束,从服务器端查看到申请信息。
[root@master ~]# puppet cert --list //在 Master 端查看申请注册的客户端
"client01.puppet.com"
(SHA256)
E1:66:62:91:8D:98:99:C4:8D:F0:20:64:A6:95:1F:93:B9:95:73:6A:7A:B5:85:18:C4:43:9B:FF:E5:61:
37:AF
"client02.puppet.com"
(SHA256)
E8:ED:80:B2:14:B4:3B:41:C5:4E:EC:97:7A:96:52:1F:36:EA:03:5A:FD:8B:AD:12:86:3A:3B:D6:D2:3
7:0C:29
(2)完成注册
在 Master 上,将所有申请未注册的客户端进行注册。
[root@master ~]# puppet cert sign --all
Notice: Signed certificate request for client01.puppet.com
Notice:
Removing
file
Puppet::SSL::CertificateRequest
client01.puppet.com
at
'/var/lib/puppet/ssl/ca/requests/client01.puppet.com.pem'
Notice: Signed certificate request for client02.puppet.com
Notice:
Removing
file
Puppet::SSL::CertificateRequest
client02.puppet.com
at
'/var/lib/puppet/ssl/ca/requests/client02.puppet.com.pem'
注册成功后,可以通过目录去查看已经注册的客户端。
[root@master ~]# ll /var/lib/puppet/ssl/ca/signed/
总用量 12
-rw-r--r-- 1 puppet puppet 1960 7 月
3 13:21 client01.puppet.com.pem
-rw-r--r-- 1 puppet puppet 1960 7 月
3 13:21 client02.puppet.com.pem
-rw-r--r-- 1 puppet puppet 2037 7 月
3 11:05 master.puppet.com.pem
此时,客户端已经完成证书的请求与签名。
4.2.2 配置实例
为了保护 Linux 的 SSH 端口,批量修改客户端 SSH 端口,将默认端口 22 修改
为 9922,并实现重启工作。在 Master 端创建 SSH 模块,模块目录为 ssh,模块目
录下面有三个子目录:manifests、templates 和 files。
manifests 里面必须要包含一个 init.pp 的文件,这是该模块的初始(入口)文件,
导入一个模块的时候,会从 init.pp 开始执行。可以把所有的代码都写到 init.pp
里面,也可以分成多个 pp 文件,init 再去包含其他文件,定义 class 类名的时候
必须是 ssh,这样才能实现调用。
files 目录是该模块的文件发布目录,Puppet 提供一个文件分发机制,类似 rsync
的模块。
templates 目录包含 erb 模型文件,这个和 file 资源的 template 属性有关(很少
用)。
1. 配置测试节点
Master 需要使用的相关配置文件如下:
节点信息:/etc/puppet/manifests/nodes/。
模块信息:/etc/puppet/modules/。
(1)Master 上创建需要的目录
[root@master ~]# 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/
//修改权限
[root@master puppet]# ll modules/ssh //查看/etc/puppet/modules/ssh 目录下的结构
总用量 0
drwxr-xr-x 3 puppet root 17 7 月
3 14:18 files
drwxr-xr-x 2 puppet root 6 7 月
3 14:08 manifests
drwxr-xr-x 2 puppet root 6 7 月
3 14:08 templates
(2)创建模块配置文件 install.pp
[root@master ~]# vim /etc/puppet/modules/ssh/manifests/install.pp
//输入以下信息(首先确定客户端安装 SSH 服务)
class ssh::install{
package{ "openssh":
ensure => present,
}
}
(3)创建模块配置文件 config.pp
[root@master ~]# 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
}
}
(4)创建模块配置文件 service.pp
[root@master ~]# 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 调用
}
}
(5)创建模块主配置文件 init.pp
[root@master ~]# vim /etc/puppet/modules/ssh/manifests/init.pp
class ssh{
include ssh::install,ssh::config,ssh::service //加载以上配置文件
}
此时,/etc/puppet/modules/ssh/manifests 目录下有四个文件。
[root@master ~]# ll /etc/puppet/modules/ssh/manifests/
总用量 16
-rw-r--r-- 1 root root 378 7 月 3 15:33 config.pp
-rw-r--r-- 1 root root 67 7 月 3 16:50 init.pp
-rw-r--r-- 1 root root 82 7 月 3 15:31 install.pp
-rw-r--r-- 1 root root 234 7 月 3 16:50 service.pp
(6)建立服务器端 ssh 统一维护文件
复制服务器端/etc/ssh/sshd_config 文件到模块默认路径。
[root@master ~]# cp /etc/ssh/sshd_config /etc/puppet/modules/ssh/files/ssh/
[root@master ~]# chown -R puppet /etc/puppet/modules/ssh/files/ssh/
(7)创建测试节点配置文件
创建测试节点配置文件,并加载 SSH。
[root@master ~]# vim /etc/puppet/manifests/nodes/ssh.pp
node 'client01.puppet.com'{
include ssh
}
node 'client02.puppet.com'{
include ssh
}
(8)将测试节点载入 Puppet,即修改 site.pp
[root@master ~]# vim /etc/puppet/manifests/site.pp
import "nodes/ssh.pp"
(9)修改服务端维护的 sshd_config 配置文件
[root@master ~]# vim /etc/puppet/modules/ssh/files/ssh/sshd_config
Port 9922
//取消注释并修改为 9922
#AddressFamily any
#ListenAddress 0.0.0.0
#ListenAddress ::
(10)重新启动 Puppet Master 服务
[root@master ~]# systemctl restart puppetmaster
2. 客户端主动拉取
在其中一台 client01.puppet.com 客户端上,执行以下操作从服务器端主动拉取
配置。
[root@client01 ~]# puppet agent -t
......
//省略部分
+++ /tmp/puppet-file20200716-2177-zqlbd0
2020-07-3 17:11:57.327357239 +0800
@@ -15,6 +15,7 @@
# semanage port -a -t ssh_port_t -p tcp #PORTNUMBER
#
#Port 22
+Port 9922
#AddressFamily any
#ListenAddress 0.0.0.0
#ListenAddress ::
Info: Computing checksum on file /etc/ssh/sshd_config
Info: /Stage[main]/Ssh::Config/File[/etc/ssh/sshd_config]: Filebucketed /etc/ssh/sshd_config to
puppet with sum 0440a9608de01c4fa1c1dd6301b568ec
Notice:
/Stage[main]/Ssh::Config/File[/etc/ssh/sshd_config]/content:
content
changed
'{md5}0440a9608de01c4fa1c1dd6301b568ec' to '{md5}34ba2b7fa9efb61396216aad50899226'
Info: /Stage[main]/Ssh::Config/File[/etc/ssh/sshd_config]: Scheduling refresh of Class[Ssh::Service]
Info: Class[Ssh::Service]: Scheduling refresh of Service[sshd]
Notice: /Stage[main]/Ssh::Service/Service[sshd]: Triggered 'refresh' from 1 events
Info: Creating state file /var/lib/puppet/state/state.yaml
Notice: Finished catalog run in 1.20 seconds
[root@client01 ~]# cat /etc/ssh/sshd_config | grep Port
Port 9922
#GatewayPorts no
查看服务器 SSH 服务是否重启,端口是否生效。
[root@client01 ~]# netstat -tunlp | grep ssh
tcp
0
0 0.0.0.0:9922 0.0.0.0:*
LISTEN
2370/sshd
tcp6
0
0 :::9922
:::*
LISTEN
2370/sshd
3. 服务端主动推送
当大规模部署时不可能在每台客户端都采用拉取动作,而此时用服务器推送模式
反而更合理。在客户端 client02.puppet.com 上做修改。
(1)修改 puppet 配置文件,最后一行添加如下。
[root@client02 ~]# vim /etc/puppet/puppet.conf
listen = true //使 Puppet 监听 8139 端口
(2)修改验证配置文件 auth.conf 定义一些验证信息及访问权限,最后一行添加
如下。
[root@client02 ~]# vim /etc/puppet/auth.conf
allow *
//允许任何服务端推送
(3)启动 Puppet Agent 客户端。
[root@client02 ~]# systemctl start puppetagent
(4)修改客户端 client02.puppet.com 的/etc/ssh/sshd_config 文件,将 Port 9922
还原成最初始状态,然后重启 sshd 服务。
查看还原后的/etc/ssh/sshd_config 的内容如下。
[root@client02 ~]# cat /etc/ssh/sshd_config | grep Port
#Port 22
#GatewayPorts no
[root@client02 ~]# netstat -tunlp| grep ssh
tcp
0
0 0.0.0.0:22
0.0.0.0:*
LISTEN 3161/sshd
tcp6
0
0 :::22
:::*
LISTEN 3161/sshd
(5)向 client02.puppet.com 节点推送配置。
[root@master ~]# puppet kick client02.puppet.com
Triggering client02.puppet.com
Getting status
status is success
client02.puppet.com finished with exit code 0
Finished
(6)校验结果
此时,在 client02.puppet.com 主机上可以查看到 SSH 端口已经被更改为 9922。
[root@client02 ~]# cat /etc/ssh/sshd_config | grep Port
Port 9922
#GatewayPorts no
[root@client02 ~]# netstat -tunlp | grep sshd
tcp
0
0 0.0.0.0:9922 0.0.0.0:*
LISTEN
3371/sshd
tcp6
0
0 :::9922
:::*
LISTEN
3371/sshd
4.3 案例二分析
4.3.1 案例概述
如果有工作经验的朋友看到升级部署,第一时间会想到是将新的应用替换或覆盖
旧的应用,然后重启服务之类的。没错,这里的自动部署就是将新的应用自动覆盖旧
的应用,起到一个更新的作用,主要还是利用文件拷贝的原理。
网上可能大部分自动部署的案例是将 SVN 和 Puppet Master 整合在一台服务器
上。如果 SVN 服务器里面的代码有更新,Puppet Agent 就会根据自身设置拉取更新
文件完成全自动部署。这样做唯一的缺点就是如果出现问题,不能很好的控制。例如:
由于开发人员误操作导致一个错误的文件已提交到 SVN 服务器上,那么 Agent 节点
也会更新成错误的文件,而 Web 站点将会出现故障。所以将 SVN 服务器、Puppet
Master 服务器、发布服务器建议全部单独分开,只要保证发布服务器上的代码不会更
新错误的文件,Web 站点也就不会自动更新。因此,就不能用 Puppet Master 作为文
件服务器,而是以发布服务器作为文件服务器,所以需要用到 Puppet 的 rsync 模块。
4.3.2 案例前置知识点
自动部署工作流程如图 4.3 所示。
图 4.3 自动部署工作流程
开发人员手工提交更新代码到 SVN 服务器上。
开发人员使用系统账号登录到发布服务器上,手工执行与发版相对应的项目脚本。
也就是从 SVN 服务器上检出要更新的代码到发布机上。
待脚本执行完后,Web 测试环境的应用会根据自身设置的时间自动更新或者更新
后执行一些其它动作。这里暂定五分钟。
开发人员和测试人员进行相关测试。
如果测试环境通过测试,需要发布正式环境的话,请开发人员邮件或者电话通知
运维人员要发版的项目。
同样运维人员也是手工执行与发版相对应的项目脚本(正式环境发布脚本),发
布完成后五分钟左右通知开发人员发布结束。
4.3.3 案例环境
1. 本案例实验环境
本案例主要演示项目版本自动部署,这里使用五台服务器,五台服务器均采用
CentOS 7.3 系统版本,要求能上互联网,Selinux 和防火墙均已关闭。服务器具体信
息如表 4-2 所示。
表 4-2 服务器具体配置信息
角色 | 主机名 | IP 地址 | 用途 |
master | master.puppet.com | 192.168.0.111 | 控制端 |
client | web.puppet.com | 192.168.0.112 | 正式节点 |
client | web-test.puppet.com | 192.168.0.113 | 测试节点 |
release | release.puppet.com | 192.168.0.114 | 时间同步,发布机 |
svn | svn.puppet.com | 192.168.0.115 | 版本控制 |
确保发布服务器到另外四台服务器网络都是相通的。同时确保所有服务器的时间
都同步。本案例的自动部署网络环境比较适合于公司内部机房有一条 SDH 专线连到
IDC 机房,而不是通过互联网去部署,因为这样相当于在局域网内执行动作,速度和
安全性都是比较可靠的。SVN 服务器、发布服务器、Puppet Master 都在公司内部,
Web 正式节点和 Web 测试节点都在 IDC 机房中。所以说自动部署也在很大程度上依
赖网络环境。
2. 案例需求
使用 Puppet 进行项目版本发布。
3. 案例实现思路
(1)准备工作;
(2)安装 Puppet 软件;
(3)安装配置 SVN 服务器;
(4)配置 Puppet 服务端和客户端;
(5)Puppet 部署发布服务器;
(6)发布测试和正式应用。
4.4 案例二实施
1. 准备工作
(1)添加域名解析
需要修改 Puppet Master、发布服务器、Web 正式节点、Web 测试节点、SVN
服务器的 hosts 文件,因为 Puppet 都是基于域名的方式来管理节点。如果 IDC 机房
内部有 DNS 管理更好,因为以后更多的项目都会自动部署。以 master.puppet.com主机为例,五台服务器都增加如下解析:
[root@master ~]# cat << EOF >> /etc/hosts
192.168.0.111 master.puppet.com
192.168.0.112 web.puppet.com
192.168.0.113 web-test.puppet.com
192.168.0.114 ntp.puppet.com release.puppet.com
192.168.0.115 svn.puppet.com
EOF
(2)同步时间
五台服务器都需要进行时间同步操作,下面以 master.puppet.com 主机为例进行
演示。
[root@master ~]# ntpdate ntp.puppet.com
14 Jun 16:02:59 ntpdate[19748]: adjust time server 192.168.0.114 offset 0.001015 sec
2. 安装 Puppet
在 Puppet Master、发布服务器、Web 正式节点和 Web 测试节点都需要安装
Puppet 源。Puppet Master 需要安装 puppet-server 包,而发布服务器、Web 正式节
点和 Web 测试节点都被看作是 Puppet 的被管理节点,即通常所说的 Agent 端。在
场景一中,Puppet Master 节点已经安装了 puppet-server 包,可执行以下命令确认。
[root@master ~]# systemctl status puppetmaster
● puppetmaster.service - Puppet master
Loaded: loaded (/usr/lib/systemd/system/puppetmaster.service; enabled; vendor preset:
disabled)
Active: active (running) since 日 2020-07-19 19:00:15 CST; 42min ago
Main PID: 12300 (puppet)
CGroup: /system.slice/puppetmaster.service
└─12300 /usr/bin/ruby /usr/bin/puppet master --no-daemonize
......
//省略部分内容
[root@master ~]# netstat -antpu |grep 8140
tcp
0
0 0.0.0.0:8140
0.0.0.0:*
LISTEN
18686/ruby
Web 正式节点和 Web 测试节点在场景一中都已经安装了 Puppet,下面只是演示
在发布机上进行安装 Puppet。进行安装 Puppet 操作之前,需要提前上传下载好的
puppetlabs 源的 rpm 包。
[root@release ~]# rpm -ivh puppetlabs-release-7-12.noarch.rpm
[root@release ~]# yum install -y puppet
3. 安装配置 SVN 服务器
在 svn.puppet.com 服务器上,安装并配置 SVN 服务。
[root@svn ~]# yum install -y subversion
//在 svn.puppet.com 服务器上安装 SVN 服务
[root@svn ~]# mkdir -p /var/svn/html
//创建目录
[root@svn ~]# svnadmin create /var/svn/html/
//创建版本库
[root@svn ~]# ls /var/svn/html/
//查看生成文件
conf db format hooks locks README.txt
[root@svn ~]# vim /var/svn/html/conf/svnserve.conf
//修改 svn 配置文件
anon-access = read
//匿名用户可读
auth-access = write
//授权用户可写
password-db = /var/svn/html/conf/passwd
//指定账号文件
authz-db = /var/svn/html/conf/authz
//指定权限文件
[root@svn ~]# vim /var/svn/html/conf/passwd
//设置账号密码
[users]
alpha = alphapasswd
sysadmin = sysadminpasswd
[root@svn ~]# vim /var/svn/html/conf/authz
//设置权限
[/]
sysadmin = r
alpha = rw
[web]
sysadmin = r
alpha = rw
[root@svn ~]# svnserve -d -r /var/svn/html
//启动版本库
创建测试目录并测试。
[root@svn ~]# cd /var/svn/html/
[root@svn html]# mkdir web
[root@svn html]# svn import web file:///var/svn/html/web -m "init svn"
提交后的版本为 1。
4. 配置 Puppet Agent
因为 Puppet Master 管理客户端 Agent 是基于 SSL 方式通过证书通信,所以需
要在所有的 Agent 角色上,也就是在发布服务器、Web 正式节点、Web 测试节点上
修改 Puppet 的主配置文件/etc/puppet/puppet.conf,在[main]字段中指定 Puppet 服
务端地址。因为场景一和场景二中某些主机名已经发生改变,所以都需要重新认证。
下面以发布机上为例进行演示。
[root@release ~]# vim /etc/puppet/puppet.conf
server = master.puppet.com
// Puppet Master 的地址
然后,在所有的 Agent 角色上分别执行如下命令,向 Master 发起注册请求。
[root@release ~]# puppet agent --server=master.puppet.com --verbose --no-daemonize
在 Master 进行查看申请注册的客户端,执行如下命令。
[root@master ~]# puppet cert --list
"release.puppet.com"
(SHA256)
12:A3:04:91:1D:2D:FE:83:D7:E7:F2:C7:CC:B6:CC:D4:92:B4:E8:35:42:D6:35:B6:E8:CB:71:D9:F5:
D4:69:00
"web-test.puppet.com"
(SHA256)
F6:71:F4:D1:75:9A:8A:C2:CB:DD:50:56:F7:6E:2A:1E:5C:7D:71:85:DC:D4:39:AF:69:44:D3:AE:EE:
46:2F:B1
"web.puppet.com"
(SHA256)
E2:A3:55:17:43:61:AA:CC:53:24:72:2A:23:2B:33:9A:A9:0C:E1:6A:46:91:FB:B1:C1:55:06:C5:77:10:
59:B2
在 Puppet Master 执行如下命令完成注册。
[root@master ~]# puppet cert sign release.puppet.com
//单个客户端
Notice: Signed certificate request for release.puppet.com
Notice:
Removing
file
Puppet::SSL::CertificateRequest
release.puppet.com
at
'/var/lib/puppet/ssl/ca/requests/release.puppet.com.pem'
[root@master ~]# puppet cert sign --all
//所有客户端
Notice: Signed certificate request for web.puppet.com
Notice:
Removing
file
Puppet::SSL::CertificateRequest
web.puppet.com
at
'/var/lib/puppet/ssl/ca/requests/web.puppet.com.pem'
Notice: Signed certificate request for web-test.puppet.com
Notice:
Removing
file
Puppet::SSL::CertificateRequest
web-test.puppet.com
at
'/var/lib/puppet/ssl/ca/requests/web-test.puppet.com.pem'
5. 使用 Puppet 部署发布服务器
(1)下载 concat 和 rsync 模块
在发布服务器和 Puppet Master 上需要下载安装 concat 和 rsync 模块。如果发布
服务器上没有 concat 和 rsync 模块,那么之后发布服务器上生成的 rsyncd.conf 文件
的 内 容 就 会 是 空 的 。 Puppet 对 应 concat 模 块 的 下 载 位 置 在 GitHub 位 置
https://github.com/onyxpoint/pupmod-concat,对应 rsync 模块的下载位置在 GitHub
位置 https://github.com/onyxpoint/pupmod-rsync。
这里是使用 git。如果服务器没有安装,可以先使用 yum -y install git 安装。如果
不想安装 git,也可以下载 zip 压缩包,解压到相应目录。
在发布服务器、Puppet Master 上执行如下命令。
[root@release ~]# yum install -y git
[root@release ~]# cd /etc/puppet/modules/
[root@release modules]# git clone https://github.com/onyxpoint/pupmod-concat && mv
pupmod-concat concat
正克隆到 'pupmod-concat'...remote: Enumerating objects: 116, done.
remote: Total 116 (delta 0), reused 0 (delta 0), pack-reused 116
接收对象中: 100% (116/116), 48.07 KiB | 47.00 KiB/s, done.
处理 delta 中: 100% (26/26), done.
[root@release modules]# git clone https://github.com/onyxpoint/pupmod-rsync && mv
pupmod-rsync rsync
正克隆到 'pupmod-rsync'...
remote: Enumerating objects: 36, done.
remote: Total 36 (delta 0), reused 0 (delta 0), pack-reused 36
Unpacking objects: 100% (36/36), done.
[root@release modules]# ll
总用量 0
drwxr-xr-x 5 root root 72 7 月 3 20:26 concat
drwxr-xr-x 8 root root 118 7 月 3 20:26 rsync
(2)配置 Puppet Master
Puppet Master 开始创建管理 Agent 节点目录及文件,方便以后管理。
[root@master ~]# mkdir -p /etc/puppet/manifests/nodes
[root@master ~]# vim /etc/puppet/manifests/nodes/release.puppet.com.pp
class rsync::client inherits rsync {
}
node 'release.puppet.com' {
include 'rsync::server'
rsync::server::global { 'global':
address => '192.168.0.114'
}
rsync::server::section { 'web':
comment => 'This is formal file path',
path => '/var/www/html/web',
hosts_allow => '192.168.0.112'
}
rsync::server::section { 'web_test':
comment => 'This is test file path',
path => '/var/www/html/web_test',
hosts_allow => '192.168.0.113'
}
}
(3)创建 site.pp 配置文件
在 site.pp 配置文件中定义 Puppet 相关的变量和默认配置,site.pp 是 Puppet
最先读取的文件。
[root@master ~]# vim /etc/puppet/manifests/site.pp
import "nodes/release.puppet.com.pp"
(4)自动配置发布服务器
[root@release ~]# puppet agent --server=master.puppet.com --test -v
Info: Retrieving pluginfacts
Info: Retrieving plugin
Info: Caching catalog for release.puppet.com
Info: /Stage[main]/Rsync/Tidy[/etc/rsync]: File does not exist
Info: Applying configuration version '1528969467'
Notice: /Stage[main]/Rsync/File[/etc/rsync]/ensure: created
Notice:
//省略部分
Notice: /Stage[main]/Rsync::Server/Service[rsync]/ensure: ensure changed 'stopped' to 'running'
Info: /Stage[main]/Rsync::Server/Service[rsync]: Unscheduling refresh on Service[rsync]
Notice: Finished catalog run in 8.25 seconds
查看发布服务器的/etc 目录,发现已经自动生成 rsyncd.conf 文件,但是 rsync
服务是未启动的。自动生成的/etc/rsyncd.conf 文件内容如下。
[root@release ~]# cat /etc/rsyncd.conf
pid file = /var/run/rsyncd.pid
syslog facility = daemon
port = 873
address = 192.168.0.114
[web]
comment = This is formal file path
path = /var/www/html/web
use chroot = false
max connections = 0
max verbosity = 1
lock file = /var/run/rsyncd.lock
read only = true
write only = false
list = false
uid = root
gid = root
outgoing chmod = o-w
ignore nonreadable = true
transfer logging = true
log format = "%o %h [%a] %m (%u) %f %l"
dont compress = *.gz *.tgz *.zip *.z *.rpm *.deb *.iso *.bz2 *.tbz *.rar *.jar *.pdf *.sar *.war
hosts allow = 192.168.0.112
hosts deny = *
[web_test]
comment = This is test file path
path = /var/www/html/web_test
use chroot = false
max connections = 0
max verbosity = 1
lock file = /var/run/rsyncd.lock
read only = true
write only = false
list = false
uid = root
gid = root
outgoing chmod = o-w
ignore nonreadable = true
transfer logging = true
log format = "%o %h [%a] %m (%u) %f %l"
dont compress = *.gz *.tgz *.zip *.z *.rpm *.deb *.iso *.bz2 *.tbz *.rar *.jar *.pdf *.sar *.war
hosts allow = 192.168.0.113
hosts deny = *
(5)启动 rsync 服务
在发布服务器上手动启动 rsync 服务。
[root@release ~]# rsync --daemon
查看 873 端口是否开启。如果发布机上开启防火墙,记得打开 873 端口。
[root@release ~]# netstat -an | grep 873
tcp
0
0 192.168.0.114:873
0.0.0.0:*
LISTEN
如果希望下次发布服务器能自动启动 rsync 服务,那么需要修改 Puppet Master
的 rsync 模块文件,将/etc/puppet/modules/rsync/manifests/server.pp 文件中的如下
行注释掉。
stop => "/bin/kill `cat \\`grep \"pid file\" /etc/rsyncd.conf | cut -f4 -d' '\\``",
新增如下所示:
stop => "/bin/kill `ps -ef | grep rsync | grep -v grep | awk '{print $2}'`",
6. 版本发布
在上面搭建 SVN 服务器的时候只设置了一个版本库,但是目录里面实际是空的,
为了模拟真实性,上传一个本地文件到 svn 版本库,然后通过发布脚本将这个文件发
布到测试站点。
(1)从 SVN 服务器检出项目,检出的时候需要输入 SVN 服务器密码,然后输入
svn 用户和密码。
[root@release ~]# svn co svn://svn.puppet.com/web
[root@release ~]# cd web
从本地拷贝一个文件到 SVN 版本库。
[root@release web]# cp /root/anaconda-ks.cfg .
添加文件到 SVN 版本库,删除文件是使用 delete 参数。
[root@release web]# svn add anaconda-ks.cfg
A
anaconda-ks.cfg
提交到版本库,ci 是 commit 的简写。
[root@release web]# svn ci -m "add file"
正在增加
anaconda-ks.cfg
传输文件数据.
提交后的版本为 2。
(2)编写 SVN 发布测试站点脚本
[root@release ~]# vim webtest.sh
#web 测试环境版本发布工具#!/bin/bash
#定义路径
path=$(cd $(dirname "$0");pwd);
svnRoot="svn://svn.puppet.com/web";
svndir="/var/svn/html/web_test";
webdir="/var/www/html/web_test";
choose="no yes"
echo "请确认要发布的是 web 项目测试环境";
select comfirm in $choose
do
if [ "${comfirm}" != "yes" ];then
echo "发布程序结束"
exit 0;
fi
break;
done;
echo "请确认 SVN 地址(默认 no):${svnRoot}";
select comfirm in $choose
do
if [ "${comfirm}" != "yes" ];then
echo "发布程序结束"
exit 0;
fi
break;
done;
#开始检出程序代码
svn co ${svnRoot}
${svndir};
rsync -acvz --exclude=".svn/" --delete --delete-after ${svndir}/ ${webdir}
当然脚本里面还可以增加其它的预设动作,根据不同的业务逻辑进行修改。
执行脚本之前需要在发布服务器上创建需要的目录。
[root@release ~]# mkdir -p /var/svn/html/web_test
[root@release ~]# mkdir -p /var/www/html/web_test
(3)配置 Web 测试站点客户端
在 Puppet Master 上定义客户端模板文件。因为下载的 rsync 模块不带--delete
参数,但是在实际环境中完全同步代码的时候需要用到这个参数。
[root@master ~]# mkdir /etc/puppet/modules/rsync/manifests/client
[root@master ~]# vim /etc/puppet/modules/rsync/manifests/client/host.pp
//添加如下内容
define rsync::client::host ($title,$rsyserver,$source,$target){
exec{"$title":
path => "/usr/bin:",
command => "rsync -acvz --delete $rsyserver::$source $target"
}
}
上述参数含义:
title:定义的一个主题,可以任意定义。
rsyserver:是 rsync server 的 IP。
source:是 rsync server 上定义的目录。
target:是网站测试节点上放置的目录。
(4)创建测试站点文件
[root@master ~]# vim /etc/puppet/manifests/nodes/web-test.puppet.com.pp
node 'web-test.puppet.com' {
include 'rsync::client'
rsync::client::host {"web 项目测试环境":
title => 'web 项目测试环境',
source =>'web_test',
rsyserver => 'release.puppet.com',
target =>'/var/www/html/web_test'
}
}
上述内容很少,因为完全就是调用 rsync 命令复制文件。当然,里面也可以增加
同 步 完 后 的 一 些 预 设 动 作 , 比 如 exec 执 行 外 部 脚 本 之 类 的 。 最 后 , 需 要 将
web-test.puppet.com 文件也导入到 site.pp 文件里面。
[root@master
~]#
echo
"import
'nodes/web-test.puppet.com.pp'
">>
/etc/puppet/manifests/site.pp
(5)手动测试
手动运行上面创建的发布脚本 webtest.sh。
[root@release ~]# sh webtest.sh
请确认要发布的是 web 项目测试环境
1) no
2) yes
#? 2
请确认 SVN 地址(默认 no):svn://svn.puppet.com/web
1) no
2) yes
#? 2
A
/var/svn/html/web_test/anaconda-ks.cfg
取出版本 2。
Building file list ... done
anaconda-ks.cfg
sent 785 bytes received 34 bytes 1,638.00 bytes/sec
total size is 1,260 speedup is 1.54
查看文件是否已经检出到发布机。
[root@release ~]# ll /var/svn/html/web_test/
总用量 4
-rw-r--r-- 1 root root 1261 7 月 3 21:25 anaconda-ks.cfg
在 Web 项目测试站点上创建同步目录,然后执行如下命令确认发布服务器上的
更新文件是否被同步到 Web 项目测试站点。
[root@web-test ~]# mkdir -p /var/www/html/web_test
[root@web-test ~]# puppet agent --server master.puppet.com --test --debug
//省略部分
Notice: /Stage[main]/Rsync/Tidy[/etc/rsync]: Tidying File[/etc/rsync]
Info: Applying configuration version ‘1529027298’
Debug: Exec[web 项 目 测 试 环 境 ](provider=posix): Executing ‘rsync -acvz —delete
192.168.0.114::web_test /var/www/html/web_test’
Debug: Executing ‘rsync -acvz —delete 192.168.0.114::web_test /var/www/html/web_test’
Notice: /Stage[main]/Main/Node[web-test.puppet.com]/Rsync::Client::Host[web 项 目 测 试 环
境]/Exec[web 项目测试环境]/returns: executed successfully
//省略部分
在 Web 测试节点查看文件是否被同步。
[root@web-test ~]# ll /var/www/html/web_test/
总用量 4
-rw-r--r-- 1 root root 1261 7 月 3 21:25 anaconda-ks.cfg
再测试一下上面添加的 host.pp 是否可用,首先从 svn 删除 anaconda-ks.cfg,
然后重新上传一个文件进行测试。
[root@release ~]# cd web
[root@release web]# svn delete anaconda-ks.cfg
D
anaconda-ks.cfg
[root@release web]# svn ci -m "delete file"
正在删除
anaconda-ks.cfg
提交后的版本为 3。
[root@release web]# cp /root/webtest.sh .
[root@release web]# svn add webtest.sh
A
webtest.sh
[root@release web]# svn ci -m "add new file"
正在增加
webtest.sh
传输文件数据.
提交后的版本为 4。
运行发布脚本
[root@release ~]# sh webtest.sh
Web 测试节点手动同步。
[root@web-test ~]# puppet agent --server master.puppet.com --test
Notice: Ignoring —listen on onetime run
Info: Retrieving pluginfacts
Info: Retrieving plugin
Info: Caching catalog for web-test.puppet.com
Notice: /Stage[main]/Rsync/Tidy[/etc/rsync]: Tidying File[/etc/rsync]
Info: Applying configuration version ‘1529027298’
Notice: /Stage[main]/Main/Node[web-test.puppet.com]/Rsync::Client::Host[web 项 目 测 试 环
境]/Exec[web 项目测试环境]/returns: executed successfully
Notice: Finished catalog run in 1.53 seconds
在 Web 测试节点查看,发现文件旧文件已经删除,新文件已经同步。
[root@web-test ~]# ll /var/www/html/web_test/
总用量 4
-rw-r--r-- 1 root root 784 7 月 3 21:31 webtest.sh
(6)设置正式节点自动部署
上述都是手动执行拉取动作,而本案例的目的是自动部署,所以需要配置正式节
点的 Agent 自动更新应用。
① 修改 Agent 自动更新
在正式环境上的 Agent 客户端的/etc/puppet/puppet.conf 配置文件中的[agent]字
段中增加如下内容。
[root@web ~]# vim /etc/puppet/puppet.conf
listen = true
runinterval = 300s
//表示 5 分钟自动更新
[root@web ~]# systemctl restart puppetagent
至于发布服务器上为了防止 rsync 进行消失,也可以采用一小时自动拉取一次。
具体时间根据需求而定。
② 编写正式发布脚本,其实原理就是把发布机上的/var/www/html/web_test 目录
下的文件拷贝到/var/www/html/web 目录下。
[root@release ~]# vim web.sh
#!/bin/bash
#设置根目录
SOURCE_ROOT='/var/www/html';
SHELL_ROOT=$(cd $(dirname "$0"); pwd);
#设置源码目录
SOURCE_WEB="${SOURCE_ROOT}/web";
SOURCE_WEB_TEST="${SOURCE_ROOT}/web_test";
choose="no yes"echo "请确认要发布的是 web 项目正式环境?(该脚本只能由运维人员执行)";
select comfirm in $choose
do
if [ "${comfirm}" != "yes" ]; then
echo "发布程序结束";
exit 0;
fi
break;
done;
echo "请确认是否同步正式环境?请务必确认目录正确性!";
select COMFIRM in '否' '是'
do
if [ "${COMFIRM}" == "是" ]; then
echo '同步源码目录';
rsync -avr --delete-after ${SOURCE_WEB_TEST}/ ${SOURCE_WEB};
fi
break;
done;
echo 'web 项目正式环境发布完成,请通知相关开发和测试人员五分钟后进行测试!'
手动运行发布正式节点脚本。
[root@release ~]# sh web.sh
请确认要发布的是 web 项目正式环境?(该脚本只能由运维人员执行)
1) no
2) yes
#? 2
请确认是否同步正式环境?请务必确认目录正确性!
1) 否
2) 是
#? 2
同步源码目录
building file list ... done
created directory /var/www/html/web
./
webtest.sh
sent 939 bytes received 96 bytes 2,070.00 bytes/sec
total size is 769 speedup is 0.74
web 项目正式环境发布完成,请通知相关开发和测试人员五分钟后进行测试!
查看发布机的正式目录文件是否同步。
[root@release ~]# ll /var/www/html/web/
总用量 4
-rw-r--r-- 1 root root 769 6 月 15 10:37 webtest.sh
③ 创建正式节点文件
[root@master ~]# vim /etc/puppet/manifests/nodes/web.puppet.com.pp
node 'web.puppet.com' {
include 'rsync::client'
rsync::client::host {"web 项目正式环境":
title => 'web 项目正式环境',
source =>'web',
rsyserver => 'release.puppet.com',
target =>'/var/www/html/web'
}
}
同样还需要将 web.puppet.com.pp 文件 import 到 site.pp 文件里面。
[root@master ~]# echo "import 'nodes/web.puppet.com.pp'">>/etc/puppet/manifests/site.pp
重启 Puppet Master 服务。
[root@master ~]# systemctl restart puppetmaster
在正式节点创建同步目录。
[root@web ~]# mkdir -p /var/www/html/web
接下来,就是耐心得等待 5 分钟后进行查看文件已经同步。
[root@web ~]# ll /var/www/html/web/
总用量 0
[root@web ~]# ll /var/www/html/web/
总用量 4
-rw-r--r-- 1 root root 784 7 月 3 21:31 webtest.sh
至此,项目就自动化部署完成了。