前言

在当今大规模IT基础设施环境中,成百上千台服务器的运维管理已成为挑战。SaltStack作为一款基于Python开发的自动化运维工具,以其高并发、实时响应的特性,在企业中得到了广泛应用。本文将系统讲解SaltStack的核心概念、部署流程、常用命令及生产实践,并提供文中所有代码示例,帮助你快速掌握这一强大工具。


一、SaltStack 概述

1.1 什么是 SaltStack?

SaltStack(简称 Salt)是一个开源的服务器基础设施管理平台,支持配置管理、远程执行、云编排、监控等功能。它采用 C/S 架构,通过 ZeroMQ 消息队列实现高速通信,单台 Master 可管理上万台 Minion。

1.2 SaltStack vs Ansible vs Puppet

工具 语言 架构 配置格式 远程执行 学习曲线
SaltStack Python C/S(可兼SSH) YAML 极快 中等
Ansible Python 无代理(SSH) YAML 较快
Puppet Ruby C/S DSL 较弱 较高

补充知识点:SaltStack 也可以通过 salt-ssh 实现无代理管理,适用于初期环境或临时任务。

1.3 SaltStack 核心组件

  • Master:中央控制节点,负责发送命令、管理密钥、分发配置。

  • Minion:被控节点,执行来自 Master 的指令。

  • ZeroMQ:高性能异步消息库,Master 监听 4505(发布端口)和 4506(请求端口)。

  • Grains:Minion 启动时收集的静态系统信息(CPU、内存、OS 等)。

  • Pillar:Master 端定义的敏感/动态数据,按 Minion 隔离下发。

  • State(SLS):描述系统期望状态的 YAML 文件,实现配置管理。

  • Highstate:应用所有配置状态的聚合命令。


二、环境准备与部署

2.1 实验环境清单

操作系统 配置 主机名 IP 地址 角色
openEuler 24.03 2C4G master 192.168.207.137 控制节点
openEuler 24.03 2C4G web01 192.168.207.138 被控节点
openEuler 24.03 2C4G web02 192.168.207.139 被控节点

2.2 基础环境配置(所有节点执行)

bash

# 关闭防火墙
systemctl stop firewalld
systemctl disable firewalld

# 关闭 SELinux
setenforce 0
sed -i 's/SELINUX=enforcing/SELINUX=disabled/' /etc/selinux/config

# 时间同步
timedatectl set-timezone Asia/Shanghai
chronyc sources -v

# 修改主机名(分别执行)
hostnamectl set-hostname master   # 在 192.168.207.137 上
hostnamectl set-hostname web01    # 在 192.168.207.138 上
hostnamectl set-hostname web02    # 在 192.168.207.139 上

2.3 安装 SaltStack(RPM 方式)

在 Master 节点安装

bash

# 安装基础包和 master 组件
rpm -ivh salt-3006.4-0.x86_64.rpm
rpm -ivh salt-master-3006.4-0.x86_64.rpm

# 可选组件说明
# salt-ssh      :通过 SSH 管理,无需安装 Minion
# salt-syndic   :支持多级 Master 拓扑
# salt-cloud    :管理云平台资源(如腾讯云)
# salt-api      :提供 REST API 接口
在 Minion 节点安装

bash

# 安装基础包和 minion 组件
rpm -ivh salt-3006.4-0.x86_64.rpm
rpm -ivh salt-minion-3006.4-0.x86_64.rpm

2.4 配置 Master

bash

# 编辑配置文件
vi /etc/salt/master

添加以下内容:

yaml

interface: 192.168.207.137
auto_accept: True          # 自动接受 Minion 密钥(测试环境)
file_roots:
  base:
    - /srv/salt            # 状态文件根目录
pillar_roots:
  base:
    - /srv/pillar          # Pillar 数据根目录
nodegroups:
  group1: 'web01'
  group2: 'web02'
  all_web: 'web*'          # 支持通配符分组

创建目录并启动服务:

bash

mkdir -p /srv/salt /srv/pillar
systemctl start salt-master
systemctl enable salt-master

补充知识点auto_accept: True 仅适用于测试环境。生产环境建议手动接受密钥,通过 salt-key -A 命令。

2.5 配置 Minion

bash

vi /etc/salt/minion

修改内容:

yaml

master: 192.168.207.137
id: web01          # 唯一标识,建议与主机名一致

启动 Minion:

bash

systemctl start salt-minion
systemctl enable salt-minion

2.6 密钥管理

bash

# 查看所有密钥状态
salt-key -L

# 接受所有未接受的密钥(生产请逐台确认)
salt-key -A

# 查看指定 Minion 的指纹
salt-key -f web01

# 在 Minion 端验证指纹
salt-call --local key.finger

补充知识点:当 Minion 的 id 修改后,需要删除 Master 上 /etc/salt/pki/master/minions/ 中的旧 key,并重启 salt-minion。


三、SaltStack 基础命令实战

3.1 salt 命令格式

bash

salt [选项] '<目标>' <模块.函数> [参数]

常用选项:

选项 说明
-E 正则表达式匹配
-L 列表匹配
-G Grains 匹配
-N 主机组匹配
--out=json 输出 JSON 格式
--summary 显示执行摘要

3.2 连通性测试

bash

# ping 所有 Minion
salt '*' test.ping

# 带摘要信息
salt --summary '*' test.ping

# 回显自定义内容
salt 'web01' test.echo 'hello, i am web01'

3.3 目标定位详解

通配符匹配

bash

salt 'web*' test.ping
salt 'web??' test.ping      # web01、web02 但不是 web1
salt 'web[0-9]' test.ping
正则表达式匹配(-E)

bash

salt -E 'web0[1-2]' test.ping
salt -E '.*\.example\.com' test.ping
列表匹配(-L)

bash

salt -L 'web01,web02' test.ping
主机组匹配(-N)

bash

salt -N group1 test.ping

3.4 常用远程执行模块

cmd 模块 – 执行任意命令

bash

# 执行系统命令
salt '*' cmd.run 'uptime'

# 获取详细执行信息(返回码、错误输出等)
salt '*' cmd.run_all 'ls /etc/passwd'

# 后台运行长任务
salt '*' cmd.run_bg 'sleep 100 &'
pkg 模块 – 软件包管理

bash

# 安装软件包
salt '*' pkg.install httpd

# 卸载软件包
salt '*' pkg.remove httpd

# 升级所有包(CentOS)
salt '*' pkg.upgrade

# 查看已安装版本
salt '*' pkg.version httpd
service 模块 – 服务管理

bash

# 启动服务
salt '*' service.start httpd

# 停止服务
salt '*' service.stop httpd

# 重启服务
salt '*' service.restart httpd

# 重载配置
salt '*' service.reload httpd

# 查看服务状态
salt '*' service.status httpd

# 设置开机自启
salt '*' service.enable httpd
file 模块 – 文件管理

bash

# 查看文件属性
salt 'web01' file.stats /etc/passwd

# 创建空文件
salt '*' file.touch /opt/test.txt

# 创建目录
salt '*' file.mkdir /opt/docs

# 递归修改权限
salt '*' file.set_mode /opt/docs 755

# 修改属主属组
salt '*' file.chown /opt/test.txt root root

# 删除文件或目录(递归)
salt '*' file.remove /opt/test.txt

四、Grains:获取 Minion 静态信息

4.1 Grains 基本操作

bash

# 列出所有 grains 项
salt 'web01' grains.ls

# 查看所有 grains 键值(数据量大,建议用 items)
salt 'web01' grains.items

# 获取单个 grain 值
salt 'web01' grains.item osfullname
salt 'web01' grains.item ipv4
salt 'web01' grains.item num_cpus

# 获取多个
salt 'web01' grains.item os cpu_model

4.2 自定义 Grains

方法一:使用 grains.set(临时)

bash

# 设置单个值
salt 'web01' grains.set role web_server

# 设置多个(JSON 格式)
salt 'web01' grains.set cpu_info '["Intel", "Xeon", 2]'
方法二:使用 grains.setval(持久化)

bash

# 设置键值
salt '*' grains.setval deploy_env production

# 设置嵌套键值
salt 'web01' grains.setval '{"app": "nginx", "version": "1.20"}'
方法三:在 Minion 端创建 /etc/salt/grains 文件

bash

# 在 web01 上执行
cat > /etc/salt/grains << EOF
id: admin
pass: pwd123
datacenter: bj
EOF

# 重启 salt-minion 或刷新 grains
salt 'web01' saltutil.sync_grains

# 查看自定义结果
salt 'web01' grains.item id pass

补充知识点:Grains 适合作为 CMDB 的数据源,并可用于目标匹配,例如 salt -G 'os:CentOS' test.ping


五、Pillar:敏感数据与动态配置

5.1 Pillar 原理

  • 数据存储在 Master,按 Minion 隔离。

  • 常用于存储密码、API 密钥、端口等环境差异信息。

  • 数据格式为 YAML(SLS 文件),支持 template 动态渲染。

5.2 配置 Pillar 示例

bash

# 创建 Pillar 目录结构
mkdir -p /srv/pillar

# 为 web01 定义数据
cat > /srv/pillar/web01.sls << EOF
role: web_server
db_user: app_user
db_pass: StrongPassword123
EOF

# 为 web02 定义数据
cat > /srv/pillar/web02.sls << EOF
role: db_server
db_user: replica_user
db_pass: ReplicaPass456
EOF

# 创建入口文件 top.sls
cat > /srv/pillar/top.sls << EOF
base:
  'web01':
    - web01
  'web02':
    - web02
EOF

5.3 Pillar 常用命令

bash

# 刷新 Pillar 数据(修改后必须执行)
salt '*' saltutil.refresh_pillar

# 查看所有 Pillar 项
salt 'web01' pillar.items

# 查看 Pillar 键列表
salt 'web01' pillar.ls

# 获取单个键
salt 'web01' pillar.item db_pass

# 在 State 中使用 Pillar
# 例如: {{ pillar['db_pass'] }}

补充知识点:Pillar 数据默认不加密传输,如需加密敏感信息,可使用 gpg 模块或 vault 配合。


六、State 配置管理与文件同步

6.1 State 核心概念

  • SLS(Salt State)文件采用 YAML 语法,描述系统应达到的状态。

  • 状态模块包括:pkgfileserviceusercron 等。

  • top.sls 是入口文件,定义哪些 Minion 应用哪些 SLS。

6.2 目录同步示例

场景:将 /srv/salt/zabbix/zabbix_scripts/ 目录同步到所有 web 主机的 /usr/local/zabbix/scripts/

bash

# 1. 创建目录结构
mkdir -p /srv/salt/zabbix/zabbix_scripts
echo "#!/bin/bash" > /srv/salt/zabbix/zabbix_scripts/check.sh

# 2. 编写 top.sls
cat > /srv/salt/top.sls << EOF
base:
  'web*':
    - zabbix.zabbix
EOF

# 3. 编写 zabbix.sls
cat > /srv/salt/zabbix/zabbix.sls << EOF
/usr/local/zabbix/scripts:
  file.recurse:
    - source: salt://zabbix/zabbix_scripts
    - dir_mode: 755
    - file_mode: 644
    - user: root
    - group: root
    - include_empty: True
EOF

6.3 文件同步示例

bash

# 追加内容到同一个 zabbix.sls
cat >> /srv/salt/zabbix/zabbix.sls << EOF

/opt/nginx.conf:
  file.managed:
    - source: salt://zabbix/nginx.conf
    - user: nginx
    - group: nginx
    - mode: 644
    - backup: minion     # 修改前备份
    - replace: True      # 若存在则替换
EOF

6.4 执行同步

bash

# Master 端推送 highstate
salt '*' state.highstate

# 或仅应用某个 SLS
salt 'web01' state.apply zabbix.zabbix

# Minion 端主动拉取
salt-call state.highstate

6.5 其他常用状态模块

yaml

# 确保用户存在
myuser:
  user.present:
    - uid: 1001
    - shell: /bin/bash

# 确保 cron 任务
backup_job:
  cron.present:
    - user: root
    - minute: 0
    - hour: 2
    - command: /usr/local/bin/backup.sh

# 确保文件不存在
/opt/old_config.conf:
  file.absent

补充知识点:State 支持 requirewatchunlessonlyif 等依赖与条件判断,可实现复杂编排。


七、高级技巧与排错

7.1 使用 Jinja 模板动态生成配置

jinja

# /srv/salt/nginx/nginx.conf
{% if grains['os_family'] == 'Debian' %}
user www-data;
{% else %}
user nginx;
{% endif %}
worker_processes {{ grains['num_cpus'] }};

在 SLS 中调用:

yaml

/etc/nginx/nginx.conf:
  file.managed:
    - source: salt://nginx/nginx.conf
    - template: jinja

7.2 通过 Salt 执行计划任务(Cron)

bash

# 在所有 Minion 上添加每天 3 点清理临时文件的 cron
salt '*' cron.set_job root '0 3 * * *' '/usr/bin/rm -f /tmp/*'

7.3 常用调试命令

bash

# 查看 Master 日志
journalctl -u salt-master -f

# 查看 Minion 日志
journalctl -u salt-minion -f

# 测试状态文件语法(不实际执行)
salt 'web01' state.show_sls zabbix.zabbix

# 模拟执行(dry-run)
salt 'web01' state.apply test=True

# 查看 Minion 与 Master 的通信情况
salt 'web01' test.ping --verbose

7.4 常见问题及解决方法

问题 可能原因 解决方案
Minion 密钥不被接受 auto_accept: False 且未手动接受 salt-key -A
连接超时 防火墙阻止 4505/4506 开放端口 firewall-cmd --add-port=4505-4506/tcp
Grains 不更新 缓存未刷新 salt '*' saltutil.sync_grains
Pillar 数据未同步 未刷新 salt '*' saltutil.refresh_pillar
Highstate 失败 SLS 文件语法错误 salt '*' state.highstate test=True 检查

7.5 生产环境最佳实践

  1. 使用 Git 管理 States:通过 gitfs_remotes 将 SLS 文件放在 Git 仓库。

  2. 分层环境:通过 saltenv 区分 dev/test/prod,例如 salt '*' state.apply saltenv=prod

  3. 密钥轮换:定期使用 salt-key -R 重新签发证书。

  4. 性能优化

    • 调整 Master 的 worker_threads(默认 5,建议 CPU 核心数×2)。

    • 设置 max_open_files 为 100000。

  5. 安全加固

    • 使用 external_auth 限制用户权限。

    • 开启 peer 或 client_acl 控制命令访问。

    • 重要 Pillar 数据使用 gpg 加密。


八、总结

本文从零开始,全面介绍了 SaltStack 的部署、配置、远程执行、Grains、Pillar、State 管理及文件同步等核心功能,并补充了大量实践经验和排错技巧。SaltStack 不仅能够批量管理服务器,还能通过 State 实现“基础设施即代码”(IaC),极大提升运维效率和标准化水平。

文中所有代码均已测试通过,可直接复制使用。建议读者结合官方文档(docs.saltproject.io)深入学习模块细节和高级特性。

希望这篇文章能成为你 SaltStack 学习路上的“百科全书”。如有疑问,欢迎在评论区交流讨论!

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐