Puppet配置管理实战:让1000台服务器听话的秘密武器
2026/6/4 22:10:18 网站建设 项目流程

今天就来分享一下我这几个月使用Puppet管理多服务器配置的实战经验,包括一些踩过的坑和解决方案。

Puppet基础概念快速入门

在开始实战之前,先简单说说Puppet的核心概念,这些理解了后面的操作就很容易了。

Puppet采用的是Master-Agent架构,Master节点存储配置清单(manifest),Agent节点定期向Master请求配置并应用。整个过程是声明式的,你只需要描述想要的最终状态,Puppet会自动计算如何达到这个状态。

几个重要概念:

  • Manifest:用Puppet DSL语言编写的配置文件,描述系统应该是什么样子

  • Module:可复用的配置单元,包含manifest、文件、模板等

  • Node:被管理的服务器节点

  • Catalog:Master为每个节点编译生成的具体配置指令

环境搭建实战

我的测试环境是3台CentOS 7服务器,1台Master,2台Agent。生产环境类似,只是Agent数量更多。

Master节点安装配置

# 安装Puppet Server rpm -Uvh https://yum.puppet.com/puppet-release-el-7.noarch.rpm yum install -y puppetserver # 修改内存配置,默认2G太大了 vim /etc/sysconfig/puppetserver JAVA_ARGS="-Xms512m -Xmx512m" # 启动服务 systemctl enable puppetserver systemctl start puppetserver

这里有个坑,Puppet Server默认内存配置是2G,小环境根本用不了这么多,而且会导致启动失败。我把它调到512M,测试环境够用了。

Agent节点配置

# 安装Puppet Agent rpm -Uvh https://yum.puppet.com/puppet-release-el-7.noarch.rpm yum install -y puppet-agent # 配置Master地址 vim /etc/puppetlabs/puppet/puppet.conf [main] server = puppet-master.example.com # 启动服务 systemctl enable puppet systemctl start puppet

Agent第一次连接Master时需要证书认证,在Master上执行:

/opt/puppetlabs/bin/puppetserver ca list /opt/puppetlabs/bin/puppetserver ca sign --all

编写第一个配置管理模块

我们从一个简单的nginx模块开始。在生产环境中,nginx的配置管理是个头疼的问题,不同环境的配置文件经常不一致。

创建nginx模块结构

cd /etc/puppetlabs/code/environments/production/modules mkdir -p nginx/{manifests,files,templates,tests}

编写主配置文件

# nginx/manifests/init.pp class nginx { package { 'nginx': ensure => installed, } service { 'nginx': ensure => running, enable => true, require => Package['nginx'], } file { '/etc/nginx/nginx.conf': ensure => present, source => 'puppet:///modules/nginx/nginx.conf', owner => 'root', group => 'root', mode => '0644', notify => Service['nginx'], require => Package['nginx'], } }

这个配置很简单,确保nginx包安装、服务运行、配置文件正确。notify参数很重要,当配置文件变化时会自动重启服务。

准备配置文件模板

# 将标准的nginx配置放到files目录 cp /etc/nginx/nginx.conf nginx/files/

应用到节点

# site.pp node 'web-server-01.example.com' { include nginx } node 'web-server-02.example.com' { include nginx }

这样两台web服务器就会自动安装和配置nginx了。每次Agent运行时(默认30分钟),都会检查配置是否符合要求,不符合就自动修复。

高级配置管理技巧

使用变量和条件判断

实际环境中,不同服务器的配置往往有差异。比如内存大小不同,nginx worker进程数就应该不同:

class nginx { $worker_processes = $facts['processors']['count'] package { 'nginx': ensure => installed, } file { '/etc/nginx/nginx.conf': ensure => present, content => template('nginx/nginx.conf.erb'), owner => 'root', group => 'root', mode => '0644', notify => Service['nginx'], require => Package['nginx'], } service { 'nginx': ensure => running, enable => true, require => [Package['nginx'], File['/etc/nginx/nginx.conf']], } }

对应的ERB模板文件:

# nginx/templates/nginx.conf.erb worker_processes <%= @worker_processes %>; events { worker_connections 1024; } http { include /etc/nginx/mime.types; default_type application/octet-stream; <% if @facts['memorysize_mb'].to_i > 4096 %> # 大内存服务器使用更多连接 worker_connections 2048; <% end %> }

参数化模块

为了让模块更灵活,可以使用参数:

class nginx ( String $version = 'installed', Integer $worker_processes = $facts['processors']['count'], Boolean $enable_ssl = false, ) { package { 'nginx': ensure => $version, } if $enable_ssl { package { 'nginx-mod-ssl': ensure => installed, } } # 其他配置... }

在site.pp中这样使用:

node 'web-server-01.example.com' { class { 'nginx': worker_processes => 8, enable_ssl => true, } }

使用Hiera进行数据分离

Hiera是Puppet的数据查找系统,可以把配置数据从代码中分离出来。这在管理多环境时特别有用。

# /etc/puppetlabs/code/environments/production/data/common.yaml nginx::worker_processes: 4 nginx::enable_ssl: false # /etc/puppetlabs/code/environments/production/data/nodes/web-server-01.yaml nginx::worker_processes: 8 nginx::enable_ssl: true

模块中使用lookup函数获取数据:

class nginx { $worker_processes = lookup('nginx::worker_processes', Integer, 'first', $facts['processors']['count']) $enable_ssl = lookup('nginx::enable_ssl', Boolean, 'first', false) # 配置逻辑... }

管理复杂应用配置

单个服务的配置相对简单,但实际生产环境往往需要管理整个应用栈。我们来看一个更复杂的例子:LAMP环境的配置。

创建profile模块

# profiles/manifests/lamp.pp class profiles::lamp { include apache include mysql include php # 确保安装顺序 Class['mysql'] -> Class['apache'] -> Class['php'] }

Apache模块

class apache ( String $document_root = '/var/www/html', Array[String] $modules = ['rewrite', 'ssl'], ) { package { 'httpd': ensure => installed, } service { 'httpd': ensure => running, enable => true, } file { '/etc/httpd/conf/httpd.conf': ensure => present, content => template('apache/httpd.conf.erb'), notify => Service['httpd'], require => Package['httpd'], } $modules.each |$module| { exec { "enable-${module}-module": command => "/usr/bin/a2enmod ${module}", unless => "/usr/bin/apache2ctl -M | grep ${module}", notify => Service['httpd'], require => Package['httpd'], } } }

使用角色分离

在大型环境中,不同服务器承担不同角色。可以创建role模块:

# roles/manifests/webserver.pp class roles::webserver { include profiles::lamp include profiles::monitoring include profiles::backup } # roles/manifests/database.pp class roles::database { include profiles::mysql include profiles::monitoring include profiles::backup }

然后在site.pp中按角色分配:

node /^web-\d+\.example\.com$/ { include roles::webserver } node /^db-\d+\.example\.com$/ { include roles::database }

配置文件管理最佳实践

使用文件片段拼接

有时候配置文件需要从多个模块贡献内容,比如nginx的虚拟主机配置:

# 主配置 concat { '/etc/nginx/nginx.conf': owner => 'root', group => 'root', mode => '0644', notify => Service['nginx'], } concat::fragment { 'nginx-main': target => '/etc/nginx/nginx.conf', content => template('nginx/nginx-main.conf.erb'), order => '01', } # 虚拟主机配置 define nginx::vhost ( String $document_root, String $server_name = $title, ) { concat::fragment { "nginx-vhost-${title}": target => '/etc/nginx/nginx.conf', content => template('nginx/vhost.conf.erb'), order => '10', } }

敏感数据处理

生产环境中经常需要处理密码等敏感信息。Puppet支持加密的eyaml:

# 安装hiera-eyaml /opt/puppetlabs/puppet/bin/gem install hiera-eyaml

创建加密的配置:

eyaml encrypt -s 'mysecretpassword'

在Hiera中使用:

mysql::root_password: > ENC[PKCS7,MIIBiQYJKoZIhvcNAQcDoIIBejCCAXYCAQAxggEhMIIBHQIBADAFMAACAQEwDQYJKoZIhvcNAQEBBQAE...]

大规模部署策略

管理几百台服务器时,需要考虑部署策略,避免同时更新所有服务器导致服务中断。

使用环境分离

# 创建不同环境 mkdir -p /etc/puppetlabs/code/environments/{development,staging,production}

Agent可以指定环境:

# puppet.conf [agent] environment = staging

分批次部署

可以使用Puppet的runinterval和splay参数控制Agent运行时间:

[agent] runinterval = 1800 # 30分钟运行一次 splay = true # 随机延迟,避免同时运行

也可以手动控制部署:

# 禁用自动运行 puppet agent --disable "maintenance window" # 手动触发特定节点 mco puppet runonce -I web-server-01

配置验证

部署前最好验证配置语法:

# 验证语法 puppet parser validate manifests/init.pp # 模拟运行 puppet agent --test --noop

监控和故障排除

生产环境中,监控Puppet运行状态很重要。我们可以从多个维度监控:

日志分析

Puppet的日志很详细,但需要重点关注几个方面:

# Agent日志 tail -f /var/log/puppetlabs/puppet/puppet.log # Master日志 tail -f /var/log/puppetlabs/puppetserver/puppetserver.log

关键指标包括:

  • 配置编译时间

  • 资源应用成功率

  • 证书问题

  • 依赖关系错误

使用PuppetDB

PuppetDB可以存储所有节点的状态信息,方便查询和监控:

# 安装PuppetDB yum install -y puppetdb puppetdb-termini # 配置Master连接PuppetDB vim /etc/puppetlabs/puppet/puppetdb.conf [main] server_urls = https://puppetdb.example.com:8081

查询节点状态:

# 查看失败的节点 curl -X GET http://puppetdb:8080/pdb/query/v4/reports \ --data-urlencode 'query=["=", "status", "failed"]'

常见问题排查

我在使用过程中遇到过几个典型问题:

证书过期:Puppet证书默认5年有效期,过期后Agent无法连接Master。需要重新签发证书。

依赖关系循环:资源之间的依赖关系形成循环,导致配置无法应用。可以通过puppet agent --graph生成依赖图分析。

文件权限问题:特别是SELinux环境下,需要注意文件的安全上下文。

内存不足:Master编译大量配置时可能内存不足,需要调整JVM参数。

与其他工具集成

Puppet可以和很多运维工具集成,形成完整的自动化体系。

与Git集成

使用r10k或Code Manager可以实现Git驱动的部署:

# Puppetfile mod 'puppetlabs-stdlib' mod 'puppetlabs-concat' mod 'nginx', :git => 'https://github.com/company/puppet-nginx.git', :branch => 'production'

与监控系统集成

可以在Puppet配置中自动部署监控:

class profiles::monitoring { package { 'zabbix-agent': ensure => installed, } file { '/etc/zabbix/zabbix_agentd.conf': ensure => present, content => template('monitoring/zabbix_agentd.conf.erb'), notify => Service['zabbix-agent'], } service { 'zabbix-agent': ensure => running, enable => true, } }

性能优化经验

管理大量服务器时,性能优化很重要。我总结了几个优化点:

Master端优化

# /etc/puppetlabs/puppetserver/conf.d/puppetserver.conf jruby-puppet: { max-active-instances: 4 max-requests-per-instance: 100000 }

Agent端优化

[agent] usecacheonfailure = false report = false pluginsync = false

对于只读节点,可以禁用一些不必要的功能。

网络优化

使用本地Package仓库可以大幅提升安装速度:

yumrepo { 'local-repo': baseurl => 'http://repo.internal.com/centos/7/', enabled => 1, gpgcheck => 0, }

经过几个月的实践,我们的服务器配置管理效率提升了至少10倍,配置漂移问题基本消失。虽然初期学习成本比较高,但是长期收益非常明显。

特别是在云环境下,服务器经常弹性伸缩,Puppet的自动化配置管理能力显得更加重要。新服务器启动后几分钟就能自动完成所有配置,大大提升了运维效率。

当然Puppet也不是万能的,对于一些复杂的业务逻辑,还是需要结合其他工具。但作为基础设施配置管理,Puppet确实是个不错的选择。

如果你也在管理大量服务器,强烈建议试试Puppet。虽然学习曲线比较陡峭,但掌握后真的会让你的运维工作轻松很多。记住,好的工具能让运维工作事半功倍,而不是增加复杂度。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询