使用Puppet进行服务器管理

试验环境

我们将不会管理几百台服务器,只运行两个独立的系统,分别运行puppet master和puppet agent。因此,通过主puppet服务器,我们将尝试配置远程节点,并使用puppet代理安装“hello”包。这将在尽可能少的配置下完成。

介绍

Puppet是一个开源配置管理实用程序,允许用户自动管理多个系统及其配置,如果需要,还可以远程管理多个系统及其配置。Puppet是声明性的,这意味着用户只需要请求服务或者资源的状态,而实际上并没有考虑如何实现这种状态。
换句话说,假设您是管理数百个系统的系统管理员,需要确保安装了诸如“hello”包之类的特定资源。为了以传统的系统管理方式实现这一点,管理员用户需要在实际安装包之前进行多次检查,例如包安装的当前状态、操作系统平台的类型、要使用的安装命令。作为一个声明性的puppet,用户只需要定义所需包的状态,puppet将处理其余的部分。在安装了我们的包“hello”的情况下,puppet将不采取任何操作,而如果未安装包,它将安装它。

安装和配置Pupper

让我们从安装Puppet Master的安装开始:

root@master:~# apt-get install puppetmaster-passenger

上面的命令将与Apache和乘客一起安装Puppet。因此,我们不使用典型的WEBrick服务器,而是让Apache乘客在端口'8140'上运行puppet master。默认和自动生成的Apache乘客配置文件可以位于“/etc/apache2/sites available/puppetmaster.conf”下:

# This Apache 2 virtual host config shows how to use Puppet as a Rack
# application via Passenger. See
# http://docs.puppetlabs.com/guides/passenger.html for more information.
# You can also use the included config.ru file to run Puppet with other Rack
# servers instead of Passenger.
# you probably want to tune these settings
PassengerHighPerformance on
PassengerMaxPoolSize 12
PassengerPoolIdleTime 1500
# PassengerMaxRequests 1000
PassengerStatThrottleRate 120
Listen 8140

        SSLEngine on
        SSLProtocol             ALL -SSLv2 -SSLv3
        SSLCipherSuite          EDH+CAMELLIA:EDH+aRSA:EECDH+aRSA+AESGCM:EECDH+aRSA+SHA384:EECDH+aRSA+SHA256:EECDH:+CAMELLIA256:+AES256:+CAMELLIA128:+AES128:+SSLv3:!aNULL:!eNULL:!LOW:!3DES:!MD5:!EXP:!PSK:!DSS:!RC4:!SEED:!IDEA:!ECDSA:kEDH:CAMELLIA256-SHA:AES256-SHA:CAMELLIA128-SHA:AES128-SHA
        SSLHonorCipherOrder     on
        SSLCertificateFile      /var/lib/puppet/ssl/certs/master.pem
        SSLCertificateKeyFile   /var/lib/puppet/ssl/private_keys/master.pem
        SSLCertificateChainFile /var/lib/puppet/ssl/certs/ca.pem
        SSLCACertificateFile    /var/lib/puppet/ssl/certs/ca.pem
        # If Apache complains about invalid signatures on the CRL, you can try disabling
        # CRL checking by commenting the next line, but this is not recommended.
        SSLCARevocationFile     /var/lib/puppet/ssl/ca/ca_crl.pem
        # Apache 2.4 introduces the SSLCARevocationCheck directive and sets it to none
        # which effectively disables CRL checking; if you are using Apache 2.4+ you must
        # specify 'SSLCARevocationCheck chain' to actually use the CRL.
        # SSLCARevocationCheck chain
        SSLVerifyClient optional
        SSLVerifyDepth  1
        # The `ExportCertData` option is needed for agent certificate expiration warnings
        SSLOptions +StdEnvVars +ExportCertData
        # This header needs to be set if using a loadbalancer or proxy
        RequestHeader unset X-Forwarded-For
        RequestHeader set X-SSL-Subject %{SSL_CLIENT_S_DN}e
        RequestHeader set X-Client-DN %{SSL_CLIENT_S_DN}e
        RequestHeader set X-Client-Verify %{SSL_CLIENT_VERIFY}e
        DocumentRoot /usr/share/puppet/rack/puppetmasterd/public/
        RackBaseURI /

                Options None
                AllowOverride None
                Order allow,deny
                allow from all

查看上面的配置文件,我们可以注意到许多基于系统的主机名生成的SSL证书自动。
确认所有列出的证书路径指向正确的Puppet SSL证书。
否则,需要生成新的SSL证书。
如果我们需要先生成新的证书,请删除当前证书:

root@master:~# rm -rf /var/lib/puppet/ssl

接下来,在前台运行puppet以查看要生成的新证书。完成后,使用CTRL+C组合键停止进程:

root@master:~# puppet master --verbose --no-daemonize
Info: Creating a new SSL key for ca
Info: Creating a new SSL certificate request for ca
Info: Certificate Request fingerprint (SHA256): FA:D8:2A:0F:B4:0B:91:8C:01:AD:71:B4:49:66:1F:B1:38:BE:A4:4E:AF:76:16:D2:97:50:C8:A3:8F:35:CC:F2
Notice: Signed certificate request for ca
Info: Creating a new certificate revocation list
Info: Creating a new SSL key for master
Info: csr_attributes file loading from /etc/puppet/csr_attributes.yaml
Info: Creating a new SSL certificate request for master
Info: Certificate Request fingerprint (SHA256): 43:67:42:68:64:73:83:F7:36:2B:2E:6F:06:20:65:87:AB:61:96:2A:EB:B2:91:A9:58:8E:3F:F0:26:63:C3:00
Notice: master has a waiting certificate request
Notice: Signed certificate request for master
Notice: Removing file Puppet::SSL::CertificateRequest master at '/var/lib/puppet/ssl/ca/requests/master.pem'
Notice: Removing file Puppet::SSL::CertificateRequest master at '/var/lib/puppet/ssl/certificate_requests/master.pem'
Notice: Starting Puppet master version 3.7.2
^CNotice: Caught INT; calling stop

在启动puppet master之前,我们首先需要创建一个默认的空白配置列表:

root@master:~# > /etc/puppet/manifests/site.pp

一切就绪,可以在重新启动后启动puppet master:

root@master:~# systemctl enable apache2
Synchronizing state for apache2.service with sysvinit using update-rc.d...
Executing /usr/sbin/update-rc.d apache2 defaults
Executing /usr/sbin/update-rc.d apache2 enable

并启动Apache WebServer启动Puppet Master:

root@master:~# service apache2 start  
[ ok ] Starting web server: apache2.
root@master:~#

确认Puppet 正在运行

# ps aux
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root         1  0.0  0.0  20228  2014 ?        Ss   11:53   0:00 /bin/bash
root      1455  0.0  0.0  98272  4600 ?        Ss   12:40   0:00 /usr/sbin/apache2 -k start
root      1458  0.0  0.0 223228  1920 ?        Ssl  12:40   0:00 PassengerWatchdog
root      1461  0.0  0.0 506784  4156 ?        Sl   12:40   0:00 PassengerHelperAgent
nobody    1466  0.0  0.0 226648  4892 ?        Sl   12:40   0:00 PassengerLoggingAgent
www-data  1476  0.0  0.0 385300  5116 ?        Sl   12:40   0:00 /usr/sbin/apache2 -k start
www-data  1477  0.0  0.0 450880  5608 ?        Sl   12:40   0:00 /usr/sbin/apache2 -k start
root      1601  0.0  0.0  17484  1140 ?        R+   12:44   0:00 ps aux

并在端口8140上监听:

# netstat -ant              
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address           Foreign Address         State      
tcp6       0      0 :::8140                 :::*                    LISTEN     
tcp6       0      0 :::80                   :::*                    LISTEN     
tcp6       0      0 :::443                  :::*                    LISTEN

故障排除

问题

apache2: Could not reliably determine the server’s fully qualified domain name, using 172.17.0.43.
apache2:无法可靠地确定服务器的完全限定域名,使用172.17.0.43。

解决方法

全局设置“ServerName”指令

# echo "ServerName `hostname`" >> /etc/apache2/apache2.conf

问题

注意:正在跳过Puppet配置客户端的运行;管理性禁用(原因:“在新安装或者未配置的旧安装上默认禁用”);

解决方法

使用 puppet agent --enable重新启用。

root@node1:/# puppet agent --enable

Puppet节点配置

目前,我们的主服务器正在运行,并期待来自puppet代理的请求,因此是时候在'node1'上安装我们的puppet代理了:

# apt-get install puppet

接下来,我们需要通过从配置文件“/etc/puppet/puppet.conf”中删除任何主服务器默认指令,将puppet配置为代理:

[main]
logdir=/var/log/puppet
vardir=/var/lib/puppet
ssldir=/var/lib/puppet/ssl
rundir=/var/run/puppet
factpath=$vardir/lib/facter
prerun_command=/etc/puppet/etckeeper-commit-pre
postrun_command=/etc/puppet/etckeeper-commit-post
[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

改成

[main]
logdir=/var/log/puppet
vardir=/var/lib/puppet
ssldir=/var/lib/puppet/ssl
rundir=/var/run/puppet
factpath=$vardir/lib/facter
prerun_command=/etc/puppet/etckeeper-commit-pre
postrun_command=/etc/puppet/etckeeper-commit-post
[agent]
server = master

上面的指令'server=master'定义了puppet代理要连接的主服务器。其中,在本例中,单词“master”作为主机名,解析为主服务器的IP地址:

# ping -c 1 master
PING master (172.17.0.43): 56 data bytes
64 bytes from 172.17.0.43: icmp_seq=0 ttl=64 time=0.226 ms
--- master ping statistics --
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max/stddev = 0.226/0.226/0.226/0.000 ms

安装部分已完成,剩下的是在重新启动后启用puppet并启动puppet:

# systemctl enable puppet
Synchronizing state for puppet.service with sysvinit using update-rc.d...
Executing /usr/sbin/update-rc.d puppet defaults
Executing /usr/sbin/update-rc.d puppet enable
root@node1:/# service puppet start
[ ok ] Starting puppet agent.

此外,默认情况下,在新的未配置主机上安装后,代理将被禁用。要启用puppet agent,我们需要运行:

root@node1:/# puppet agent --enable

签署代理证书

主机“master”和“node1”都已启动并正在运行。让主机和代理通话所需的最后一组配置是对“node1”的证书请求进行签名。在'node1'上启动puppet代理后,向'master'服务器发出了证书签名请求:

root@master:/# puppet cert list
  "node1" (SHA256) 2C:62:B3:A4:1A:66:0A:14:17:93:86:E4:F8:1C:E3:4E:25:F8:7A:7C:FB:FC:6B:83:97:F1:C8:21:DD:52:E4:91

默认情况下,每个证书签名请求都必须手动签名:

root@master:/# puppet cert sign node1
Notice: Signed certificate request for node1
Notice: Removing file Puppet::SSL::CertificateRequest node1 at '/var/lib/puppet/ssl/ca/requests/node1.pem'

在这个阶段,我们的主机应该托管两个签名证书:

root@master:/# puppet cert list --all
+ "master" (SHA256) EE:E0:0A:5C:05:17:FA:11:05:E8:D0:8C:29:FC:D2:1F:E0:2F:27:A8:66:70:D7:4B:A1:62:7E:BA:F4:7C:3D:E8
+ "node1"  (SHA256) 99:DC:41:BA:26:FE:89:98:DC:D6:F0:34:64:7A:DF:E2:2F:0E:84:48:76:6D:75:81:BD:EF:01:44:CB:08:D9:2A

术语

  • Puppet Master - 主机和编译所有代理配置表单的中央服务器
  • Puppet代理 - 在节点上运行的服务,并定期检查使用主Puppet 服务器的配置状态,并获取当前最新的配置列表
  • manifest - 配置文件在Puppet Master和Puppet代理之间交换
  • node - Puppet 服务运行的操作系统

场景设置

在本教程中,我将这两个主机简单地称为“master”和“node1”。“master”和“node1”实例上使用的操作系统都是Debian 8 Jessie。Ubuntu Linux也可以作为遵循本教程的另一种选择。底层网络配置是不相关的。但是,预期'node1'可以通过其名称解析'master'主机,并且两台主机都已连接,并应用了适当的防火墙设置,以允许Puppet 'master'和'node1'代理进行通信:

root@node1:/# ping -c 1 master
PING master (172.17.0.1): 56 data bytes
64 bytes from 172.17.0.1: icmp_seq=0 ttl=64 time=0.083 ms
--- master ping statistics --
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max/stddev = 0.083/0.083/0.083/0.000 ms

触发puppet配置请求

现在是创建第一个配置列表的时候了。如上所述,我们现在要确保'node1'上有'hello'包。在“主机”主机上打开默认列表“/etc/puppet/manifests/site.pp”文件,并添加以下简化的节点配置:

package { "hello":
    ensure => "installed"
}

“node1”上的代理默认设置为每30分钟检索一次主机的配置。如果我们不希望等待,我们可以手动触发配置请求:

root@node1:/# hello
bash: hello: command not found

软件包hello当前在'node1'上不可用。手动触发新配置请求:

root@node1:/# puppet agent --test
Info: Caching certificate_revocation_list for ca
Info: Retrieving pluginfacts
Info: Retrieving plugin
Info: Caching catalog for node1
Info: Applying configuration version '1434159185'
Notice: /Stage[main]/Main/Package[hello]/ensure: ensure changed 'purged' to 'present'
Info: Creating state file /var/lib/puppet/state/state.yaml
Notice: Finished catalog run in 4.00 seconds

从以上输出中,我们可以看到应用了新的配置,现在可以使用包“hello”:

root@node1:/# hello
Hello, world!
日期:2020-07-07 20:54:59 来源:oir作者:oir