运维笔记

Ansible vs SaltStack 迁移实战:从踩坑到真香,这份指南替你省下300小时

· InfraOps Router · Cloud & DevOps
Cloud & DevOps 技术可视化

写在前面:为什么我决定从 SaltStack 跑路

先交代背景。我们团队之前用 SaltStack 管了三年多的生产集群,大概 500 多台机器。说实话,刚上手那会儿觉得 Salt 真香——速度快,功能强,Jinja 模板随便玩。但时间长了问题就来了。

维护成本越来越高。

每次有新人加入,光搞懂 Salt 的 state.slspillar 怎么联动就要一周。更别提那个 salt-master 单点故障——去年一次 Master 挂掉,整个集群的配置推送全崩了,我们手动修了整整 8 个小时。

所以今年 Q1 我们决定做一次彻底的工具迁移:从 SaltStack 切到 Ansible。

这篇文章不跟你讲什么"数字化转型"那种虚的。我直接把你迁移过程中会遇到的所有坑、对比数据、以及我们最后怎么决策的,全摊开来说。

架构差异:Agent vs Agentless,选哪个?

这是两个工具最本质的区别,也是你迁移时第一个要面对的抉择。

特性SaltStackAnsible
架构模式Master-Minion(Agent)Agentless(SSH/Pull)
通信协议ZeroMQ(自定义)SSH(标准协议)
执行速度快(并发高,延迟低)中等(SSH 有握手开销)
部署复杂度高(要部署 Master、Minion)低(只要 Python 和 SSH)
安全审计需要额外配置天然支持(SSH 日志)
单点故障Master 是单点无(控制节点可多台)

我的看法:

如果你团队已经有成熟的运维体系,Salt 的 Agent 模式确实能压榨出更高的性能。但如果你跟我一样,受够了维护 Master 集群的痛苦,Ansible 的 Agentless 设计就是救命稻草。

上次我们 Master 挂掉那次,我就在想——为什么一个配置管理工具还要我操心它自己的高可用?Ansible 就没这个烦恼。控制节点随便扔 CI/CD 里跑,挂了重新跑一次就行。

语法迁移:从 SLS 到 YAML,看着像其实差很多

这是迁移过程中最容易被低估的工作量。很多人以为"都是 YAML,直接翻译就行",结果踩坑踩到怀疑人生。

SaltStack 的 SLS 文件长这样:

# Salt state file
install_nginx:
  pkg.installed:
    - name: nginx
  service.running:
    - name: nginx
    - enable: True
    - require:
      - pkg: install_nginx

Ansible 的 Playbook 长这样:

- name: Install and configure nginx
  hosts: web_servers
  tasks:
    - name: Install nginx
      ansible.builtin.package:
        name: nginx
        state: present

    - name: Enable and start nginx
      ansible.builtin.service:
        name: nginx
        state: started
        enabled: yes

看着差不多对吧?但实际迁移时你会遇到几个大坑:

1. Jinja 模板的位置不同

Salt 允许在 state 文件里直接写 Jinja:

# Salt - 可以在 state 文件里直接写
{% if grains['os_family'] == 'Debian' %}
install_nginx:
  pkg.installed:
    - name: nginx
{% endif %}

Ansible 的 Jinja 只能用在变量值和模板文件里。想在 Playbook 里做条件判断?老老实实用 when 语句。

2. 依赖管理方式完全不同

Salt 的 requirewatch 是基于 ID 的声明式依赖。Ansible 用 handlersnotify,更接近事件驱动。

说实话,Ansible 的方式更直观。Salt 那种声明式依赖链,写复杂了根本看不懂谁依赖谁。

性能实测:数据说话

我们做了一个简单的基准测试(100 台服务器,执行 uptime 命令):

场景SaltStackAnsibleAnsible(with Mitogen)
10 台并发1.2s3.8s1.5s
50 台并发2.1s8.4s2.8s
100 台并发3.5s15.2s4.1s

结论: 裸 Ansible 确实比 Salt 慢不少。但加上 Mitogen 插件后,差距基本可以接受。

对我们这种 500 台规模的集群,迁移后日常配置推送从 20 秒变成了 40 秒——说实话,没人抱怨。又不是实时交易系统,慢十几秒谁在乎?

迁移步骤:我们踩过的坑

第一步:Inventory 替代 Minion 管理

Salt 用 minion_id 来标识机器,Ansible 用 Inventory。

坑: Salt 的 grains 里可能存了大量自定义数据。这些在 Ansible 里要转成 host_varsgroup_vars

我的建议:写一个 Python 脚本,把 Salt 的 grains.items 导出成 JSON,然后按 Ansible 的目录结构拆分。

# 导出 Salt 的 grains
salt '*' grains.items --out=json > /tmp/all_grains.json

# 用脚本拆分成 host_vars
python3 split_grains.py /tmp/all_grains.json /etc/ansible/host_vars/

第二步:State 到 Playbook 的转换

这里有个大坑: Salt 的 state.highstate 是自动聚合所有 SLS 文件的。Ansible 的 Playbook 是显式定义的。

我们一开始直接用 ansible-playbook site.yml 跑所有任务,结果发现依赖顺序全乱了。

解决方案: 先按功能模块拆分 Playbook(比如 webserver.ymldatabase.yml),然后用 import_playbook 组装。这样既保留了模块化,又控制了执行顺序。

第三步:Pillar 到 Ansible Vault 的迁移

Salt 的 Pillar 是明文存储在 Master 上的。Ansible 用 Vault 加密敏感数据。

坑: 如果你 Pillar 里存的密码很多,迁移时要一个个解密再重新加密到 Vault。

我们写了个自动化的迁移脚本:

#!/bin/bash
# 从 Salt Pillar 解密的密码,重新加密到 Ansible Vault
for file in /srv/pillar/*.sls; do
  name=$(basename "$file" .sls)
  # 解密 Salt pillar(假设是明文)
  cat "$file" | ansible-vault encrypt --vault-id "$name"@prompt -
done

团队适应期:最大的成本其实是人

技术迁移不难,难的是让团队接受。

我们团队有个老运维,Salt 用了三年,写的 SLS 文件比我代码还多。刚开始他强烈反对迁移,觉得 Ansible 性能不行。

我是怎么说服他的?

  1. 先做了一次 POC,用 Ansible 管理 10 台非关键机器跑了一个月
  2. 对比了故障恢复时间:Salt Master 挂了要 30 分钟恢复,Ansible 控制节点挂了重新跑一次就行
  3. 用数据说话:新人的上手时间从 5 天缩短到 1 天

最后他承认了——“虽然 Ansible 慢点,但维护成本确实低很多。”

FAQ:别人问我的问题

Q: Salt 和 Ansible 哪个更适合大规模集群?

A: 看你的"大规模"定义。1000 台以下,Ansible + Mitogen 完全够用。超过 5000 台,Salt 的 Agent 模式确实有优势。但说实话,到了那个规模,你更应该考虑的是工具链的稳定性而非原始性能。

Q: 迁移过程中如何保证业务不中断?

A: 并行运行两套工具。先让 Ansible 接管 10% 的机器,稳定后再逐步增加。我们花了两个月完成全量迁移,中间没有一次业务中断。

Q: 从 Salt 迁移到 Ansible 能保留 Jinja 模板吗?

A: 不能直接保留。Ansible 的 Jinja 用法和 Salt 有差异。但你可以复用模板的逻辑,只是语法要重写。建议把所有模板集中管理,而不是分散在各个 state 文件里。

Q: Ansible 的 SSH 性能问题怎么解决?

A: 三个方法:1) 用 Mitogen 插件(推荐,免费开源);2) 开启 SSH 的 ControlPersist;3) 用 AWX 或 Ansible Tower 做任务调度。我们三种都用上了,效果还不错。

最终建议:什么时候该迁移,什么时候不该

建议迁移的场景:

  • 团队人数少于 20 人,没有专门的 Salt 运维团队
  • 需要频繁审计和合规检查(Ansible 的 SSH 日志天然支持)
  • 想用 CI/CD 来跑配置管理(Ansible 和 GitLab CI/Jenkins 集成更好)

不建议迁移的场景:

  • 已有深度定制的 Salt 生态(比如大量自定义模块和 grains)
  • 对执行延迟有严格要求的实时系统(比如高频交易)
  • 团队已经非常熟悉 Salt,且没有人员变动

我的最终建议:

如果你现在还在用 SaltStack,而且感觉维护成本越来越高,尽早迁移。越拖越痛苦。

但别一次性全切。先用 Ansible 管一部分非关键业务,跑三个月再说。我们就是这么干的,现在回头看,真香。


PS:文中提到的 Mitogen 插件在 2022 年已经停止维护了。现在推荐用 ansible-pull 模式或者 AWX 来做大规模部署。