注意:本教程的较新版本,它使用 Puppet Server 而不是 Puppet with Passenger,可以在这里找到:如何在 Ubuntu 14.04 上的 Master-Agent 设置中安装 Puppet 4 .
介绍
Puppet Labs 的 Puppet 是一种配置管理工具,可帮助系统管理员自动执行服务器基础架构的供应、配置和管理。 提前计划并使用 Puppet 等配置管理工具可以减少重复基本任务所花费的时间,并有助于确保您的配置在整个基础架构中保持一致和准确。 一旦掌握了使用 Puppet 和其他自动化工具管理服务器的窍门,您将腾出时间来改进整体设置的其他方面。
Puppet 有两个品种,Puppet Enterprise 和开源 Puppet。 它可以在大多数 Linux 发行版、各种 UNIX 平台和 Windows 上运行。
在本教程中,我们将介绍如何在代理/主设置中安装开源 Puppet。 此设置由一个中央 Puppet Master 服务器组成,您的所有配置数据都将从该服务器进行管理和分发,您所有剩余的服务器将是 Puppet Agent 节点,可以配置由傀儡主服务器。
先决条件
要学习本教程,您必须对要配置 Puppet 的所有服务器具有 root 访问权限。 您还需要创建一个新的 Ubuntu 14.04 VPS 来充当 Puppet 主服务器。 如果您没有现有的基础架构,请随时按照先决条件 DNS 设置教程重新创建示例基础架构(如下所述)。
在我们开始安装 Puppet 之前,请确保您具有以下先决条件:
- 私网DNS:正向和反向DNS必须配置,每台服务器必须有唯一的主机名。 这里有一个配置你自己的私网DNS服务器的教程。 如果您没有配置 DNS,则必须使用
hosts
文件进行名称解析。 我们将假设您将使用您的专用网络在您的基础设施内进行通信。 - 防火墙开放端口: Puppet master 必须在端口 8140 上可访问。 如果您的防火墙过于严格,请查看此 UFW 教程 ,了解如何允许端口 8140 上的传入请求。
示例基础架构
我们将使用以下基础设施来演示如何设置 Puppet:
主机名 | 角色 | 私有 FQDN |
---|---|---|
主机1 | 通用 Ubuntu 14.04 VPS | host1.nyc2.example.com |
主机2 | 通用 Ubuntu 14.04 VPS | host2.nyc2.example.com |
ns1 | 主域名服务器 | ns1.nyc2.example.com |
ns2 | 辅助域名服务器 | ns2.nyc2.example.com |
puppet 代理将安装在所有这些主机上。 这些主机将由其专用网络接口引用,这些接口映射到 DNS 中的“.nyc2.example.com”子域。 这与先决条件教程中描述的基础架构相同:如何在 Ubuntu 14.04 上将 BIND 配置为专用网络 DNS 服务器。
具备所有先决条件后,让我们继续创建 Puppet 主服务器!
创建 Puppet Master 服务器
创建一个新的 Ubuntu 14.04 x64 VPS,使用“puppet”作为其主机名。 使用以下详细信息将其专用网络添加到您的 DNS:
主机名 | 角色 | 私有 FQDN |
---|---|---|
木偶 | 木偶大师 | puppet.nyc2.example.com |
如果您刚刚设置 DNS 并且不确定如何将主机添加到 DNS,请参阅 DNS 教程的 维护 DNS 记录 部分。 本质上,您需要添加“A”和“PTR”记录,并允许新主机执行递归查询。 此外,请确保您配置了搜索域,以便您的服务器可以使用短主机名相互查找。
使用“puppet”作为 Puppet master 的主机名可以稍微简化代理设置,因为它是代理在尝试连接到 master 时将使用的默认名称。
现在我们需要设置 NTP。
安装 NTP
因为它充当代理节点的证书颁发机构,所以 puppet 主服务器必须保持准确的系统时间,以避免在颁发代理证书时出现潜在问题——如果存在时间差异,证书可能会过期。 为此,我们将使用网络时间协议 (NTP)。
首先,使用 ntpdate
命令进行一次时间同步:
sudo ntpdate pool.ntp.org
您的系统时间将会更新,但您需要安装 NTP 守护程序以自动更新时间,以尽量减少时间漂移。 使用以下 apt 命令安装它:
sudo apt-get update && sudo apt-get -y install ntp
通常的做法是更新 NTP 配置以使用地理位置更接近 NTP 服务器的“池区域”。 在 Web 浏览器中,转到 NTP 池项目 并查找地理位置靠近您正在使用的数据中心的 池区 。 在我们的示例中,我们将使用美国池(http://www.pool.ntp.org/zone/us),因为服务器位于纽约数据中心。
打开ntp.conf
进行编辑:
sudo vi /etc/ntp.conf
将 NTP 池项目页面中的时间服务器添加到文件顶部:
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 service ntp restart
现在我们的服务器保持准确的时间,让我们安装 Puppet Master 软件。
安装木偶大师
有多种方法可以安装开源 Puppet。 我们将使用由 Puppet Labs 提供的名为 puppetmaster-passenger 的 debian 软件包。 puppetmaster-passenger 包包括 Puppet master 和生产就绪的 Web 服务器(Passenger with Apache),与使用基本的 puppetmaster 包相比,它消除了一些配置步骤。
下载 Puppet Labs 软件包:
cd ~; wget https://apt.puppetlabs.com/puppetlabs-release-trusty.deb
安装包:
sudo dpkg -i puppetlabs-release-trusty.deb
更新 apt 的可用软件包列表:
sudo apt-get update
安装 puppetmaster-passenger
包:
sudo apt-get install puppetmaster-passenger
现在安装了 Puppet master、Passenger、Apache 和其他所需的软件包。 因为我们在Apache中使用Passenger,所以Puppet master进程是由Apache控制的,即 它在 Apache 运行时运行。
在继续之前,通过停止 apache2
服务来停止 Puppet Master:
sudo service apache2 stop
接下来,我们要锁定 Puppet 的版本。
锁定版本
版本之间的更改有时会导致您的 Puppet 环境停止正常工作。 因此,您需要在整个基础架构中维护一致的 Puppet 版本。 如果您决定升级到较新版本,请确保在任何代理节点之前升级您的 master,因为 master 无法管理具有更高版本号的代理。
让我们使用以下命令查看 Puppet 安装的版本:
puppet help | tail -n 1
在撰写本文时,上一条命令的输出为 Puppet v3.6.2
。 我们可以使用 apt 的 pin 功能将我们的 Puppet 安装锁定到 3.6.*
,这将阻止 apt 将 Puppet 升级到更高的主要版本。 在 apt 首选项目录中创建一个名为的新文件:
sudo vi /etc/apt/preferences.d/00-puppet.pref
添加以下行以将 puppet
、puppet-common
和 puppetmaster-passenger
包锁定到 3.6.*
(更改此以匹配您安装的版本):
# /etc/apt/preferences.d/00-puppet.pref Package: puppet puppet-common puppetmaster-passenger Pin: version 3.6* Pin-Priority: 501
保存并退出。 您的 Puppet 版本现已锁定。
下一步是设置您的 Puppet 主名称和证书。
设置名称和证书
Puppet 使用 SSL 证书来验证主节点和代理节点之间的通信。 Puppet master 充当证书颁发机构 (CA),并且必须生成自己的证书,用于签署代理证书请求。 我们现在将设置主人的证书。
删除现有证书
删除在软件包安装期间创建的任何现有 SSL 证书。 Puppet 的 SSL 证书的默认位置是 /var/lib/puppet/ssl
:
sudo rm -rf /var/lib/puppet/ssl
配置证书
创建 puppet master 的证书时,包括代理节点可以联系 master 的每个 DNS 名称。 在我们的示例中,我们将分别使用“puppet”和“puppet.nyc2.example.com”,即短主机名和 FQDN。
编辑 master 的 puppet.conf 文件:
sudo vi /etc/puppet/puppet.conf
它将如下所示:
[main] logdir=/var/log/puppet vardir=/var/lib/puppet ssldir=/var/lib/puppet/ssl rundir=/var/run/puppet factpath=$vardir/lib/facter templatedir=$confdir/templates [master] # These are needed when the puppetmaster is run by passenger # and can safely be removed if webrick is used. ssl_client_header = SSL_CLIENT_S_DN ssl_client_verify_header = SSL_CLIENT_VERIFY
删除带有 templatedir
选项的行,因为该选项已被弃用。
将以下两行添加到 [main]
部分的末尾(将突出显示的文本替换为私有 FQDN):
certname = puppet dns_alt_names = puppet,puppet.nyc2.example.com
将 certname
分配给“puppet”很重要,因为 Apache/Passenger 配置要求证书命名为“puppet”。 如果您决定需要不同的 certname
设置,请务必编辑 Apache 配置文件 (/etc/apache2/sites-available/puppetmaster.conf
) 以更改 SSL 证书路径的名称。
保存并退出。
生成新证书
现在通过运行以下命令创建新的 CA 证书:
sudo puppet master --verbose --no-daemonize
您将看到几行输出表明正在创建 SSL 密钥和证书。 看到 Notice: Starting Puppet master version 3.6.2
后,证书设置完成。 按 CTRL-C
返回外壳。
样本输出:
Info: Creating a new SSL key for ca Info: Creating a new SSL certificate request for ca Info: Certificate Request fingerprint (SHA256): EC:7D:ED:15:DE:E3:F1:49:1A:1B:9C:D8:04:F5:46:EF:B4:33:91:91:B6:5D:19:AC:21:D6:40:46:4A:50:5A:29 Notice: Signed certificate request for ca ... Notice: Signed certificate request for puppet Notice: Removing file Puppet::SSL::CertificateRequest puppet at '/var/lib/puppet/ssl/ca/requests/puppet.pem' Notice: Removing file Puppet::SSL::CertificateRequest puppet at '/var/lib/puppet/ssl/certificate_requests/puppet.pem' Notice: Starting Puppet master version 3.6.2
如果要查看刚刚创建的证书的证书信息,请输入以下内容:
sudo puppet cert list -all
前面的命令实际上列出了所有签名证书和未签名证书请求。 目前,只会显示主证书,因为尚未添加其他证书:
+ "puppet" (SHA256) 05:22:F7:65:64:CF:46:0E:09:2C:5D:FD:8C:AC:9B:31:17:2B:7B:05:93:D5:D1:01:52:72:E6:DF:84:A0:07:37 (alt names: "DNS:puppet", "DNS:puppet.nyc2.example.com")
我们的 Puppet master 服务几乎可以启动了。 我们先来看看master的配置。
配置人偶大师
主 puppet 配置文件 puppet.conf
由三个部分组成:[main]
、[master]
和 [agent]
。 正如您可能已经猜到的那样,“main”部分包含全局配置,“master”部分特定于 puppet master,“agent”用于配置 puppet 代理。 除了我们之前所做的更改之外,默认设置对于基本设置也适用。
配置文件有许多可能与您自己的设置相关的选项。 Puppet Labs 提供了该文件的完整描述:Main Config File (puppet.conf)。
如果要编辑它,请运行以下命令:
sudo vi /etc/puppet/puppet.conf
让我们看一下主要的清单文件。
主要清单文件
Puppet 使用特定领域的语言来描述系统配置,这些描述被保存到名为“manifests”的文件中,文件扩展名为 .pp
。 默认的主清单文件位于 /etc/puppet/manifests/site.pp
。 稍后我们将介绍一些基本的清单,但我们现在将创建一个占位符文件:
sudo touch /etc/puppet/manifests/site.pp
启动木偶大师
我们现在准备启动 Puppet master。 通过运行 apache2
服务启动它:
sudo service apache2 start
您的 Puppet master 正在运行,但尚未管理任何代理节点。 让我们学习如何安装和添加 Puppet 代理!
安装 Puppet 代理
Puppet 代理必须安装在 Puppet Master 将管理的任何服务器上。 在大多数情况下,这包括基础架构中的每台服务器。 正如介绍中提到的,Puppet 代理可以在所有主要的 Linux 发行版、一些 UNIX 平台和 Windows 上运行。 由于每个操作系统的安装略有不同,我们将仅介绍 Ubuntu 和 Debian 服务器上的安装。
在其他平台上安装 Puppet 的说明位于 Puppet Labs Docs - 请务必按照您选择的操作系统的“在代理节点上安装 Puppet”部分。
注意: 假设您的所有 Puppet 节点(包括代理节点)都配置为使用您的 DNS。 如果您正在创建一个全新的服务器,请确保在安装 Puppet 代理之前 将其添加到您的 DNS。
Ubuntu / Debian 代理节点
注意:我们所有的示例代理节点,host1、host2、ns1和ns2都是Ubuntu 14.04 VPS。 我们将为每个服务器重复此步骤,因此每个服务器都可以由 Puppet Master 管理。
在您的 Puppet 代理节点上,下载 Puppet Labs 软件包:
cd ~; wget https://apt.puppetlabs.com/puppetlabs-release-trusty.deb
安装包:
sudo dpkg -i puppetlabs-release-trusty.deb
更新 apt 的可用软件包列表:
sudo apt-get update
安装 Puppet 代理包(puppet
):
sudo apt-get install puppet
默认情况下禁用 puppet 代理。 要更改此设置,请更新其默认文件:
sudo vi /etc/default/puppet
并将 START
的值更改为“yes”:
START=yes
保存并退出/etc/default/puppet
。
锁定版本
与 Puppet master 一样,我们将希望使用 apt pin 功能来锁定 Puppet 代理的版本:
sudo vi /etc/apt/preferences.d/00-puppet.pref
添加以下行以将 puppet
和 puppet-common
包锁定到 3.6.*
(更改它以匹配您安装的版本):
# /etc/apt/preferences.d/00-puppet.pref Package: puppet puppet-common Pin: version 3.6* Pin-Priority: 501
保存并退出。 您的 Puppet 版本现已锁定。
配置代理
在运行代理之前,我们必须进行一些配置更改。
编辑代理的puppet.conf
:
sudo vi /etc/puppet/puppet.conf
它看起来与 Puppet Master 的初始配置文件完全相同。
再次删除 templatedir
行。 然后删除 [master]
部分,以及它下面的所有行。
假设在“puppet”处可以访问 Puppet master,代理应该能够连接到 master。 如果主服务器在“puppet”上不可用,您将需要添加 Puppet 主服务器的 FQDN。 无论如何,我们建议配置此(用您自己的 FQDN 替换):
[agent] server = puppet.nyc2.example.com
保存并退出。
Puppet 代理已准备好运行。 通过运行以下命令来执行此操作:
sudo service puppet start
如果一切配置正确,您应该看不到任何输出。 第一次运行 Puppet 代理时,它会生成 SSL 证书并向 Puppet Master 发送签名请求。 在 Puppet Master 签署代理的证书后,它将能够与代理节点进行通信。
注意:如果这是您的第一个 Puppet 代理,建议您在添加其他代理之前尝试在 Puppet Master 上签署证书。 一旦您确认一切正常,您就可以放心地返回并添加剩余的代理节点。
在 Master 上签名请求
Puppet 第一次在代理节点上运行时,它将向 Puppet Master 发送证书签名请求。 在主节点能够通信和控制代理节点之前,它必须签署该特定代理节点的证书。 我们将描述如何签名和检查签名请求。
列出当前的证书请求
在 Puppet Master 上,运行以下命令列出所有未签名的证书请求:
sudo puppet cert list
如果您只是设置了第一个代理节点,您将看到一个请求。 它将如下所示,以代理节点的 FQDN 作为主机名:
"host1.nyc2.example.com" (SHA256) B1:96:ED:1F:F7:1E:40:53:C1:D4:1B:3C:75:F4:7C:0B:A9:4C:1B:5D:95:2B:79:C0:08:DD:2B:F4:4A:36:EE:E3
注意前面没有+
。 这表明它还没有被签署。
签署请求
要签署证书请求,请使用 puppet cert sign
命令以及要签署的证书的主机名。 例如,要签署 host1.nyc2.example.com
,您可以使用以下命令:
sudo puppet cert sign host1.nyc2.example.com
您将看到以下输出,表明证书请求已被签名:
Notice: Signed certificate request for host1.nyc2.example.com Notice: Removing file Puppet::SSL::CertificateRequest host1.nyc2.example.com at '/var/lib/puppet/ssl/ca/requests/host1.nyc2.example.com.pem'
Puppet master 现在可以通信和控制签名证书所属的节点。
如果要签署所有当前请求,请使用 -all
选项,如下所示:
sudo puppet cert sign --all
吊销证书
您可能希望从 Puppet 中删除主机,或者重建主机然后将其添加回 Puppet。 在这种情况下,您需要从 Puppet Master 吊销主机证书。 为此,您需要使用 clean
操作:
sudo puppet cert clean hostname
指定主机的关联证书将从 Puppet 中删除。
查看所有已签名的请求
如果要查看所有已签名和未签名的请求,请运行以下命令:
sudo puppet cert list --all
您将看到所有请求的列表。 签名请求前面有 +
,未签名请求没有 +
。
"ns2.nyc2.example.com" (SHA256) E4:F5:26:EB:B1:99:1F:9D:6C:B5:4B:BF:86:14:40:23:E0:50:3F:C1:45:D0:B5:F0:68:6E:B2:0F:41:C7:BA:76 + "host1.nyc2.example.com" (SHA256) 71:A2:D3:82:15:0D:80:20:D4:7E:E3:42:C2:35:87:83:79:2B:57:1D:D5:5A:EC:F6:8B:EE:51:69:53:EB:6B:A1 + "host2.nyc2.example.com" (SHA256) F4:79:A6:7C:27:0C:EA:8E:BC:31:66:FF:F2:01:AB:B1:35:7B:9F:5E:C8:C9:CE:82:EE:E8:2F:23:9F:0C:2B:ED + "puppet" (SHA256) 05:22:F7:65:64:CF:46:0E:09:2C:5D:FD:8C:AC:9B:31:17:2B:7B:05:93:D5:D1:01:52:72:E6:DF:84:A0:07:37 (alt names: "DNS:puppet", "DNS:puppet.nyc2.example.com")
恭喜! 您的基础设施现在已准备好由 Puppet 管理!
木偶入门
现在您的基础架构已设置为使用 Puppet 进行管理,我们将向您展示如何执行一些基本任务以帮助您入门。
如何收集事实
Puppet 使用名为 facter 的工具收集有关其每个节点的事实。 默认情况下,Facter 收集对系统配置有用的信息(例如 操作系统名称、主机名、IP 地址、SSH 密钥等)。 如果您需要其他事实来执行配置,则可以添加自定义事实。
收集到的事实在许多情况下都很有用。 例如,您可以创建 Web 服务器配置模板并自动为特定虚拟主机填写适当的 IP 地址。 或者你可以确定你的服务器的操作系统是“Ubuntu”,所以你应该运行apache2
服务而不是httpd
。 这些是基本示例,但它们应该让您了解如何使用事实。
要查看在您的代理节点上自动收集的事实列表,请运行以下命令:
facter
主要清单是如何执行的
puppet 代理定期检查 puppet master(通常每 30 分钟一次)。 在此期间,它会将关于自己的事实发送给主控,并拉取当前目录——资源的编译列表及其与代理相关的所需状态,由主清单确定。 然后代理节点将尝试进行适当的更改以实现其所需状态。 只要 Puppet Master 正在运行并与代理节点通信,这个循环就会继续。
在特定代理节点上立即执行
也可以通过运行以下命令(在相关代理节点上)手动启动对特定代理节点的检查:
puppet agent --test
运行它会将主清单应用于运行测试的代理。 您可能会看到如下输出:
Info: Retrieving pluginfacts Info: Retrieving plugin Info: Loading facts in /var/lib/puppet/lib/facter/pe_version.rb Info: Loading facts in /var/lib/puppet/lib/facter/puppet_vardir.rb Info: Loading facts in /var/lib/puppet/lib/facter/root_home.rb Info: Loading facts in /var/lib/puppet/lib/facter/facter_dot_d.rb Info: Caching catalog for host1.nyc2.example.com Info: Applying configuration version '1407966707'
此命令对于查看主清单将如何立即影响单个服务器很有用。
一次性清单
puppet apply
命令允许您按需执行与主清单无关的清单。 它仅将清单应用于您从中运行应用的节点。 这是一个例子:
sudo puppet apply /etc/puppet/modules/test/init.pp
如果您想在代理节点上测试新清单,或者您只想运行一次清单(例如 将代理节点初始化为所需状态)。
一个简单的清单
您可能还记得,Puppet Master 上的主清单文件位于 /etc/puppet/manifests/site.pp
。
在 master 上,现在编辑它:
sudo vi /etc/puppet/manifests/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 地址):
Here is my Public IP Address: 128.131.192.11.
指定节点
如果要为特定节点定义资源,请在清单中定义 node
。
在 master 上,编辑 site.pp
:
sudo vi /etc/puppet/manifests/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 puppet module install puppetlabs-apache
警告:不要在现有的 Apache 设置上使用此模块。 它将清除任何不受 Puppet 管理的 Apache 配置。
现在编辑 site.pp
:
sudo vi /etc/puppet/manifest/site.pp
现在添加以下行以在 host2 上安装 Apache:
node 'host2' { class { 'apache': } # use apache module apache::vhost { 'example.com': # define vhost resource port => '80', docroot => '/var/www/html' } }
保存并退出。 现在 Puppet 下次更新 host2 时,它会安装 Apache 包,并配置一个名为“example.com”的虚拟主机,监听 80 端口,文件根目录为 /var/www/html
。
在 host2 上,运行以下命令:
sudo puppet agent --test
您应该看到一堆输出表明正在安装 Apache。 完成后,转到host2的公网IP地址。 您应该会看到默认的 Apache 欢迎页面。
恭喜! 您已经使用了您的第一个 Puppet 模块!
结论
现在您已经安装了基本的代理/主 Puppet,您现在可以了解有关如何使用 Puppet 管理服务器基础架构的更多信息。 查看以下教程:木偶代码入门:清单和模块。