资讯详情

SaltStack极速入门:Master-Minion架构与配置管理实战

📅 2026/10/14 17:30:19 | 华诺云谱 👁 阅读
SaltStack极速入门:Master-Minion架构与配置管理实战
做运维或者接触过服务器的人应该都听过“配置管理”这个词。SaltStack通常被直接叫 Salt就是一个用 Python 编写的开源自动化运维工具核心思路是 Master-Minion 架构一台 Master 管所有 Minion通过高效的 ZeroMQ 消息队列通信可以同时向成百上千台机器下发命令、同步配置文件、管理服务状态。我第一次被 Salt 吸引是因为一个特别原始的痛点凌晨三点手动登录几十台服务器改一个配置项边改边担心抄错路径。如果你也有类似的经历这篇极速入门会带你在最短时间内跑通 Salt 最核心的部分并尽量绕开我踩过的那些坑。1. 为什么是 SaltStack从日常运维痛点说起1.1 当几十台服务器需要同时改配置时的真实场景假设你有 30 台测试环境的服务器今天产品经理说某个日志级别要从 warning 改成 info。如果没有自动化工具你会怎么做先写一个 shell 脚本用 ssh 批量传命令然后逐个确认结果。脚本写得好还行但一旦中间有一台机器网络抖动、密钥不对、或者服务名不一样你就要开始处理各种例外。我早年就干过这种事。写了一个 for 循环把一段 sed 命令打包发给 30 台机器结果跑完才发现有一台机器因为主机名不在白名单里直接失败了。更麻烦的是命令执行完只是“改完文件”并没有检查服务是否 reload 成功。这种手工模式本质上是在用临时方案弥补流程缺失下次需求换一换脚本又要重新改。Salt 解决的是另一个层面的问题把“我要在多台机器上执行什么操作”和“这些机器最终应该处于什么状态”这两件事变成可声明、可追踪的配置。你可以先用一个命令批量查看所有机器的状态再统一执行变更最后再批量确认结果。整个过程不需要再关心某台机器的 IP、密码、密钥因为 Minion 会自动连接 MasterMaster 通过 key 来识别每一台机器。1.2 SaltStack 与 Ansible、Puppet、Chef 的选择逻辑SaltStack 只是配置管理工具里的一员。经常被拿来对比的还有 Ansible、Puppet 和 Chef。下面这个表格是这几类工具最核心的差异工具通信方式是否需要在被管理端装 agent语言门槛执行模式SaltStackZeroMQMaster-Minion 长连接需要安装 Minion主要 YAML Jinja底层 Python命令执行 State 声明式AnsibleSSH 短连接不需要但需要能 SSH 的目标机YAML无需 agent命令执行 Playbook 声明式PuppetHTTPS 长连接Agent 定期拉取需要安装 agent使用其自身 DSL基于 Ruby声明式为主Chef由 Chef Server 下发配置需要安装 clientRuby DSL声明式为主如果只看最表面Salt 和 Ansible 最像都是 YAML 写配置都很灵活。但两者的执行模型不太一样。Ansible 走 SSH优势是“零 agent”适合机器数量不大、临时任务偏多的场景Salt 走长连接优势是批量执行效率高而且 Master 能实时掌握所有 Minion 的状态Pillar、Event、Runner 这些机制做大规模集群管理时很好用。选择工具时不必迷信“谁最流行”更重要的是看你的场景。如果你的服务器数量超过一百台而且希望有一套能持续管理配置、收集信息、甚至做命令通道的基础设施Salt 更值得投入。如果你只是偶尔改几台机器Ansible 的学习成本更低。我选择 Salt是因为我当时所在团队维护的机器数量很大需要一台中心化的 Master 来统一下发配置而且要能和各种监控、发布系统联动。2. 极速上手从安装到第一条命令2.1 安装 SaltStack 的最小准备我在这里按最常见的 Master Minion 模式讲。最简方案是准备两台机器一台当作 Master一台当作 Minion。系统只要主流 Linux 发行版都可以比如 CentOS、Ubuntu、Debian。Salt 也支持 Windows Minion但日常使用中 Linux 占绝大多数所以先不要管 Windows 的事。在 CentOS 上官方仓库用得最多的是 saltstack 的 rpm 仓库。安装前先配置一下 yum 源。以 Red Hat 系为例一条命令把官方源装上然后直接 yum 安装yum install -y https://repo.saltproject.io/py3/redhat/7/x86_64/latest/salt-repo-latest.rpm yum clean expire-cache yum install -y salt-master salt-minionUbuntu/Debian 上则是用 apt 加官方源再安装。这一步没什么技巧关键是记住Master 和 Minion 是两个独立的服务在一台机器上可以同时装两者但生产环境最好分开。装完之后先启动 Mastersystemctl enable salt-master systemctl start salt-masterMinion 端要做的第一件事是告诉它 Master 在哪里。Minion 的配置文件在 /etc/salt/minion里面有一个参数是 master默认写着 salt也就是主机名为 salt 的机器。如果你没有对主机名做解析最好直接改成 Master 的 IP# /etc/salt/minion 中设置 master: 192.168.1.100另外还需要给每台 Minion 一个唯一的名字。默认情况下 Minion 会用自己的 hostname 作为 id这个 id 会显示在 Master 的 key 列表里。建议用有规律的命名方式比如业务名 环境 序号。如果不想用主机名可以在 minion 配置里显式设置id: web-test-01启动 Minionsystemctl enable salt-minion systemctl start salt-minion这样 Minion 就会主动去连 Master。如果它们之间网络是通的Master 上用 salt-key -L 就能看到这台 Minion 的指纹 key。2.2 认证管理与第一个远程命令Salt 的认证机制通过 salt-key 管理。这个概念不复杂和 SSH 的 known_hosts 类似。Minion 第一次连接 Master会带着自己的公钥来状态是 unaccepted未接受。你得手动接受它Master 才会给它下发命令。查看所有 keysalt-key -L接受所有未认证的 keysalt-key -A只接受某一台salt-key -a web-test-01这里有一个建议刚开始学习时为了方便可以 -A 全接受但生产环境千万不要这样。批量接受 key 虽然省事但万一有人误装了一个 Minion 进来你就等于直接把一台陌生机器纳入了管理范围。比较稳妥的做法是逐个确认或者用 salt-key -A --include-rejected 这种不常用的参数但最终还是要人工判断。接受完之后测试连通性salt * test.pingtest.ping 返回 True 说明 Master 和 Minion 的通道已经打通。这里的 * 是目标表达式表示所有 Minion 的 id。你还可以用正则或者列表。看一下所有 Minion 的系统信息salt * grains.itemsgrains 是 Salt 采集的静态机器信息包括操作系统、CPU、内存、IP 等。这条命令可以作为最常用的信息收集工具。远程执行任意命令salt * cmd.run df -h如果你要只看某一台机器把 * 换成 Minion id 就可以了salt web-test-01 cmd.run uptime到这一步你已经掌握了 Salt 最核心的通道能力批量执行命令。剩下的 State 管理本质上也是把一个个模块调用组合起来只不过它有“期望状态”这个概念比直接跑命令更可控。2.3 我常用的几个基础排查命令刚入门时很多人会卡在“命令发出去了结果不对”这件事上。有几条命令能帮你快速定位问题。第一确认 Minion 是否在线。salt-key -L 只能看 key 是否被接受不能证明 Minion 还连着。用salt-run manage.status能看到当前 up 和 down 的 Minion。salt-run manage.status第二看执行日志。Master 的日志默认在 /var/log/salt/masterMinion 的日志在 /var/log/salt/minion。如果执行命令失败日志里常常会给出真正的报错原因比如 key mismatch、网络超时、或者 Python 模块缺依赖。不要只看终端返回的那一段日志才是第一现场。第三检查 Minion 进程和连接。Minion 启动后会维持到 Master 的长连接端口默认是 4505 和 4506。我自己排查时习惯先看这两个端口通不通ss -tunlp | grep 450从 Master 上 telnet Minion 的 4506 端口也可以判断基本连通性。很多时候命令不执行不是 Salt 的问题而是防火墙把 4505/4506 给挡了。3. State 状态管理让服务器配置“可声明”起来3.1 SLS 文件的基本结构与 Top file如果说远程执行命令是“临时手动”那么 State 管理就是“长期自动化”。两者的区别用一个生活类比最好理解命令执行像你打电话告诉保洁今天擦窗户State 则像是你写了一份标准保洁流程每一天屋子都应该保持这种状态如果有窗口没擦它就替你擦掉。State 文件在 Salt 里叫 SLSSaLt State。它本质上是一个 YAML 文件描述一批操作比如“确保 nginx 已安装”、“确保配置文件是哪个版本”、“确保服务正在运行”。所有 SLS 文件的根目录由 Master 配置里的 file_roots 指定。默认路径是 /srv/salt/base。在 /srv/salt/base 下top.sls 文件相当于“总装清单”它告诉 Master哪些 Minion 节点需要加载哪些 SLS。我举一个最简单的例子。要在所有机器上创建一个普通用户 ops并且设置好 sudoers 权限这里只是示例不涉及具体组织新建一个文件 /srv/salt/base/users.slsops_user: user.present: - name: ops - shell: /bin/bash - createhome: True然后在 top.sls 里把这个状态分配给所有 Minionbase: *: - users执行这条命令状态就会被应用salt * state.apply usersstate.apply 后面可以跟一个或多个 SLS 名称如果不写名称默认应用 top.sls 里匹配的整组状态。执行完之后的返回结果里每个步骤都会标记 True 或 False还会注明是“执行了”还是“已经是目标状态”一目了然。3.2 用 YAMLJinja 写出可复用的安装配置只写一个用户管理太简单了真实场景中你往往要根据不同系统、不同版本加载不同的配置。Salt 默认支持 Jinja 模板你可以把 SLS 文件写成模板里面读取变量、判断条件、循环生成配置。举个例子我要写一个 nginx 安装状态同时希望 CentOS 和 Ubuntu 上都能用。系统类型可以从 grains 里读取{% if grains[os_family] RedHat %} nginx_pkg: pkg.installed: - name: nginx {% elif grains[os_family] Debian %} nginx_pkg: pkg.installed: - name: nginx - update_pkg_cache: True {% endif %} nginx_service: service.running: - name: nginx - enable: True - require: - pkg: nginx_pkgJinja 的好处是可以减少重复。你不用为 CentOS 写一份、Ubuntu 再写一份。但要注意缩进和引号YAML 的语法本身对缩进极其敏感Jinja 标签又容易干扰 YAML 解析写完后建议先用salt * state.show_sls nginx查看渲染后的最终内容确认无误再执行。某些模块还支持 template 参数例如 file.managed 可以把本地文件模板渲染后传到远端/etc/nginx/nginx.conf: file.managed: - source: salt://nginx/files/nginx.conf.j2 - template: jinja - user: root - group: root - mode: 644 - watch_in: - service: nginx_service这里 watch_in 的意思很关键当 nginx.conf 发生变化后会让 nginx_service 触发重启或 reload。这样可以避免改了配置但服务没加载的情况。3.3 Grains 与 Pillar区分机器差异的正确姿势学习 Salt 时有两个概念特别容易被搞混Grains 和 Pillar。Grains 是 Minion 自己收集并上报给 Master 的静态数据比如操作系统、IP、内存、CPU 型号。它是 Minion 的“自我介绍”主要用来做目标匹配比如“只对操作系统是 CentOS 的机器执行某个状态”。你可以在 Minion 上手动设置一些自定义 Grains比如角色、机房、业务线。Pillar 是 Master 上用来存储机密和个性化数据的东西。和 Grains 相反Pillar 由 Master 定义并且只下发给指定的 Minion。比如数据库密码、配置文件里的某些密钥、不同业务的差异化参数。Pillar 更适合放敏感数据因为它在设计上就是按目标定向分发不会像 Grains 那样全量广播。看一下 Pillar 的目录默认在 /srv/pillar。写一个 top.sls 来指定哪个 Minion 用哪些 Pillarbase: web-test-01: - web再写 /srv/pillar/web.slsapp_name: demo listen_port: 8080然后在 SLS 中读取{% set port pillar[listen_port] %}这两个机制配合起来非常顺用 Grains 判断“它是什么机器”用 Pillar 决定“它应该怎么配置”。如果你刚开始只用一台 Master也可以暂时不用 Pillar但一旦状态文件多了建议立刻把可变参数抽到 Pillar否则 SLS 会变成一堆写死的路径和密码时间一长没人敢改。4. 高级用法与真实场景案例4.1 批量部署一个 Nginx PHP 环境说了这么多理论用一个实际案例把流程串起来。假设我临时接管了一批机器需要统一部署 Nginx PHP 的环境这里按模拟项目 X 来处理不绑定任何具体业务。我的做法是先规划目录再写状态文件最后执行验证。目录结构规划如下/srv/salt/base/ ├── top.sls ├── nginx.sls ├── php.sls └── files/ └── nginx.conf.j2top.sls 内容base: web-*: - nginx php-*: - php这样 id 以 web- 开头的机器装 Nginxphp- 开头的机器装 PHP。如果一台机器两种都要直接写两个状态即可Salt 允许并列base: web-*: - nginx - phpnginx.sls 简单写法nginx_install: pkg.installed: - name: nginx nginx_running: service.running: - name: nginx - enable: True - require: - pkg: nginx_install如果要把配置文件管理起来再加 file.managed 节点并 watch_in 到 service。这里比较容易漏的一点是nginx.conf 里的监听端口、root 路径往往因机器而异这时就要用 Pillar 来传参而不是写死在一个状态里。php.sls 类似只不过要按不同系统处理 PHP 的包名和模块。在 RedHat 系上php-fpm 是单独的包在 Debian 系上php-fpm 也在独立包里。用 grains 判断即可。执行时我喜欢先指定某一台机器试跑salt web-test-01 state.apply nginx看返回结果有没有 failed再扩大范围。如果全部成功再对整批机器执行salt web-* state.apply nginx这个习惯能帮我减少大面积误操作的风险。很多人一上来就salt * state.apply结果状态文件里有瑕疵一批机器全中招排查的时候相当难受。4.2 Salt Event 与 Runner主动监听变更Salt 的核心不止是远程执行和状态管理它还有一个事件系统。Master 和 Minion 之间每时每刻都在产生事件比如 Minion 上线、Job 结束、状态变更。如果你愿意可以写一个事件监听器实时捕捉这些消息然后触发另一个系统动作。Event 的能力在自动化发布里很有用。比如某个 Minion 执行完 state.apply 后会发出一个 job ret 事件里面包含执行结果。你可以用 Salt Runner 或外部程序订阅这个事件把结果写到数据库、推送给监控或工单系统。Salt 官方提供了 python 客户端和 API 接口这种方式比轮询更实时。我自己用 Event 做得最多的场景是把“配置变更记录”自动收集起来。每次有人对某台机器执行 state.applyEvent 里都会带有命令和目标信息。只要把这些数据接入日志系统就能知道哪台机器在什么时间被谁改过出了安全问题也更容易追溯。不过对刚入门的朋友说一句Event 和 Runner 属于进阶功能可以等基本 State 用顺了再研究。过早研究这些容易被概念淹没反而忘了 Salt 的基本盘是配置管理和命令执行。4.3 从执行结果返回到 CMDB 的思路数据中心里通常会有一张 CMDB 表记录每台服务器的配置、用途、负责人。维护这张表往往靠人工录入但服务器变了之后表格常常没人更新。Salt 可以做一件很实用的事情定时采集所有 Minion 的 grains 信息和实际运行状态写回 CMDB。实现思路也不难。先写一个 Runner 脚本或用 salt-api执行salt * grains.items拿到所有机器的硬件信息、操作系统、IP 等。再把这份数据解析成固定格式写入资产数据库。也可以用 Salt 的 Returner 机制把命令结果直接发送到数据库、Redis 或消息队列Returner 的接口相当灵活。这个思路的核心价值是“事实来源”。Salt 采集到的数据是每台机器的真实现状比人工填表靠谱得多。我见过无数 CMDB 和真实环境对不上号的场景用 Salt 做自动化采集之后至少基线数据是准确的。当然政治之敏感点别把 CMDB 搞成过于复杂的东西先解决“数据准”的问题再谈流程化。5. 常见问题与排查技巧实录5.1 master-minion 通信失败的排查通信问题是新手最容易碰到、也最容易懵的。典型症状是salt * test.ping返回一片空白或者显示 Minion did not return。排查步骤按顺序来看 keysalt-key -L确认 Minion 的 key 存在且是 Accepted 状态。如果状态是 Unaccepted接受它再试。看端口Master 默认监听 4505 和 4506。用ss -tunlp | grep 450确认端口没被防火墙挡住。云环境要注意安全组虚机环境要注意 iptables。看日志Master 和 Minion 的日志里会写明 master address 或者 authentication 相关错误。如果日志里有 Master 地址解析失败就是 /etc/salt/minion 里 master 配错了。看时间Salt 对证书和 token 有时间校验如果 Master 和 Minion 时钟差太多认证会失败。这个坑比较隐蔽我踩过一次后来在所有机器上配好 NTP 才彻底解决。另外一个之前提过的坑是 minion id 重复。如果两台机器叫同一个 id后接入的那台可能把先接入的挤掉或者认证直接失败。建议在安装时就把 id 规范化避免这种低级别问题。5.2 state 执行报错的常见坑State 文件写好后执行最常出现几种错误。第一YAML 语法错误。YAML 对缩进和空格要求特别严格我习惯用yamllint检查一遍或者在执行前先salt * state.show_sls nginx看渲染结果很多错误在渲染阶段就能发现。第二模块或者参数写错。比如某个模块在特定系统版本上不支持或者某个参数拼错了。这时候返回信息里会带有 module 相关的 traceback按模块名去查文档就好。官方文档虽然有时候写得绕但模块列表和参数列表是准的。第三watch_in 和 require 的使用顺序问题。Salt 的执行顺序由依赖关系决定不是按文件从上到下排。如果 A 模块依赖 B 模块但 B 因为某种原因被跳过A 就会报错。用 require 的时候要确保被依赖项一定存在。第四状态明明没变化但每次执行都显示 changed。这多半是文件源写错了或者模板渲染产生了非确定性输出比如每次生成都把时间戳写进文件导致文件内容一直在变。排查方式是看结果里具体是哪一步 changed再去看 module 的 diff 输出。5.3 性能与安全方面的经验Salt 的 ZeroMQ 连接效率很高但随着 Minion 数量增长Master 也需要调优。初步需要关注每个 Job 的超时时间、Minion 连接数、以及 Master 的 worker 数量。官方文档提到一个常用配置是worker_threads在大量并发执行时可以适当调大但也不能无限大否则内存会被拖垮。安全方面salt-key 一定要管好。绝不能让未认证的 Minion 长期挂在 Unaccepted 状态里。另一个我坚持的做法是不要把所有机器都放在一个 salt * 这种全量目标下随意执行。Salt 支持 Nodegroup可以把机器分组按组执行降低误操作范围。还有一个容易被忽视的点state 文件本身可能有敏感信息。Pillar 是存敏感信息的正规位置但如果你把 Pillar 或 SLS 放到了版本管理仓库里注意访问权限和加密。很多人在仓库里直接提交数据库密码这种做法风险极高。我是建议用外部加密方案或密钥管理服务在 Pillar 里引用解密后的值。Panel 再补充一条实际体会Salt 的模块非常多但很多时候不需要背完所有模块。常见操作集中在 pkg、service、file、user、cmd、cron 这几个模块上把它们的参数搞明白再遇到不确定的模块现场查文档比硬背更高效。个人经验先从一个小目标开始写到这里最后想分享一点个人想法。SaltStack 的学习曲线其实很有意思安装和第一条命令很快十分钟就能通真正难的是把 State 写得有结构、好维护、能应对机器差异。我在实际使用中最大的体会是不要想着一口气把所有功能都学会。先选一个很小的目标比如让某一批服务器统一时间同步、统一创建用户、统一安装一款监控 agent在一个小范围里跑通再逐步扩展成就感会强很多。另外一个小技巧如果你刚开始练习可以准备一台干净的虚拟机做 Minion每次练完就把快照回滚这样能反复测试也不影响别的环境。等你对 Salt 的执行逻辑有了肌肉记忆再上手大规模管理就会觉得一切都是水到渠成的事。配置管理这件事工具本身只是起点真正有价值的是你对自己服务器资产的理解和持续维护机制。Salt 能帮你把这个机制固化下来但首先你得先把它跑起来。
📝

华诺云谱内容团队

资深建站顾问 · 行业研究员

10年+企业数字化服务经验,专注智能建站、SEO优化与品牌营销,持续输出建站技巧、行业洞察与营销干货,已帮助5000+企业实现数字化增长。

你可能需要的服务

订阅华诺云谱资讯周报

每周一封,精选建站技巧、SEO与营销干货,直达邮箱。已有 8,000+ 企业主订阅,助你少走弯路。

↑