介绍
Puppet Labs 的 Puppet 是一种配置管理工具,可帮助系统管理员自动执行服务器基础架构的供应、配置和管理。 提前计划并使用 Puppet 等配置管理工具可以减少重复基本任务所花费的时间,并有助于确保您的配置在整个基础架构中保持一致和准确。 一旦掌握了使用 Puppet 和其他自动化工具管理服务器的窍门,您将有更多空闲时间用于改进设置的其他方面。
Puppet 有两个品种,Puppet Enterprise 和开源 Puppet。 它可以在大多数 Linux 发行版、各种 UNIX 平台和 Windows 上运行。
在本教程中,我们将介绍如何在 CentOS 7 上的代理/主设置中安装开源 Puppet 4。 在此设置中,运行 Puppet Server 软件的 Puppet master 服务器可用于控制所有其他服务器,或 Puppet 代理 节点。 请注意,我们将使用 Puppet Server 包,而不是 Passenger 或任何其他运行时环境。
先决条件
要学习本教程,您必须对要使用 Puppet 的所有服务器具有 root 或超级用户访问权限。 您还需要创建一个新的 CentOS 7 服务器来充当 Puppet 主服务器。 如果您没有现有的服务器基础架构,请按照先决条件 DNS 设置教程重新创建示例基础架构(如下所述)。
在我们开始安装 Puppet 之前,请确保您具有以下先决条件:
- 私网DNS:正向和反向DNS必须配置,每台服务器必须有唯一的主机名。 这里有一个配置你自己的私网DNS服务器的教程。 如果您没有配置 DNS,则必须使用
hosts
文件进行名称解析。 我们将假设您将使用您的专用网络在您的基础设施内进行通信。 - 防火墙开放端口: Puppet master 必须在端口 8140 上可访问。 如果您的防火墙过于严格,请查看此 FirewallD 教程 ,了解如何允许端口 8140 上的传入请求。
示例基础架构
我们将使用以下基础设施来演示如何设置 Puppet:
主机名 | 角色 | 私有 FQDN |
---|---|---|
主机1 | 通用 CentOS 7 服务器 | host1.nyc3.example.com |
主机2 | 通用 CentOS 7 服务器 | host2.nyc3.example.com |
ns1 | 主域名服务器 | ns1.nyc3.example.com |
ns2 | 辅助域名服务器 | ns2.nyc3.example.com |
puppet 代理将安装在所有这些主机上。 这些主机将由其专用网络接口引用,这些接口映射到 DNS 中的“.nyc3.example.com”子域。 这与先决条件教程中描述的基础架构相同:如何在 CentOS 7 上将 BIND 配置为专用网络 DNS 服务器。
具备所有先决条件后,让我们继续创建 Puppet 主服务器!
创建 Puppet Master 服务器
创建一个新的 CentOS 7 x64 服务器,使用“puppet”作为其主机名。 硬件要求取决于您要管理的代理节点数量; 两个 CPU 内核和 1 GB 内存是管理少数节点的 最低 要求,但如果您的服务器基础架构更大,您将需要更多资源。 Puppet Server 默认配置为使用 2 GB 的 RAM。
主机名 | 角色 | 私有 FQDN |
---|---|---|
木偶 | 木偶大师 | puppet.nyc3.example.com |
如果您刚刚设置 DNS 并且不确定如何包含新主机,请参阅 DNS 教程的 维护 DNS 记录 部分。 本质上,您需要添加“A”和“PTR”记录,并允许新主机执行递归查询。 此外,请确保您配置了搜索域,以便您的服务器可以使用短主机名相互查找。
注意: 本教程假设您的 Puppet Master 的主机名为“puppet”。 如果您使用不同的名称,则需要与本教程有所不同。 具体来说,您必须在您的 Puppet 代理节点的配置文件中指定您的 Puppet Master 的主机名,并且您必须在签署任何代理证书之前重新生成您的 Puppet Master 的 SSL 证书。 否则,您将收到此错误:Error: Could not request certificate: The certificate retrieved from the master does not match the agent's private key.
。
本教程不介绍如何配置此设置。
安装 NTP
因为它充当代理节点的证书颁发机构,所以 Puppet 主服务器必须保持准确的系统时间,以避免在颁发代理证书时出现潜在问题——如果存在时间差异,证书可能会过期。 为此,我们将使用网络时间协议 (NTP)。
首先,使用以下命令查看可用的时区:
timedatectl list-timezones
这将为您提供服务器可用的时区列表。 当您找到适合您的服务器的区域/时区设置时,请使用以下命令进行设置(替换您的首选区域和时区):
sudo timedatectl set-timezone America/New_York
使用以下命令通过 yum 安装 NTP:
sudo yum -y install ntp
使用 ntpdate
命令进行一次时间同步:
sudo ntpdate pool.ntp.org
通常的做法是更新 NTP 配置以使用地理位置更接近 NTP 服务器的“池区域”。 在 Web 浏览器中,转到 NTP 池项目 并查找地理位置靠近您正在使用的数据中心的 池区 。 在我们的示例中,我们将使用美国池 (http://www.pool.ntp.org/zone/us),因为我们的服务器位于纽约数据中心。
打开ntp.conf
进行编辑:
sudo vi /etc/ntp.conf
将 NTP 池项目页面中的时间服务器添加到文件顶部(将这些替换为您选择的服务器):
/etc/ntp.conf 摘录
server 0.us.pool.ntp.org server 1.us.pool.ntp.org server 2.us.pool.ntp.org server 3.us.pool.ntp.org
保存并退出。
启动 NTP 以添加新的时间服务器:
sudo systemctl restart ntpd
最后,启用 NTP 守护进程:
sudo systemctl enable ntpd
现在我们的服务器保持准确的时间,让我们安装 Puppet Server 软件。
安装木偶服务器
Puppet Server 是在 Puppet 主服务器上运行的软件。 它是将配置推送到您的其他服务器的组件,这些服务器将运行 Puppet 代理软件。
使用以下命令启用官方 Puppet Labs 集合存储库:
sudo rpm -ivh https://yum.puppetlabs.com/puppetlabs-release-pc1-el-7.noarch.rpm
安装 puppetserver
包:
sudo yum -y install puppetserver
Puppet Server 现在已安装在您的主服务器上,但尚未运行。
配置内存分配(可选)
默认情况下,Puppet Server 配置为使用 2 GB 的 RAM。 您应该根据您的主服务器有多少可用内存以及它将管理多少代理节点来自定义此设置。
首先,在您喜欢的文本编辑器中打开 /etc/sysconfig/puppetserver
。 我们将使用 vi
:
sudo vi /etc/sysconfig/puppetserver
然后找到JAVA_ARGS
这一行,使用-Xms
和-Xmx
参数设置内存分配。 例如,如果您想使用 3 GB 内存,则该行应如下所示:
内存分配
JAVA_ARGS="-Xms3g -Xmx3g"
完成后保存并退出。
启动人偶服务器
现在我们准备好使用以下命令启动 Puppet Server:
sudo systemctl start puppetserver
接下来,启用 Puppet Server 以便它在您的主服务器启动时启动:
sudo systemctl enable puppetserver
Puppet Server 正在运行,但尚未管理任何代理节点。 让我们学习如何安装和添加 Puppet 代理!
安装 Puppet 代理
Puppet 代理软件必须安装在 Puppet Master 将管理的任何服务器上。 在大多数情况下,这将包括基础架构中的每台服务器。 正如介绍中提到的,Puppet 代理可以在所有主要的 Linux 发行版、一些 UNIX 平台和 Windows 上运行。 由于每个操作系统的安装略有不同,我们将仅介绍 CentOS 7 服务器上的安装。 关于在 Ubuntu 14.04 服务器上安装 Puppet 代理的说明可以在 here 中找到。
在所有代理服务器上执行这些步骤。
使用以下命令启用官方 Puppet Labs 集合存储库:
sudo rpm -ivh https://yum.puppetlabs.com/puppetlabs-release-pc1-el-7.noarch.rpm
安装 puppet-agent
包:
sudo yum -y install puppet-agent
现在已经安装了 Puppet 代理,使用以下命令启动它:
sudo /opt/puppetlabs/bin/puppet resource service puppet ensure=running enable=true
第一次运行 Puppet 代理时,它会生成 SSL 证书并向 Puppet Master 发送签名请求。 在 Puppet Master 签署代理证书后,它将能够与代理节点进行通信和控制。
请记住对所有 Puppet 代理节点重复此部分。
注意: 如果这是您的第一个 Puppet 代理,建议您在添加其他代理之前尝试在 Puppet Master 上签署证书,这将在下一步中介绍。 一旦您确认一切正常,您就可以放心地返回并添加剩余的代理节点。
在 Puppet Master 上签署证书
Puppet 第一次在代理节点上运行时,它将向 Puppet Master 发送证书签名请求。 在 Puppet Server 能够与代理节点进行通信和控制之前,它必须签署该特定代理节点的证书。 我们将描述如何签名和检查签名请求。
列出当前的证书请求
在 Puppet Master 上,运行以下命令列出所有未签名的证书请求:
sudo /opt/puppetlabs/bin/puppet cert list
如果您只是设置了第一个代理节点,您将看到一个请求。 它将如下所示,带有代理节点的主机名:
Output: "host1.nyc3.example.com" (SHA256) 15:90:C2:FB:ED:69:A4:F7:B1:87:0B:BF:F7:DD:B5:1C:33:F7:76:67:F3:F6:23:AE:07:4B:F6:E3:CC:04:11:4C
注意前面没有+
。 这表明它还没有被签署。
签署请求
要签署证书请求,请使用 puppet cert sign
命令以及要签署的证书的主机名。 例如,要签署 host1.nyc3.example.com
的证书,您可以使用以下命令:
sudo /opt/puppetlabs/bin/puppet cert sign host1.nyc3.example.com
您将看到以下输出,表明证书请求已被签名:
Output:Notice: Signed certificate request for host1.nyc3.example.com Notice: Removing file Puppet::SSL::CertificateRequest host1.nyc3.example.com at '/etc/puppetlabs/puppet/ssl/ca/requests/host1.nyc3.example.com.pem'
Puppet master 现在可以通信和控制签名证书所属的节点。
如果要签署所有当前请求,请使用 --all
选项,如下所示:
sudo /opt/puppetlabs/bin/puppet cert sign --all
吊销证书
您可能希望从 Puppet 中删除主机,或者重建主机然后将其添加回 Puppet。 在这种情况下,您需要从 Puppet Master 吊销主机证书。 为此,您可以使用 clean
操作:
sudo /opt/puppetlabs/bin/puppet cert clean hostname
指定主机的关联证书将从 Puppet 中删除。
查看所有已签名的请求
如果要查看所有已签名和未签名的请求,请运行以下命令:
sudo /opt/puppetlabs/bin/puppet cert list --all
您将看到所有请求的列表。 签名请求前面有 +
,未签名请求没有 +
。
Output:+ "puppet" (SHA256) 5A:71:E6:06:D8:0F:44:4D:70:F0:BE:51:72:15:97:68:D9:67:16:41:B0:38:9A:F2:B2:6C:BB:33:7E:0F:D4:53 (alt names: "DNS:puppet", "DNS:puppet.nyc3.example.com") + "host1.nyc3.example.com" (SHA256) F5:DC:68:24:63:E6:F1:9E:C5:FE:F5:1A:90:93:DF:19:F2:28:8B:D7:BD:D2:6A:83:07:BA:FE:24:11:24:54:6A + "host2.nyc3.example.com" (SHA256) CB:CB:CA:48:E0:DF:06:6A:7D:75:E6:CB:22:BE:35:5A:9A:B3:93:63:BF:F0:DB:F2:D8:E5:A6:27:10:71:78:DA + "ns2.nyc3.example.com" (SHA256) 58:47:79:8A:56:DD:06:39:52:1F:E3:A0:F0:16:ED:8D:40:17:40:76:C2:F0:4F:F3:0D:F9:B3:64:48:2E:F1:CF
恭喜! 您的基础设施现在已准备好由 Puppet 管理!
木偶入门
现在您的基础架构已设置为使用 Puppet 进行管理,我们将向您展示如何使用 Puppet 执行一些基本任务。
如何收集事实
Puppet 使用名为 facter 的工具收集有关其每个节点的事实。 默认情况下,Facter 收集对系统配置有用的信息(例如 操作系统名称、主机名、IP 地址、SSH 密钥等)。 可以添加不属于默认事实集的自定义事实。
收集到的事实在许多情况下都很有用。 例如,您可以创建 Web 服务器配置模板并自动为特定虚拟主机填写适当的 IP 地址。 或者你可以确定你的服务器的发行版是“CentOS”,所以你应该运行apache2
服务而不是httpd
。 这些是基本示例,但它们应该让您了解如何使用事实。
要查看在您的代理节点上自动收集的事实列表,请运行以下命令:
/opt/puppetlabs/bin/facter
主要清单文件
Puppet 使用特定领域的语言来描述系统配置,这些描述被保存到名为“manifests”的文件中,文件扩展名为 .pp。 默认的主清单文件位于 在您的 Puppet 主服务器 的 /etc/puppetlabs/code/environments/production/manifests/site.pp
上。 现在让我们创建一个占位符文件:
sudo touch /etc/puppetlabs/code/environments/production/manifests/site.pp
请注意,主清单现在是空的,因此 Puppet 不会在代理节点上执行任何配置。
主要清单是如何执行的
Puppet 代理定期检查 Puppet 服务器(通常每 30 分钟一次)。 当它签入时,它会将关于自己的事实发送给主控,并拉取当前目录——资源的编译列表及其与代理相关的所需状态,由主清单确定。 然后代理节点将尝试进行适当的更改以实现其所需状态。 只要 Puppet Master 正在运行并与代理节点通信,这个循环就会继续。
在特定代理节点上立即执行
也可以通过运行以下命令(在相关代理节点上)手动启动对特定代理节点的检查:
/opt/puppetlabs/bin/puppet agent --test
运行它会将主清单应用于运行测试的代理。 您可能会看到如下输出:
Output:Info: Using configured environment 'production' Info: Retrieving pluginfacts Info: Retrieving plugin ... Info: Loading facts Info: Caching catalog for host1 Info: Applying configuration version '1457389302' Notice: /Stage[main]/Main/File[/tmp/example-ip]/ensure: defined content as '{md5}dd769ec60ea7d4f7146036670c6ac99f' Notice: Applied catalog in 0.04 seconds
此命令对于查看主清单将如何立即影响单个服务器很有用。
一次性清单
puppet apply
命令允许您按需执行与主清单无关的清单。 它仅将清单应用于您从中运行 apply 的节点。 这是一个例子:
sudo /opt/puppetlabs/bin/puppet apply /path/to/your/manifest/init.pp
如果您想在代理节点上测试新清单,或者您只想运行一次清单(例如 将代理节点初始化为所需状态)。
清单示例
您可能还记得,Puppet Master 上的主清单文件位于 /etc/puppetlabs/code/environments/production/manifests/site.pp
。
在 Puppet 主服务器上,现在编辑它:
sudo vi /etc/puppetlabs/code/environments/production/manifests/site.pp
现在添加以下行来描述文件资源:
site.pp 示例
file {'/tmp/example-ip': # resource type file and filename ensure => present, # make sure it exists mode => '0644', # file permissions content => "Here is my Public IP Address: ${ipaddress_eth0}.\n", # note the ipaddress_eth0 fact }
现在保存并退出。 内联注释应该解释我们正在定义的资源。 简而言之,这将确保所有代理节点在 /tmp/example-ip
处都有一个具有 -rw-r--r--
权限的文件,其内容包括节点的公共 IP 地址。
您可以等到代理自动与主节点签入,也可以运行 puppet agent --test
命令(从您的代理节点之一)。 然后运行以下命令打印文件:
cat /tmp/example-ip
您应该看到如下所示的输出(带有该节点的 IP 地址):
Output:Here is my Public IP Address: 128.131.192.11.
指定节点
如果要为特定节点定义资源,请在清单中定义 node
。
在 master 上,编辑 site.pp
:
sudo vi /etc/puppetlabs/code/environments/production/manifests/site.pp
现在添加以下行:
site.pp 示例
node 'ns1', 'ns2' { # applies to ns1 and ns2 nodes file {'/tmp/dns': # resource type file and filename ensure => present, # make sure it exists mode => '0644', content => "Only DNS servers get this file.\n", } } node default {} # applies to nodes that aren't explicitly defined
保存并退出。
现在 Puppet 将确保 /tmp/dns
处的文件将存在于 ns1 和 ns2 上。 如果您不想等待预定的 Puppet 代理拉取,您可能需要运行 puppet agent --test
命令(来自 ns1 或 ns2)。
请注意,如果您不定义资源,Puppet 将尽最大努力不触及它。 因此,如果您从清单中删除这些资源,Puppet 将不会删除它创建的文件。 如果要让它删除文件,请将 ensure
更改为 absent
。
这些示例没有做任何有用的事情,但它们确实证明了 Puppet 工作正常。
使用模块
现在让我们使用一个模块。 模块对于将任务组合在一起很有用。 Puppet 社区中有许多可用的模块,您甚至可以编写自己的模块。
在 Puppet master 上,从 forgeapi 安装 puppetlabs-apache
模块:
sudo /opt/puppetlabs/bin/puppet module install puppetlabs-apache
警告:不要在现有的 Apache 设置上使用此模块。 它将清除任何不受 Puppet 管理的 Apache 配置。
现在编辑 site.pp
:
sudo vi /etc/puppetlabs/code/environments/production/manifests/site.pp
现在添加以下行以在 host2 上安装 Apache:
site.pp 示例
node '<$>host2<$>' { class { 'apache': } # use apache module apache::vhost { 'example.com': # define vhost resource port => '80', docroot => '/var/www/html' } } # node default {} # uncomment this line if it doesn't already exist in your manifest
保存并退出。 现在 Puppet 下次更新 host2 时,它会安装 Apache 包,并配置一个名为“example.com”的虚拟主机,监听 80 端口,文件根目录为 /var/www/html
。
在 host2 上,运行以下命令:
sudo /opt/puppetlabs/bin/puppet agent --test
您应该看到一堆输出表明正在安装 Apache。 完成后,在 Web 浏览器中打开 host2 的公共 IP 地址。 您应该看到一个由 Apache 提供服务的页面。
恭喜! 您已经使用了您的第一个 Puppet 模块!
结论
现在您已经安装了基本的代理/主 Puppet,您现在可以了解有关如何使用 Puppet 管理服务器基础架构的更多信息。 查看以下教程:木偶代码入门:清单和模块。