资讯动态

SaltStack生产环境配置精讲:Master与Minion核心参数调优实战

发布时间:2026/10/13 5:45:02 来源:尧图企业网站定制
1. 从零拆解 SaltStack 架构为什么 master 和 minion 的配置决定了整套系统的上限SaltStack 这套配置管理工具刚上手的时候很多人觉得它比 Ansible 复杂光是 master 和 minion 两个角色的配置文件就够看半天。但真正在生产环境跑过几百台机器之后你会发现它的稳定性和执行效率确实值得花时间把配置吃透。我最早接触 SaltStack 是在一个混合云环境里当时管着大概三百多台服务器Ansible 跑批量任务偶尔会因为 SSH 连接数打满而超时换成 SaltStack 之后基于 ZeroMQ 的消息队列机制让并发执行变得非常顺畅。但前提是你得把 master 和 minion 的关键配置调对否则默认配置在小规模测试时看不出问题一旦规模上去各种超时、认证失败、文件描述符耗尽的问题就会集中爆发。这篇文章主要面向已经了解 SaltStack 基本概念、能跑通最简单的 salt 命令但准备把它推向生产环境的运维人员。我会把 master 端和 minion 端的核心配置项逐个拆开讲包括每个参数为什么存在、默认值有什么坑、生产环境应该怎么调、调整之后会带来什么影响。同时也会分享一些我在实际运维中踩过的坑和总结出来的排查思路。如果你正在做 SaltStack 的规模化部署或者遇到了性能瓶颈不知道从哪里下手这篇内容应该能帮你省下不少翻文档和试错的时间。2. Master 端核心配置逐项精讲从监听地址到文件服务器调优2.1 网络监听与通信端口配置Master 端的配置文件通常位于/etc/salt/master这个文件本身是一个 YAML 格式的配置但 SaltStack 对缩进的要求没有 Ansible 那么严格它用的是自己的解析器不过还是建议保持规范的 YAML 缩进习惯。最基础的配置项是interface它决定了 master 监听在哪个网络接口上。默认值是0.0.0.0也就是监听所有网卡。在单网卡环境下这没什么问题但如果你的服务器有多张网卡比如一张内网网卡、一张管理网卡那就应该明确指定内网 IP避免 minion 通过错误的网络路径连接过来。# /etc/salt/master interface: 192.168.10.100和interface配套的是publish_port默认是4505这是 master 用来发布任务消息的端口。另一个关键端口是ret_port默认4506minion 通过这个端口把执行结果回传给 master。这两个端口在防火墙策略里必须放行而且要注意4505是 PUB/SUB 模式的发布端口4506是 REQ/REP 模式的请求响应端口两者用途不同不能混用。注意如果你的环境里有 NAT 或者端口映射ret_port的配置需要特别小心。minion 端有一个master_port参数默认指向4506如果 master 的ret_port改了minion 端也必须同步修改否则会出现 minion 能收到任务但结果回不来的情况。2.2 文件服务器后端选型与性能调优SaltStack 的文件服务器负责把 master 上的文件分发给 minion默认后端是roots也就是直接读取本地文件系统。对于大多数场景roots后端已经够用了但如果你的文件数量特别大或者需要从多个源聚合文件可以考虑git后端或者minion后端。git后端的好处是文件版本可以通过 Git 来管理回滚和审计都很方便但每次拉取文件都会有一次 Git 操作的开销文件数量少的时候影响不大文件多了就会明显拖慢速度。# 使用 roots 后端的基本配置 fileserver_backend: - roots file_roots: base: - /srv/salt/base dev: - /srv/salt/dev prod: - /srv/salt/prodfile_roots支持多环境配置这在管理不同生命周期的服务器时非常有用。比如开发环境的 minion 可以指定dev环境生产环境的 minion 指定prod环境这样同一套 master 就能管理不同环境的配置而不需要维护多套 master。环境切换是通过 minion 端的environment参数或者 pillar 来控制的。文件服务器的性能调优方面fileserver_update_interval这个参数值得关注。它控制 master 多久重新扫描一次文件根目录默认是60秒。如果你的文件更新频率很低可以把这个值调大减少不必要的磁盘扫描。反过来如果你经常需要实时推送文件变更可以调小但不要低于10秒否则会给磁盘带来不必要的压力。2.3 认证与密钥管理的关键参数Master 和 minion 之间的认证基于密钥对master 端有一个pki_dir参数默认是/etc/salt/pki/master里面存放了 master 自己的密钥和所有 minion 的公钥。auto_accept这个参数默认是False意味着新的 minion 连接上来之后需要手动执行salt-key -a来接受它的公钥。在生产环境里我强烈建议保持auto_accept: False虽然手动接受密钥多了一步操作但这是安全审计的重要环节。你可以在接受之前确认 minion 的 ID 和指纹避免未授权的节点混进来。# 认证相关配置 pki_dir: /etc/salt/pki/master auto_accept: False autosign_file: /etc/salt/autosign.conf如果 minion 数量特别大比如上千台手动接受密钥确实不太现实这时候可以用autosign_file来配置自动签名的规则。这个文件里可以写 minion ID 的正则表达式匹配的 minion 会自动通过认证。但一定要把正则写得足够严格比如只允许特定前缀的 ID 自动签名否则就失去了安全控制的意义。key_pass这个参数用于给 master 的私钥加密默认是空的。如果你的安全要求比较高可以设置一个密码但每次 master 启动都需要输入密码不适合自动化运维场景。折中的方案是把私钥文件权限设为600并且只允许 salt 用户读取。2.4 并发与超时控制worker_threads 和 timeoutworker_threads是 master 端最重要的性能参数之一它决定了 master 能同时处理多少个 minion 的请求。默认值是5这个值在 minion 数量少于 50 的时候勉强够用但超过 100 台之后就会成为瓶颈。我一般会把它设置为 minion 数量的十分之一左右比如 300 台 minion 就设成30。但也不是越大越好每个 worker 线程都会消耗内存和 CPU设置过大反而会导致上下文切换开销增加。# 性能相关配置 worker_threads: 30 timeout: 10 gather_job_timeout: 10timeout参数控制 master 等待 minion 返回结果的时间默认是5秒。这个值在局域网环境里通常够用但如果你的网络延迟比较高或者 minion 正在执行一个耗时的任务就需要适当调大。我一般会设成10到15秒。gather_job_timeout是 master 等待所有 minion 响应一个 job 的总时间默认也是5秒对于大规模并发任务这个值也需要相应调大。实操心得调整worker_threads之后记得同步检查系统的文件描述符限制。每个 worker 线程都会打开一定数量的文件描述符如果系统默认的ulimit -n是 1024在 worker_threads 设成 30 以上的时候就可能不够用。建议把 salt-master 进程的ulimit -n设成 65535可以通过 systemd 的LimitNOFILE参数来配置。3. Minion 端核心配置逐项精讲连接、认证与执行环境3.1 Master 地址配置与连接策略Minion 端的配置文件在/etc/salt/minion最核心的配置项是master它指定了 minion 要连接的 master 地址。这个地址可以是 IP也可以是域名。如果 master 有多个地址或者需要做高可用可以配置master为一个列表minion 会按顺序尝试连接。# /etc/salt/minion master: - 192.168.10.100 - 192.168.10.101master_port默认是4506对应 master 的ret_port。如果 master 端改了ret_port这里必须同步修改。还有一个publish_port参数默认是4505对应 master 的发布端口。这两个端口如果都改了minion 端的配置也要跟着改否则会出现连接不上的情况。random_master这个参数默认是False当配置了多个 master 地址时minion 会按顺序尝试。如果设成Trueminion 会随机选择一个 master 连接这在多 master 负载均衡的场景下有用但要注意随机选择意味着 minion 可能连到不同的 master如果 master 之间的配置不一致就会出现行为不一致的问题。3.2 Minion ID 的确定与重连机制Minion ID 是 minion 在 master 端的唯一标识默认情况下minion 会使用主机名作为 ID。但主机名可能会变或者在不同的环境里有重复所以我一般会显式指定id参数用一个有规律的命名方式比如web-01、db-01这种。id: web-01如果 minion 启动的时候 master 还没起来或者网络暂时不通minion 会不断重试连接。acceptance_wait_time控制重试的间隔默认是10秒。acceptance_wait_time_max是重试间隔的上限默认是0表示不设上限一直按固定间隔重试。如果设成一个非零值重试间隔会逐渐增加直到达到这个上限。在网络不稳定的环境里适当调大这两个值可以减少无谓的连接尝试。random_reauth_delay这个参数控制 minion 重新认证的随机延迟默认是60秒。当 master 重启或者密钥重新生成之后所有 minion 会同时尝试重新认证如果 minion 数量很大会给 master 带来瞬间的认证压力。设置一个随机延迟可以让认证请求分散开来避免惊群效应。3.3 执行环境与模块加载配置Minion 端的environment参数决定了它使用哪个文件环境默认是base。如果你在 master 端配置了多环境就需要在 minion 端指定对应的环境。environment: prodgrains是 minion 端非常重要的一个概念它是 minion 启动时收集的系统信息比如操作系统、CPU 架构、内存大小等。grains_refresh_every参数控制 grains 的刷新间隔默认是0表示不自动刷新。如果你的环境里硬件配置会动态变化比如云主机扩容可以设置一个刷新间隔比如3600秒让 minion 定期更新 grains 信息。modules参数用于指定 minion 加载哪些执行模块默认是加载所有可用的模块。如果你的环境对安全性要求很高可以只加载必要的模块减少攻击面。但要注意禁用模块可能会影响某些 state 的执行需要仔细测试。3.4 文件描述符与进程管理Minion 端的max_open_files参数控制 minion 进程能打开的最大文件数默认是100000。这个值在大多数场景下够用但如果你的 minion 需要同时处理大量文件操作比如批量部署大文件可能需要调大。调整这个参数的同时也要确保系统的ulimit -n足够大否则 minion 启动时会报错。max_open_files: 100000minion_pub_port和minion_ret_port是 minion 端用于接收 master 消息和回传结果的本地端口默认都是0表示随机分配。在大多数情况下不需要修改但如果你的环境有严格的端口管理策略可以指定固定的端口范围。注意修改 minion 的配置文件之后需要重启 salt-minion 服务才能生效。但重启会导致 minion 暂时断开连接如果正在执行任务任务会中断。所以建议在维护窗口进行配置变更或者使用salt-call在本地测试配置效果之后再重启服务。4. 实操过程从零搭建一套可用的 Master-Minion 环境4.1 环境准备与安装假设我们有两台服务器一台作为 masterIP 是192.168.10.100一台作为 minionIP 是192.168.10.101。操作系统是常见的 Linux 发行版这里以包管理器安装为例。在 master 上安装 salt-master# 在 master 节点执行 sudo apt-get update sudo apt-get install -y salt-master在 minion 上安装 salt-minion# 在 minion 节点执行 sudo apt-get update sudo apt-get install -y salt-minion安装完成之后先不要急着启动服务先把配置文件改好。master 端的/etc/salt/master至少需要配置interface和worker_threads。minion 端的/etc/salt/minion需要配置master和id。4.2 Master 端配置实操编辑/etc/salt/master写入以下内容interface: 192.168.10.100 publish_port: 4505 ret_port: 4506 worker_threads: 10 timeout: 10 gather_job_timeout: 10 file_roots: base: - /srv/salt/base pillar_roots: base: - /srv/pillar/base auto_accept: False创建文件根目录和 pillar 根目录sudo mkdir -p /srv/salt/base sudo mkdir -p /srv/pillar/base启动 master 服务sudo systemctl enable salt-master sudo systemctl start salt-master sudo systemctl status salt-master检查 master 是否正常监听sudo ss -tlnp | grep -E 4505|4506应该能看到 salt-master 进程监听在这两个端口上。4.3 Minion 端配置实操编辑/etc/salt/minion写入以下内容master: 192.168.10.100 master_port: 4506 id: minion-01 environment: base acceptance_wait_time: 10 random_reauth_delay: 60启动 minion 服务sudo systemctl enable salt-minion sudo systemctl start salt-minion sudo systemctl status salt-minion在 master 端查看 minion 的密钥请求sudo salt-key -L应该能在Unaccepted Keys下面看到minion-01。接受这个密钥sudo salt-key -a minion-01再次查看密钥列表确认minion-01出现在Accepted Keys下面。4.4 连通性测试与基础命令验证在 master 端执行测试命令sudo salt minion-01 test.ping如果返回minion-01: True说明 master 和 minion 之间的通信正常。接下来测试一下 grains 和 pillarsudo salt minion-01 grains.items sudo salt minion-01 pillar.itemsgrains.items会返回 minion 的所有系统信息pillar.items会返回 pillar 数据。如果 pillar 是空的说明 pillar 根目录下还没有定义任何数据这是正常的。再测试一下文件分发# 在 master 上创建一个测试文件 echo hello from master | sudo tee /srv/salt/base/test.txt # 分发到 minion sudo salt minion-01 cp.get_file salt://test.txt /tmp/test.txt # 在 minion 上验证 cat /tmp/test.txt如果 minion 上能看到hello from master说明文件服务器工作正常。4.5 关键参数调整后的效果验证调整worker_threads之后可以通过压力测试来验证效果。在 master 上执行一个批量命令同时观察 master 的 CPU 和内存使用情况# 同时向多个 minion 发送命令 sudo salt * test.ping # 查看 master 进程的线程数 ps -eLf | grep salt-master | wc -l如果worker_threads设置得太小批量命令会出现部分 minion 超时的情况。可以通过--timeout参数临时调整超时时间sudo salt * test.ping --timeout 30如果调整超时之后命令能正常返回说明worker_threads或者timeout需要调大。实操心得在调整worker_threads的时候建议每次增加 5 到 10然后观察 master 的负载情况。不要一次性调得太大否则可能因为线程过多导致 master 响应变慢。我一般会配合top -H -p $(pgrep -d, -f salt-master)来观察每个线程的 CPU 占用如果大部分线程都处于空闲状态说明当前值已经够用。5. 常见问题与排查技巧实录5.1 Minion 连接不上 Master 的排查思路这是最常见的问题表现是 minion 启动之后master 端执行salt-key -L看不到任何密钥请求。排查步骤可以按以下顺序进行排查步骤检查命令预期结果异常处理检查网络连通性ping 192.168.10.100能 ping 通检查路由和防火墙检查端口连通性telnet 192.168.10.100 4505能建立连接检查 master 防火墙规则检查 master 服务状态systemctl status salt-masteractive (running)查看 master 日志检查 minion 服务状态systemctl status salt-minionactive (running)查看 minion 日志检查 minion 配置grep -E ^master /etc/salt/minion指向正确的 master IP修正配置并重启检查 minion 日志tail -f /var/log/salt/minion无报错信息根据报错定位问题如果以上步骤都正常但 master 端还是看不到密钥请求可以尝试在 minion 上手动执行salt-call --local test.ping确认 minion 本身是否正常工作。如果本地执行正常说明问题出在网络或者认证环节。5.2 认证失败与密钥冲突的处理有时候 minion 之前连接过 master后来 master 重装了或者密钥被删了minion 再用原来的密钥去认证就会失败。表现是 minion 日志里出现Authentication failed或者SaltReqTimeoutError。解决方法是删除 minion 端的旧密钥让它重新生成# 在 minion 上执行 sudo systemctl stop salt-minion sudo rm -rf /etc/salt/pki/minion/minion.pub sudo rm -rf /etc/salt/pki/minion/minion.pem sudo systemctl start salt-minion然后在 master 端删除旧的密钥记录sudo salt-key -d minion-01等 minion 重新发起认证请求之后再接受新的密钥。注意删除密钥之前确认这个 minion 确实需要重新认证而不是因为其他原因导致的连接问题。如果只是网络抖动不需要删除密钥等网络恢复之后 minion 会自动重连。5.3 执行超时与结果丢失的优化方案当 minion 数量比较多的时候执行salt *命令经常会出现部分 minion 超时的情况。除了调整worker_threads和timeout之外还可以使用--batch参数来控制并发度# 每次向 10% 的 minion 发送命令间隔 5 秒 sudo salt * test.ping --batch 10% --batch-wait 5--batch参数可以显著降低 master 的瞬时压力但代价是总执行时间变长。对于不需要实时返回结果的批量任务这是一个很好的折中方案。另一个优化点是使用salt-run来执行编排任务而不是直接salt *。salt-run可以在 master 端做更复杂的任务编排比如按批次执行、失败重试等。5.4 文件描述符耗尽与内存泄漏的应对如果 master 运行一段时间之后出现Too many open files的错误说明文件描述符不够用了。除了调整worker_threads之外还需要检查系统的ulimit设置# 查看当前限制 ulimit -n # 临时调整 ulimit -n 65535对于 systemd 管理的服务需要在 service 文件中配置[Service] LimitNOFILE65535然后重新加载 systemd 配置并重启服务sudo systemctl daemon-reload sudo systemctl restart salt-master内存泄漏方面SaltStack 的 master 进程在长时间运行之后内存占用可能会逐渐增加。这通常是因为某些模块或者插件没有正确释放资源。如果发现内存持续增长可以定期重启 master 服务或者使用salt-master的--log-leveldebug参数来定位具体是哪个模块导致的问题。5.5 配置变更后的生效验证清单每次修改 master 或 minion 的配置之后建议按以下清单逐项验证配置文件语法检查salt-master --config-check或者salt-minion --config-check服务重启systemctl restart salt-master或systemctl restart salt-minion服务状态确认systemctl status salt-master或systemctl status salt-minion端口监听确认ss -tlnp | grep salt连通性测试salt * test.ping关键功能验证根据修改的配置项执行对应的功能测试这个清单看起来简单但实际运维中经常有人改完配置忘了重启服务或者重启之后没有验证导致问题被带到生产环境。养成按清单操作的习惯能避免很多低级错误。6. 规模化部署中的进阶配置策略6.1 多 Master 架构的配置要点当 minion 数量超过单台 master 的处理能力时就需要考虑多 master 架构。SaltStack 支持 minion 配置多个 master 地址但要注意多个 master 之间的文件根目录和 pillar 数据需要保持同步否则 minion 连接到不同的 master 会得到不同的配置结果。# minion 端配置多个 master master: - 192.168.10.100 - 192.168.10.101 - 192.168.10.102多 master 之间的数据同步可以通过共享存储来实现比如 NFS 或者分布式文件系统。但共享存储本身可能成为单点故障所以更可靠的方式是使用 Git 作为文件后端每个 master 定期从 Git 仓库拉取最新的配置。6.2 使用 Syndic 实现层级化管理Syndic 是 SaltStack 提供的一种层级化管理机制可以让一个 master 作为另一个 master 的 minion从而实现多级管理。这种架构适合跨数据中心或者跨网络区域的场景比如每个区域有一个本地 master然后统一由一个顶层 master 来管理。配置 Syndic 需要在中间层 master 上同时运行 salt-master 和 salt-minionminion 连接到顶层 mastermaster 接受本地 minion 的连接。顶层 master 通过中间层 master 来管理本地 minion命令会逐级下发。这种架构的优点是减少了跨区域的网络流量缺点是配置复杂度增加排查问题的时候需要逐级检查。我一般只在确实有跨区域管理需求的时候才用 Syndic否则单层多 master 架构已经够用了。6.3 性能监控与容量规划规模化部署之后监控 master 的性能指标变得很重要。关键指标包括master 进程的 CPU 和内存占用worker 线程的活跃数量任务队列的长度minion 的响应时间分布这些指标可以通过 SaltStack 自身的监控模块来采集也可以集成到外部的监控系统里。我一般会在 master 上部署一个简单的监控脚本定期采集这些指标并推送到监控平台。容量规划方面一台 4 核 8G 的 master 大概能管理 500 到 800 台 minion具体取决于任务的复杂度和执行频率。如果 minion 数量超过这个范围就需要考虑增加 master 或者调整架构。这个数字不是绝对的实际规划的时候需要根据压测结果来确定。6.4 配置管理的版本控制与回滚Master 端的配置文件、文件根目录、pillar 数据都应该纳入版本控制。我一般会用 Git 来管理这些内容每次变更都提交一个 commit这样出问题的时候可以快速回滚。# 在 master 上初始化 Git 仓库 cd /srv/salt git init git add . git commit -m initial salt configuration # 后续变更 git add . git commit -m update nginx config如果使用了 Git 文件后端SaltStack 可以直接从 Git 仓库读取文件这样版本控制和文件分发就统一了。但 Git 后端的性能不如本地文件系统文件数量多的时候会有明显的延迟所以需要根据实际情况权衡。实操心得不管用不用 Git 后端我都建议把/etc/salt/master和/etc/salt/minion也纳入版本控制。这两个文件虽然不大但包含了所有关键配置一旦丢失或者被误改恢复起来很麻烦。可以把它们放在一个单独的 Git 仓库里用符号链接链接到/etc/salt/下面。7. 个人实操体会与后续扩展方向SaltStack 的 master 和 minion 配置看起来项目很多但真正影响稳定性和性能的核心参数就那么几个。我的经验是先把worker_threads、timeout、max_open_files这三个参数根据实际规模调好大部分性能问题就能解决。认证和密钥管理方面保持auto_accept: False用autosign_file来做批量签名的折中方案既安全又不会太麻烦。后续如果还想深入可以研究一下 SaltStack 的 reactor 系统和 beacon 系统。Reactor 可以在特定事件发生时自动触发动作比如 minion 上线时自动执行初始化配置。Beacon 则可以让 minion 主动监控某些状态变化并上报给 master。这两个机制结合起来能实现很多自动化的运维场景比如自动发现新节点并完成配置、监控关键服务状态并自动恢复等。另外SaltStack 的 returner 机制也值得关注。默认情况下任务执行结果只保存在 master 的内存里重启就丢了。配置一个 returner比如 MySQL 或者 Elasticsearch可以把执行结果持久化方便后续审计和查询。这在合规要求比较高的环境里特别有用。最后再分享一个小技巧在调试 master 和 minion 配置的时候可以用salt-minion --log-leveldebug在前台启动 minion这样所有日志都会直接输出到终端比看日志文件方便得多。master 也可以用类似的方式调试但 master 的日志量比较大建议还是看日志文件用tail -f配合grep来过滤关键信息。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑