SaltStack 是一个轻量级的运维工具,具备配置管理、远程执行、监控等功能,类似于 Puppet 和 Chef,不过这两者是用 Ruby 写的,而 Salt Stack 用的是 Python。
结下来看看具体的使用。
简介
SaltStack 基于 Python 写的经典 C/S 框架的自动化部署平台,由 Master 和 Minion 构成,使用了一系列成熟的工具,比如网络模型采用 ZeroMQ、授权加密采用了 AES、串行化采用了 msgpack、配置文件采用 YAML 标记语言等。
安装测试
在 CentOS7 中可以通过如下方式在单机安装测试。
----- 直接通过YUM安装相关的依赖包
# yum --enablerep=epel install salt salt-master salt-minion salt-ssh
# systemctl start salt-master # 启动master
# salt-master -d # 同上,直接通过命令行启动,指定后台运行
# netstat -ltunp | grep python # 查看打开的端口,默认为4505/4506
# lsof -i:4505 # 同上,查看使用4505端口的程序
# cat /etc/salt/minion # 修改配置文件
master: localhost # master的IP地址
id: foobar # 指定minion的ID
# systemctl start salt-minion # 启动minion
$ salt --version # 查看版本号
$ salt --versions-report # 查看其它依赖模块的版本号
----- 测试,常见的使用方式
# salt-key -A # 添加本地节点
# salt "*" test.ping # 测试节点
# salt "*" cmd.run 'uptime' # 执行命令
# salt -G "os:Centos" test.ping # 根据被控主机的grains信息过滤
# salt "*" grains.item os # 查看操作系统类型
--- 执行代码,等同于python -c 'import sys; print sys.version'
# salt '*' cmd.exec_code python 'import sys; print sys.version'
实际上 master/minion 只会安装少数的文件,主要文件在 salt 安装包中。
SaltStack master 启动后默认监听 4505 和 4506 两个端口,其中 4505(publish_port) 为 salt 的消息发布系统,4506 (ret_port) 为 salt 客户端与服务端通信的端口。
Master/Minion 的认证和链接
SaltStack 主控端是依靠 openssl 证书来与受控端主机认证通讯的,受控端启动后会发送给主控端一个公钥证书文件,在主控端用 salt-key 命令来管理证书。
认证过程如下。
- 在安装 minion 之后,需要在配置文件中定义参数 master,也就是指定 master 端的 IP 地址;
- 启动 minion 服务后会在本地生成一个密钥对;
- 接着 minion 会去连接 master,并尝试把公钥发送给 master,这时在 master 端可以使用 salt-key 来查看当前已经接收到的认证。
在 master 接受 minion 认证之后,两者即可通讯了,可以通过 state 模块来配置管理 minion,也可以通过 cmd.run 远程对 minion 执行命令。
详细来说,minion 在第一次启动时,会在配置文件 (默认为/etc/salt/minion) 中的配置项 pki_dir 指定目录下(默认为 /etc/salt/pki/minion/)下自动生成 minion.pem (private key) 和 minion.pub (public key),然后将 minion.pub 发送给 master。
master 在接收到 minion 的 public key 后,通过 salt-key 命令 accept minion public key,这样在 master 的 /etc/salt/pki/master/minions 下的将会存放以 minion id 命名的 public key,然后 master 就能对 minion 发送指令了。
常见的命令有:
# salt-key -L # 查看所有节点,包括未认证的节点
# salt-key -A # 添加所有未认证的节点
# salt-key -a node* # 支持单个节点、以及通配符
# salt-key -d node # 删除对某个节点的认证
# salt-key -D # 删除所有证书
执行命令
SaltStack 执行命令的格式如下。
常用的命令如下。
# salt '*' sys.doc # 查看所有文档
# salt '*' sys.doc pkg.install # 查看pkg.install对应的文档
# salt '*' cmd.run 'ls -l /bin/ls' # 直接执行终端命令
# salt '*' disk.usage # 查看磁盘使用情况
# salt '*' network.interfaces # 查看网络设备
# salt '*' pkg.install coreutils # 安装软件
在 SaltStack 中,目前有 5 种方式来指定目标机器。
- 匹配 minion id,可以使用 shell 通配符 (Globbing)、正则表达式(Perl风格)、minion 列表。
- Grains,包括客户端配置文件中定义 Grains。
- 指定列表 (Lists),节点分组 (Node Groups),复合匹配 (Compound Matcher),批量执行 (Batch Size)。
可以参考如下的示例。
# salt '*' test.ping # 所有的minions
# salt '*.example.*' test.ping # 可以使用shell中的* ? []通配符
# salt 'web?' test.ping # 匹配web1、web2等
# salt 'web-[x-z]' test.ping # 匹配web-x、web-y、web-z
# salt -E 'web1-(prod|devel)' test.ping # 使用正则表达式
# salt -L 'web1,web2,web3' test.ping # 指定列表
# salt -G 'os:CentOS' test.ping # 使用Grains
# salt -N group1 test.ping # 指定分组节点node group
# salt -C 'web? and G@os:CentOS or E@web.*' test.ping # 使用组合模式
# salt '*' -b 10 test.ping # 使用批量模式
# salt -G 'os:RedHat' --batch-size 25% test.ping
在不指定 minion id,则会通过 socket.getfqdn() 获取,可以通过如下命令查看,同时该值会缓存在 /etc/salt/minion_id 中。
$ python -c 'import socket; print socket.getfqdn(socket.gethostname())'
节点分组可以在 master 配置文件中进行设置,如下。
nodegroups:
group1: 'L@foo.domain.com,bar.domain.com,baz.domain.com or bl*.domain.com'
group2: 'G@os:Debian and foo.domain.com'
复合匹配是通过布尔操作符连接的多个目标条件,可以使用上述的几种方式匹配,默认采用 Globbing。另外,not 不能用于第一个条件,需要使用如下的命令 salt -C '* and not G@os:CentOS' test.ping
。
相关匹配规则的语法可以参考 staltstack docs - Compoud Matchers 。
Salt State, SLS
State 用于描述系统的目标状态,SLS 代表 SaLt State 文件,是 Salt State 系统的核心;SLS 描述了系统的目标状态,采用最简单易读的序列化数据格式 YAML。
其中根路径在 master 的配置文件中通过 file_roots 指定,其中 base 必须存在,而且 base 环境中通常包含 Salt 的入口 top 文件,也即 top.sls 。注意,sls 文件需要同时在 master 和 minion 都存在。
最简单的配置文件如下,用于检查 coreutils 是否已经安装,与 state 相关的源码保存在 salt/states 目录下。
# cat top.sls
base:
'*':
- coreutils
# cat coreutils.sls
coreutils: # ID声明
pkg: # state声明
- installed # 定义的function
在配置文件中,可以通过 salt://
代替配置文件中 file_roots 指定的根路径,入口文件默认为 top.sls,可以通过 state_top 配置。
Pillar VS. Grains
Pillar 和 Grains 非常容易混淆,其中 Grain 的数据是在 minion 启动时产生的,通常是类似于 OS、CPU、磁盘的静态信息;而 Pillar 信息保存在 master 中。
Salt在 0.9.8 版本中引入了 Pillar,Pillar 是一个非常重要的组件,用于给特定的 minion 定义任何需要的数据,这些数据可以被 Salt 的其他组件使用。Pillar 解析后,是一个嵌套的字典结构,最上层的 key 是 minion ID,也就是说 Pillar 数据是与特定 minion 关联的,每一个 minion 只能看到自己的数据。
Pillar 使用独立的加密 session,所以 Pillar 可以用来传递敏感数据,如 ssh key、加密证书等。
默认情况下,master 配置文件中的所有数据都添加到 Pillar 中,且对所有 minion 可用,如果要禁用这一默认值,可以添加 pillar_opts: False 配置。Pillar 使用与 State 相似的 SLS 文件,其根目录通过 master 配置文件中 pillar_roots 指定,而且 Pillar 也有 top file。
# salt '*' pillar.data # 或者pillar.raw
# salt '*' saltutil.refresh_pillar # 修改Pillar文件后刷新minion上的数据
对于 Grains 常见的操作如下。
# salt '*' grains.ls # 列出所有grains的名字
# salt '*' grains.items # 列出名字以及内容
# salt '*' grains.item os # 查看具体选项
可以在 minion 的配置文件中 (默认为/etc/salt/minion) 设置 Grains 的静态信息。
grains:
roles:
- webserver
- memcache
deployment: datacenter4
另外,可在 master 中定义模块,可以将脚本放置在 file_roots 下的 _grains 目录中,当执行 state.highstate、saltutil.sync_grains、saltutil.sync_all 时,会将 _grains 中的文件分发到客户端上。
# mkdir /srv/salt/_grains
# cat /srv/salt/_grains/custom_grain.py
def custom_grains():
grains = {'role' : 'LB'}
return grains
# salt '*' saltutil.sync_grains
# salt '*' grains.item role
上述的脚本会作为模块导入,因此不需要 #!/usr/bin/env python
,也不需要有执行权限。
模块
一些常见的模块会保存在安装目录下的 salt/modules 下,如果通过 YUM 安装,通常为:
$ ls /usr/lib/python2.7/site-packages/salt/modules
在 Python 中,如果要添加模块也非常简单,可以直接在安装目录的 modules 子目录下添加如下文件。
# cat /usr/lib/python2.7/site-packages/salt/modules/foobar.py
def hello():
return 'hello world'
然后可以通过 salt ‘*’ foobar.hello 执行。
常用模块介绍
下面看下一些常见的模块,除此之外还有 grains、pillar、states、modules、returner、runners、reactor 等模块。
cp 模块
实现远程文件、目录的复制,以及下载URL文件等操作。
----- 将主服务器file_roots base指定目录下的文件复制到被控主机
# cat /etc/salt/master
file_roots:
base:
- /srv/salt
# echo "This is test file with saltstack module 'cp.get_file'" > /srv/salt/foobar.txt
# salt '*' cp.get_file salt://foobar.txt /tmp/foobar.txt
----- 将目录下的文件复制到被控主机
# mkdir /srv/salt/dir && mv /srv/salt/foobar.txt /srv/salt/dir/
# salt '*' cp.get_dir salt://dir /tmp
----- 下载指定URL内容到被控主机指定位置
# salt '*' cp.get_url http://justkidding.com/download/files.tgz /tmp/files.tgz
----- 根据grains选择目标
# salt '*' cp.get_file "salt://{{grains.os}}/vimrc" /etc/vimrc template=test
该模块有几个常用的参数:
- gzip=9,使用gzip的方式进行压缩,数字越大,压缩率就越高,9代表最大的压缩率。
- makedirs=True,当分发的位置在目标主机上不存在时,自动创建该目录。
模板渲染功能可以同时在源和目标文件中使用。
cmd 模块
实现远程的命令行调用执行。
# salt '*' cmd.run 'uptime'
file 模块
被控主机文件常见操作,包括文件读写、权限、查找、校验等。
# salt '*' file.get_sum /etc/resolv.conf md5
# salt '*' file.stats /etc/resolv.conf
pkg 包管理模块
被控主机程序包管理,如yum、apt-get等。
# salt '*' pkg.install coreutils
# salt '*' pkg.file_list coreutils
network模块
返回被控主机网络信息。
# salt '*' network.ip_addrs
# salt '*' network.interfaces
service 服务模块
被控主机程序包服务管理。
# salt '*' service.start crond
# salt '*' service.status crond
配置文件
interface: 0.0.0.0 # 监听IP
publish_port: 4505 # 消息发布端口
user: root # 默认用户
max_open_files: 100000 # 最大打开文件数
worker_threads: 5 # 工作线程数,不能小于3
ret_port: 4506 # master和minion使用的通讯端口
pidfile: /var/run/salt-master.pid # PID文件
root_dir
pki_dir: /etc/salt/pki/master # 存放公钥的目录
cachedir
keep_jobs
job_cache
ext_job_cache
minion_data_cache
enforce_mine_cache
sock_dir
参考
相关的文档可以查看 docs.saltstack.com,也可以直接下载 PDF 文档,内容比较多,有 2K+ 页。其它的一些常用网址可以参考: 中文社区(www.saltstack.cn)、官方网址(www.saltstack.com)、Python官方 。