ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

SaltStack自动化运维实战:从环境搭建到State状态管理

SaltStack自动化运维实战:从环境搭建到State状态管理 最近在维护一批测试环境服务器时命令行一条条敲到怀疑人生。虽然早就听说过 SaltStack 的大名但一直没系统梳理过这次索性从零开始完整过了一遍把踩过的坑和可复用的配置方案都记录下来。如果你也刚接触 Salt或者在配 Master/Minion 时遇到各种奇怪报错这篇文章应该能帮你省下不少时间。本文会从 Salt 是什么讲起接着完成环境安装、Master/Minion 认证、常用模块命令再演示如何编写 State 文件实现自动化配置最后附上高频问题排查清单和工程化建议。整个流程我尽量按“新人可直接照做”的标准来写每一步都有对应的命令和说明。1. 背景与核心概念1.1 Salt 是什么Salt全称 SaltStack是一款基于 Python 开发的开源基础设施管理工具。它采用 C/S 架构由一个 Salt Master 控制节点和若干个 Salt Minion 被管理节点组成。Master 通过高效的 ZeroMQ 消息队列与 Minion 通信下发命令、分发配置、收集执行结果。简单理解Salt 就是一台“指挥中心”控制成百上千台服务器的“遥控器”。你不需要逐一 SSH 登录每台机器只要在 Master 上执行一条命令就能让指定的一批 Minion 同时执行安装软件、修改配置、启动服务等操作。Salt 也支持 State 状态管理可以把服务器的最终状态写成配置文件然后持续维护这个状态类似 Ansible 的 Playbook 思路但 Salt 的通信模型和数据管理能力在规模化场景下有独特优势。1.2 Salt 解决什么问题在日常运维中常见痛点包括服务器数量多手动逐台操作效率低。配置分散不同环境的软件版本容易漂移。Shell 脚本缺乏统一管理难以复用和追溯。缺少集中式的配置查看和变更记录手段。Salt 把“远程命令执行”和“配置状态管理”统一到一套体系里。你可以在 Salt Master 上批量执行命令也可以维护一套 State 文件让所有 Minion 自动对齐到目标配置状态。这种“声明式管理”方式对保证测试环境与生产环境的一致性很有帮助。1.3 适合谁来学如果你属于下面几类人群Salt 值得系统性学习运维工程师管理大量服务器希望实现自动化部署和配置管理。后端开发者需要维护多套环境想用代码管理服务器配置。测试工程师经常搭建和清理测试环境希望一键准备环境。学生或自学用户想了解主流配置管理工具Salt 是很好的学习对象。学习 Salt 之前最好具备基础的 Linux 命令行操作能力了解 SSH、YAML、Python 基础语法会更轻松。不过文章会尽量降低门槛关键命令都会完整给出。2. 环境准备与版本说明2.1 系统与软件要求Salt 支持主流 Linux 发行版、Windows、macOS。本文演示以 CentOS 7 和 Ubuntu 20.04 为例其他系统思路一致只是软件源和包管理命令不同。版本方面Salt 3006 LTS 是目前比较稳定的长期支持版本Salt Project 官方推荐生产环境使用 LTS 系列。具体版本号请根据你的操作系统和官方源实际情况调整本文重点演示配置思路不强行绑定某一个具体版本。2.2 准备两台测试主机为了完整体验 Salt我们需要角色主机名操作系统IP 示例Mastersalt-masterCentOS 7192.168.56.101Minionsalt-minion-01Ubuntu 20.04192.168.56.102说明如果你的机器配置不足也可以在一台机器上同时安装 Master 和 Minion用主机名localhost或127.0.0.1代替 IP不过要理解 Master 和 Minion 是两种不同角色分离部署更贴近生产实际。2.3 配置 /etc/hosts为了便于识别建议在两台机器上同时配置 hosts。在/etc/hosts末尾增加192.168.56.101 salt-master 192.168.56.102 salt-minion-01配置完成后用ping salt-master验证互通。如果网络环境有防火墙需要提前放行 Salt 使用的端口后面会详细说明。3. 安装 Salt Master 与 Salt Minion3.1 安装 Salt Master以 CentOS 7 为例安装 Master 端# 安装 SaltStack 官方仓库以 RHEL/CentOS 7 为例 sudo yum install -y https://repo.saltproject.io/salt/py3/3006.x/rhel/7/x86_64/latest/salt-repo-latest-3006.x.rhel7.noarch.rpm # 更新仓库缓存 sudo yum clean expire-cache # 安装 salt-master sudo yum install -y salt-masterUbuntu 20.04 安装方式# 添加 SaltStack 官方 PPA 源 sudo add-apt-repository -y ppa:saltstack/salt sudo apt-get update # 安装 salt-master sudo apt-get install -y salt-master版本说明不同操作系统对应的源地址可能随版本调整如果上面仓库地址失效请前往 SaltProject 官方仓库页面获取对应系统的源配置。生产环境建议固定 LTS 版本避免升级引起兼容性问题。3.2 安装 Salt Minion在 Minion 主机Ubuntu 20.04上执行# 添加 SaltStack 官方源 sudo add-apt-repository -y ppa:saltstack/salt sudo apt-get update # 安装 salt-minion sudo apt-get install -y salt-minion如果是 CentOS 7 Minion使用sudo yum install -y https://repo.saltproject.io/salt/py3/3006.x/rhel/7/x86_64/latest/salt-repo-latest-3006.x.rhel7.noarch.rpm sudo yum clean expire-cache sudo yum install -y salt-minion3.3 配置 Minion 指向 Master安装完成后需要修改 Minion 配置文件让它知道 Master 在哪。编辑/etc/salt/minionsudo vi /etc/salt/minion找到或添加以下配置master: salt-master id: salt-minion-01说明masterMaster 的主机名或 IP这里是salt-master。idMinion 的唯一标识默认是主机名建议显式指定便于后续管理。保存后启动 Minionsudo systemctl start salt-minion sudo systemctl enable salt-minion3.4 启动 Salt Master回到 Master 主机启动并设置开机自启sudo systemctl start salt-master sudo systemctl enable salt-master用以下命令确认服务状态sudo systemctl status salt-master sudo systemctl status salt-minion如果出现active (running)说明服务已经启动。3.5 防火墙端口放行Salt Master 默认监听以下端口端口用途4505ZeroMQ 消息发布端口4506Minion 与 Master 通信端口如果开启了防火墙需要放行这两个端口。CentOS 7 示例sudo firewall-cmd --permanent --zonepublic --add-port4505/tcp sudo firewall-cmd --permanent --zonepublic --add-port4506/tcp sudo firewall-cmd --reloadUbuntu 如果使用 ufw执行sudo ufw allow 4505/tcp sudo ufw allow 4506/tcp端口和认证是新手最容易卡住的环节下面专门展开讲。4. 核心概念密钥认证机制4.1 为什么需要认证Salt Master 和 Minion 之间通过 ZeroMQ 通信为了防止未经授权的机器接入Salt 内置了一套基于 AES 和 PKI 的认证机制。每当 Minion 第一次启动并连接 Master 时会生成一对密钥把公钥发给 Master 申请加入。Master 必须显式接受这个 Minion 的公钥之后二者才能正常通信。这个设计避免了一个重要风险局域网内出现伪造 Minion 后恶意接管你的基础设施。所以“接受密钥”这个动作是 Salt 使用的第一道安全关卡。4.2 查看未接受的密钥在 Master 上执行sudo salt-key -L输出类似Accepted Keys: Denied Keys: Unaccepted Keys: salt-minion-01 Rejected Keys:可以看到salt-minion-01出现在Unaccepted Keys列表中说明它已经发起请求等待管理员审批。4.3 接受密钥执行以下命令接受密钥sudo salt-key -a salt-minion-01如果确认所有未接受密钥都可信也可以sudo salt-key -A接受后再次查看sudo salt-key -L输出中的Accepted Keys列表会出现salt-minion-01。4.4 测试连接认证通过后在 Master 上执行 Salt 自带的测试命令sudo salt salt-minion-01 test.ping预期输出salt-minion-01: True看到True说明 Master 到 Minion 的命令通路已经完全打通了。如果这里失败后面所有操作都无法继续所以这是必须跨过的第一道关卡。5. 远程执行模块入门5.1 Salt 命令的基本格式Salt 远程执行命令的格式非常统一salt 目标匹配规则 模块名.函数名 [参数]例如sudo salt salt-minion-01 cmd.run uptime这个命令表示在目标 Minionsalt-minion-01上执行 shell 命令uptime。cmd.run是 Salt 提供的一个核心执行模块用于在 Minion 上执行任意命令。5.2 目标匹配规则目标匹配规则是 Salt 批量管理的基础。常见写法匹配写法示例说明精确匹配 IDsalt salt-minion-01 test.ping匹配指定的 Minion ID通配符salt salt-minion-* test.ping匹配所有以 salt-minion- 开头的 Minion列表匹配salt -L salt-minion-01,salt-minion-02 test.ping匹配多个明确 ID正则匹配salt -E salt-minion-0[12] test.ping使用正则表达式匹配所有 Minionsalt * test.ping匹配所有已接受的 Minion示例# 匹配所有 Minion sudo salt * test.ping # 使用通配符 sudo salt salt-minion-* test.ping # 使用列表 sudo salt -L salt-minion-01,salt-minion-02 test.ping注意通配符要用引号包起来避免被 shell 提前展开。5.3 常用执行模块Salt 内置了大量执行模块下面挑选几个高频模块演示。cmd.run 执行 shell 命令sudo salt salt-minion-01 cmd.run free -h这个命令会返回 Minion 的内存使用情况适合临时查看远程机器状态。pkg.install 安装软件包sudo salt salt-minion-01 pkg.install nginxSalt 会根据 Minion 的操作系统自动选择对应的包管理工具在 Ubuntu 上等效于apt-get install nginx在 CentOS 上等效于yum install nginx。这是 Salt 跨平台管理的重要能力。service.start 启动服务sudo salt salt-minion-01 service.start nginxservice.status 查看服务状态sudo salt salt-minion-01 service.status nginxfile.write 写入文件sudo salt salt-minion-01 file.write /tmp/hello.txt Hello from Salt!cp.get_file 从 Master 分发文件如果想从 Master 端分发文件到 Minion需要先把文件放在 Master 的 file_roots 目录下。默认目录是/srv/salt文件放在/srv/salt/files/hello.txt然后执行sudo salt salt-minion-01 cp.get_file salt://files/hello.txt /tmp/hello.txt5.4 命令执行结果解析Salt 命令返回的是 YAML 格式的结构化数据。例如sudo salt salt-minion-01 test.ping返回salt-minion-01: True第一行是目标 Minion ID第二行是返回值。当多台 Minion 执行结果不一致时你可以快速看到哪些机器成功、哪些失败这是批量运维的基本排查方式。如果某个 Minion 返回Minion did not return. [No response]说明命令可能超时或 Minion 网络异常后面在常见问题部分会详细说明排查思路。6. Salt State 状态管理实战6.1 State 是什么远程执行模块解决的是“临时执行一条命令”的问题而 State 解决的是“让服务器达到并保持某个目标状态”的问题。State 文件使用 YAML 编写声明某个软件应该安装、某个服务应该启动、某个文件应该存在且内容正确然后 Salt 会在 Minion 上校验并自动修正状态。使用 State 管理配置有很多好处幂等性重复执行不会产生重复副作用。可追溯所有配置逻辑集中存放便于版本管理。可批量一次 apply所有目标机器统一生效。声明式你告诉 Salt “最终要什么”而不是“依次做什么”。6.2 目录结构State 文件默认存放在 Master 的/srv/salt目录。sudo mkdir -p /srv/salt一个最简单的 State 目录结构如下/srv/salt/ ├── top.sls └── nginx.slstop.sls入口文件定义哪些 Minion 应用哪些 State。nginx.sls具体的 State 文件描述 nginx 安装和启动的期望状态。6.3 编写 top.sls创建/srv/salt/top.slsbase: salt-minion-01: - nginx说明baseSalt 默认的环境名称可以理解为配置环境。salt-minion-01目标 Minion 匹配规则这里指定单台机器。- nginx要应用的 State 文件对应/srv/salt/nginx.sls。如果希望所有 Minion 都应用可以写成base: *: - nginx6.4 编写 nginx.sls创建/srv/salt/nginx.slsnginx: pkg.installed: - name: nginx service.running: - name: nginx - enable: True - require: - pkg: nginx这个 State 文件表达了两层意思使用pkg.installed确保nginx软件包已安装。使用service.running确保nginx服务处于运行状态并设置为开机自启。require表示服务启动依赖 nginx 软件包安装完成。这种声明式写法很直观每一段都描述一个“应该是什么样”Salt 会去检查并处理。6.5 应用 State在 Master 上执行sudo salt salt-minion-01 state.apply如果想只应用某一个 State 文件可以指定sudo salt salt-minion-01 state.apply nginx执行过程中Salt 会输出每个步骤的执行结果salt-minion-01: ---------- ID: nginx Function: pkg.installed Result: True Comment: Package nginx is already installed Started: 10:23:45.678901 Duration: 234.567 msResult: True该步骤执行成功。Result: False该步骤失败需要检查Comment中的错误原因。Result: None该步骤被跳过或没有改变一般表示状态已经符合预期。重复执行state.apply时如果一切正常你会看到很多Comment为Package nginx is already installed或Service nginx is already running的“无变更”输出这就是 State 管理的幂等效果。6.6 增加配置文件管理实际项目中不仅需要安装软件还需要把自定义配置分发到前端。假设我们要为 nginx 添加自定义 index.html可以这样做。先创建文件目录sudo mkdir -p /srv/salt/files在 Master 上创建/srv/salt/files/index.html!DOCTYPE html html head titleWelcome to Salt/title /head body h1Hello, SaltStack!/h1 pThis page is managed by Salt State./p /body /html再创建/srv/salt/nginx_files.sls/usr/share/nginx/html/index.html: file.managed: - source: salt://files/index.html - user: root - group: root - mode: 644 - require: - pkg: nginx这段 State 表示目标文件/usr/share/nginx/html/index.html应该由 Master 端salt://files/index.html内容来管理属主和权限分别为 root:root 和 644。更新 top.slsbase: salt-minion-01: - nginx - nginx_files然后应用sudo salt salt-minion-01 state.apply执行完成后在 Minion 上访问http://192.168.56.102/就能看到自定义页面说明文件已经正确下发。6.7 增加服务重载逻辑配置文件变化后需要让服务重新加载配置。在 Salt 中可以用watch监听文件变化并重启服务。修改/srv/salt/nginx.slsnginx: pkg.installed: - name: nginx service.running: - name: nginx - enable: True - require: - pkg: nginx - watch: - file: /etc/nginx/nginx.conf然后建立/srv/salt/nginx_conf.sls/etc/nginx/nginx.conf: file.managed: - source: salt://files/nginx.conf - user: root - group: root - mode: 644 - require: - pkg: nginx这里watch和require的区别是require仅确保前置条件完成。watch除了确保前置条件完成如果被监控对象发生变化还会触发当前 state 重启或重载服务。生产环境中“配置变更后自动重载服务”是很常见且危险的操作适合测试环境验证后再推广。7. Grains 与 Pillar 介绍7.1 GrainsMinion 的静态属性Grains 是 Minion 启动时收集的静态信息包括操作系统、内核版本、IP 地址、CPU 架构等。可以把它理解为每台 Minion 的“档案”。查看全部 Grainssudo salt salt-minion-01 grains.items查看指定项sudo salt salt-minion-01 grains.item osfinger sudo salt salt-minion-01 grains.item ipv4Grains 常用在目标匹配中。例如只匹配 Ubuntu 系统sudo salt -G os:Ubuntu test.ping这个命令会选出所有操作系统为 Ubuntu 的 Minion 执行测试。7.2 Pillar敏感数据与差异化配置Pillar 是 Salt 中用于存放敏感数据和差异化配置的模块。与 Grains 不同Pillar 是 Master 端下发的只有指定的 Minion 才能看到对应的数据适合存放密码、密钥、应用端口、环境标识等。默认 Pillar 目录是/srv/pillar。sudo mkdir -p /srv/pillar创建/srv/pillar/top.slsbase: salt-minion-01: - app_config创建/srv/pillar/app_config.slsapp: port: 8080 debug: false database_password: S3curePassw0rd在 Minion 上验证sudo salt salt-minion-01 pillar.itemsState 文件中可以通过pillar函数读取app-config: file.managed: - name: /etc/myapp/config.yaml - contents: | port: {{ pillar[app][port] }} debug: {{ pillar[app][debug] }}Pillar 是区分不同环境、不同项目配置的核心工具。一般建议环境无关的信息用 Grains环境相关信息用 Pillar敏感数据用 Pillar 并配合权限管理。7.3 Jinja 模板Salt State 文件支持 Jinja 模板可以动态生成配置内容。例如{% if grains[os] Ubuntu %} nginx_package: nginx {% else %} nginx_package: nginx {% endif %}虽然这个例子中最终结果一样但你已经可以看到 Jinja 在 Salt 中的位置它让 State 文件能够根据 Minion 的属性、Pillar 数据、甚至是导入的其他数据生成不同的执行逻辑。复杂环境下这是把一套 State 应用到多种服务器类型的关键手段。8. 常见问题与排查思路Salt 使用过程中新手最容易碰到下面这些问题。我按“现象 - 原因 - 解决思路”整理成表格方便快速对照。问题现象常见原因解决思路test.ping返回Minion did not returnMinion 未启动、网络不通、密钥未接受检查 Minion 服务状态确认 4505/4506 端口连通执行salt-key -L查看密钥状态salt-key -L看不到 MinionMinion 配置的 Master 地址错误检查/etc/salt/minion中master配置确认 hosts 解析正常Minion 启动时报KeyError系统缺少依赖或者版本不兼容查看/var/log/salt/minion日志确认安装版本和依赖完整State 执行报错State file not found文件路径或文件名写错确认/srv/salt目录下文件存在top.sls 引用的名称必须对应.sls文件名文件下发后内容没变化file.managed未加watch服务没重载修改 State 增加watch监听执行service.reload执行过程极慢或超时Minion 数量多或命令阻塞增加timeout参数例如salt --timeout30 * test.ping报错Authentication error密钥状态异常在 Master 和 Minion 上删除旧密钥重新接受8.1 查看日志排查问题首先要看日志。Master 日志sudo tail -f /var/log/salt/masterMinion 日志sudo tail -f /var/log/salt/minion日志中通常会明确写出报错原因比猜更高效。例如Minion 反复提示认证失败时日志里会显示密钥指纹不匹配的信息这时直接清空密钥重新认证即可。8.2 重置 Minion 密钥如果 Minion 重建过系统或者密钥文件损坏需要清除旧的密钥关系。先在 Master 端删除对应密钥sudo salt-key -d salt-minion-01然后到 Minion 端删除自己的密钥文件sudo rm -f /etc/salt/pki/minion/minion_master.pub sudo systemctl restart salt-minion接着重新在 Master 上接受密钥即可。注意这样操作会让 Minion 与 Master 之间建立全新的信任关系属于重置操作需要确认没有其他服务依赖旧的密钥关系。8.3 检查网络连通性如果 Minion 无法连接 Master可以在 Minion 上执行telnet salt-master 4506或者用ncnc -vz salt-master 4505 nc -vz salt-master 4506两个端口都能连通说明网络层没有问题。9. 最佳实践与工程建议9.1 命名规范给 Minion 设置 ID 时建议采用统一格式。例如prod-web-001test-db-002dev-app-001格式建议环境 角色 序号便于后期使用通配符匹配和脚本处理。避免使用默认主机名因为主机名可能被 DHCP 或其他服务修改。9.2 目录组织建议按业务模块组织 State 目录例如/srv/salt/ ├── top.sls ├── base/ │ ├── init.sls │ ├── packages.sls │ └── users.sls ├── nginx/ │ ├── init.sls │ ├── files/ │ │ └── nginx.conf │ └── conf.sls ├── app/ │ ├── init.sls │ ├── files/ │ │ └── app.properties │ └── service.sls └── monitor/ └── init.sls每个业务模块一个目录目录内包含 State 文件和 files 子目录。这样后续维护、定位问题都会更容易。9.3 State 文件拆分原则不要把所有配置塞进一个巨大的 sls 文件。建议一个 sls 文件只描述一个业务单元。公共基础配置放base模块。涉及敏感信息的配置用 Pillar 下发不要写死在 State 文件里。文件内容要标注来源方便别人理解。9.4 配置变更流程Salt 在生产环境会直接影响大批机器任何变更建议走下面的最小化验证流程先在测试环境的一台 Minion 上执行state.apply。检查执行结果和业务日志。再逐步扩大到测试环境全部机器。最后针对生产环境分批发布避免一次性影响所有节点。变更前记录当前 State 状态必要时用版本控制管理 State 文件方便回滚。9.5 安全注意事项严格控制salt-key的接受权限建议由专人管理。不要在生产环境随意执行salt * cmd.run 任意危险命令尤其是涉及删除、格式化、数据覆盖的操作。Pillar 中的敏感数据要限制访问范围配合文件权限和密钥管理。定期更新 Salt 版本关注官方安全公告。对 Master 主机做好登录审计和安全加固因为拿到 Master 权限等同于拿到所有 Minion 权限。9.6 日志与监控建议将 Salt 执行记录接入日志系统。可以用 Salt 自身的事件总线Event Bus监听任务执行事件也可以定期执行state.apply并记录结果让定时巡检自动发现配置漂移。10. 总结与学习路线到这一步你已经从零完成了 Salt 环境的搭建掌握了 Master/Minion 的密钥认证、远程执行命令、State 状态管理、Grains 和 Pillar 的核心用法也知道了遇到常见报错时该从哪里排查。这套能力在实际工作中能解决的问题很多比如批量安装软件、快速下发配置、统一维护多个环境、实现测试环境自动准备等。如果后续希望继续深入可以按下面的方向进阶学习 Salt 的更多执行模块比如 scheduled jobs计划任务、grains 自定义、reactor 响应器。掌握 Salt SSH 模式适合不安装 Minion 的临时场景。学习 Salt 的多 Master 架构和消息队列高可用方案。使用 Salt 与 CI/CD 流程集成实现发布自动化。探索 Salt 的扩展开发用 Python 自定义执行模块和 State 模块。在实际项目中优先要做好两件事一是把 State 文件纳入 Git 管理所有变更可追溯二是从小范围实验开始逐步扩大自动化覆盖面。Salt 的能力很强但只有在一个可控、可观察的环境中使用才能真正提升效率而不是引入新的混乱。如果这篇文章对你有帮助可以收藏备用。接下来我建议直接动手准备两台虚拟机把安装和认证跑通再写一个简单的 nginx State 文件体验一次从零到自动化的完整过程。遇到问题不要怕多看看 Master 和 Minion 的日志绝大多数问题都能从日志里找到答案。
返回列表