SaltStack部署应用:从入门到实战
前言
在当今大规模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 语法,描述系统应达到的状态。
-
状态模块包括:
pkg、file、service、user、cron等。 -
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 支持
require、watch、unless、onlyif等依赖与条件判断,可实现复杂编排。
七、高级技巧与排错
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 生产环境最佳实践
-
使用 Git 管理 States:通过
gitfs_remotes将 SLS 文件放在 Git 仓库。 -
分层环境:通过
saltenv区分 dev/test/prod,例如salt '*' state.apply saltenv=prod。 -
密钥轮换:定期使用
salt-key -R重新签发证书。 -
性能优化:
-
调整 Master 的
worker_threads(默认 5,建议 CPU 核心数×2)。 -
设置
max_open_files为 100000。
-
-
安全加固:
-
使用
external_auth限制用户权限。 -
开启
peer或client_acl控制命令访问。 -
重要 Pillar 数据使用
gpg加密。
-
八、总结
本文从零开始,全面介绍了 SaltStack 的部署、配置、远程执行、Grains、Pillar、State 管理及文件同步等核心功能,并补充了大量实践经验和排错技巧。SaltStack 不仅能够批量管理服务器,还能通过 State 实现“基础设施即代码”(IaC),极大提升运维效率和标准化水平。
文中所有代码均已测试通过,可直接复制使用。建议读者结合官方文档(docs.saltproject.io)深入学习模块细节和高级特性。
希望这篇文章能成为你 SaltStack 学习路上的“百科全书”。如有疑问,欢迎在评论区交流讨论!
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐



所有评论(0)