Atom

思考、故事和创意

SaltStack

SaltStack: There and back again

First Class 之后,master 可以管理 minion 了,这里记下一些用法,从“低端”用法,到不那么“低端”的用法。除非特殊说明,执行命令和编辑文件都是在 master 上进行的。

saltstack 有很多的可执行模块(execution modules),比如下面要提到的 file, cmd, state, cp 等等,这里是 saltstack 所有的可执行模块列表。这些模块一般是这样用的

salt '*' module_name.module_function args...

'*' 表示所有 minion,可以指定特定一个 minion,或者使用通配符 'a*' 之类的字符串,还可以'x[0-9]'这样写,表示从 'x0' 到 'x9' 之间的名称。还支持正则表达式。通过 -L 指定一个 minion 的列表。

salt -L 'web1,web2,web3' test.ping

这类模块的作用,可以大概理解成,在 master 机器上敲一行命令,告诉 minion 要做一件什么事情。

saltstack 有个重要的概念:state,或许可以这么理解,这是让所有 minion 变成统一状态 (state) 的 saltstack 的一个系统。这个系统也包含了很多模块,这里是所有 state 模块的列表。

前面提到的可执行模块里有个 state,它是用来对 saltstack 的 state 系统进行控制的。

state 是较为“高端”的用法。编辑一些文件,在 master 机器上定义好所管理的机器应该处于什么状态,装些什么包,配置文件怎么样,运行哪些服务,然后告诉 minion, minion 就把所在机器变成这个样子。

从简单的开始。先把两个最容易想到的两件事情搞定。

salt '*' cmd.run 'date'

cmd 模块的 run 方法,命令在所有 minion 上执行 date 命令。

salt '*' cp.get_file salt://file /tmp/abcd

这个命令让我很迷惑,我以为是在 minion 端执行,去 master 拉取文件,试了好多次才知道,这个命令是在 master 执行的。

上面这一行命令是让所有 minion 拉取 master 上 salt://file 文件到本地的 /tmp/abcd, salt://file 的真实路径跟 file_roots 的配置有关,例如

file_roots:
  base:
    - /srv/salt

这样 salt://file 就是 /srv/salt/file

如果要批量执行某个脚本,可以把脚本放在 master 上前面说的 salt:// 目录,然后执行 salt '*' cmd.script salt://hello.sh 让所有 minion 执行 hello.sh 这个脚本。

批量执行命令、传文件,这种任务用 fabric 也是可以轻松做到的,这也不是 saltstack 主要的用途。

state

上面这种方法并不是一个批量处理 minion 机器某个软件配置文件的好方法。通过 state,可以这样做。

下发文件

/srv/salt/ 目录编辑文件 testfile.sls,文件内容:

/tmp/abcd:
  file.managed:
    - source:
      - salt://file

执行 salt '*' state.sls testfile,作用是把 master 的 salt://file 文件下发到各个 minion 保存为 /tmp/abcd。看上去跟前面 cp.get_file 作用是一样的。

这条命令表示执行 state 模块的 sls 方法,即执行名为 testfile 的 sls 文件,sls 的意思就是 Salt State。

testfile.sls 的第一行表示目标,第二行表示使用 state 的 file 模块,managed 方法,下面是该方法的参数,这里只用了一个 source 参数,表示源文件路径,还可以添加其他参数,用于设置目标的权限、所属用户等属性。

整个目录

还可以下发整个目录,编辑新文件 testdir.sls 文件内容

/tmp/dir:
  file.recurse:
    - makedirs: True
	- source: salt://dir_test
    - include_empty: True

执行 salt '*' state.sls testdir,作用是把 salt://dir_test 目录及其子目录包括空文件,下发到各个 minion,存为 /tmp/dir

这种方法要比 cp.get_file 强大灵活得多,因为 state 的 file 模块还有很多其他方法,比如 file.append 用于追加字符串或者是一个文件到 minion 的目标文件。文档地址是 salt.states.file

顺带提一下,还可以用名为 file 可执行模块进行一些操作,比如在 minion 的 /etc/foo.conf 末尾追加一行字符串 'world'。

salt '*' file.append /etc/foo.conf world

这个跟 state 的 file 模块不是一回事,不要搞混了。file 可执行模块的文档地址是 salt.modules.file

上面的传文件和目录都是用的 state 的 file 模块,下面用到的是 state 的 cmd 模块。

执行命令

state 系统有 file 模块,也有 cmd 模块,最简单的使用方法是:
/srv/salt/test_cmd.sls 内容:

date:
  cmd.run

执行salt '*' state.sls test_cmd.sls,就在每一个 minion 执行了 date 命令。

执行脚本

如果要所有机器都执行一个脚本,一个个传上去,然后一个个执行是个相当蠢的办法。使用 saltstack 可以大大解放我们的双手。
/srv/salt/scripts/test.sls 内容:

salt://scripts/test.sh:
  cmd.script

/srv/salt/scripts/test.sh 内容

date;

/srv/salt/scripts/test.sh 就是希望在所有 minion 都执行的脚本,这里只写了一个 date 命令。

执行 salt '*' state.sls scripts.test,就在每一个 minion 执行 test.sh 脚本。这个命令里最后的参数是 scripts.test,因为 test.sls 文件的路径在 srv/salt/scripts/,在 file_roots 设定的 saltstack “根”目录的 scripts 目录下。

state 的 cmd 模块的文档在这里 salt.states.cmd

上面几节都是用的 state.sls 方法,参数是 sls 文件名(不包含后缀'sls'),这个文件可能有两种方式存在着,假设名字叫 xxxxx,一种是像这样在 /srv/salt/ 目录下的 xxxxx.sls 文件,还有一种是在 /srv/salt/xxxxx/ 下创建一个 init.sls 文件。

可执行模块 state 还有别的用法,比如 state.highstate。具体的各种方法请看 salt.modules.state

综合例子

这里有个比较综合,简单的例子。来自 SaltStack Walk-Through

/srv/salt/edit/vim.sls:

vim:
  pkg.installed

/etc/vimrc:
  file.managed:
    - source: salt://edit/vimrc
	- mode: 644
	- user: root
	- group: root

执行 salt '*' state.sls edit.vim

首先是制定需要安装 vim,大多数 saltstack 文档都提到了 pkg 这个模块。然后是把 /srv/salt/edit/vimrc 文件放到每个 minion 的 /etc/vimrc,并且设置好 644 权限以及 root 用户和组。

注意命令最后是 edit.vim,跟上面 scripts.test 类似,因为 vim.sls 路径不是在 file_roots 设定的 /srv/salt/ “根”目录,而是多了一层 edit/


最后写几个可能有用的命令

查看 minion 在线状态

salt-run manage.status // 查看在线、离线 minion
salt-run manage.up			// 查看在线 minion
salt-run manage.down		// 查看离线 minion

查看 minion 的版本

salt '*' test.version	

用了 test 可执行模块,还有其他可执行的方法,比如 minion 和 master 能“互动”之后,执行一条 salt '*' test.ping


两篇文章,只能记下 saltstack 的皮毛,好在官方文档很完善,由浅入深,而且很清晰标明哪些属于“新手入门”,哪些是“深入 saltstack”,哪些是“最佳实践”。赞!

SaltStack: First Class

上周花了几天时间学习了 saltstack,感觉是个值得一试的工具。这里记一下学习和使用过程。没有高大上的用法,这些记录也不一定是 saltstack 的最佳实践。saltstack 的官方文档比较完善,可供参考。

初步认识

saltstack 是需要在被管理的机器上装 agent 的,这里叫做 minion。管理中心要安装的是 master。

minion 带着自己的公钥去连接 master,master 接受 minion 的公钥之后,鉴权成功,master 可以对这个 minion 进行管理了。在每一个 minion 上都保存着 master 的公钥,在 master 上保存有各个 minion 的公钥。saltstack 并不是走的 ssh 鉴权。

master 和 minion 是通过 zeromq 进行通信的,之前对 zeromq 有过一点了解,印象是“快”!

安装

可以通过源(yum, apt-get...)安装,也可以通过 pip 安装,当然也可以用源码编译安装。建议用 Linux 各个发行版的源进行安装,因为方便。安装各种依赖库、工具,尤其是要在很多机器上安装,是个挺痛苦的过程。详细内容见官方文档

简单配置

saltstack 的 master 的配置文件默认是在 /etc/salt/master,minion 的配置文件路径是 /etc/salt/minion。通过源安装的这个文件应该已经存在了,其他方式可能没有,自己创建即可。

每个配置项都是配置项名称: 配置项的值这种格式。

master 配置

通过源安装的 salt-master,已经放好了 /etc/salt/master 文件,所有配置项都被注释,里面是各项配置的介绍,可以仔细看一下,看自己需要取消注释或者修改配置项。通过 pip 等其他方式安装,自己创建空白的配置文件。先写下这些内容就暂时够用了:

interface: 192.168.0.1
file_roots:
  base:
    - /srv/salt

interface 指定绑定的地址,默认是 0.0.0.0,一般来说,走外网进行服务器管理,我想是个挺奇怪的场景,所以这里填一个内网地址吧。
file_roots 是设置 salt-master 作为文件服务器要用的本地的路径,可以为不同的环境设置不同的路径,上面的配置是 base 环境的路径是 /srv/salt,具体的意义到下面涉及到文件管理再说。

minion 配置

minion 配置里写上 master: 192.168.0.1 就基本可以了,指定了它要连的 master 的地址。

日志

日志的相关配置在 master 和 minion 端一样。为了检查 master 或者 minion 启动失败,minion 连接 master 失败等问题,可以降低 log_levellog_level_logfile 的日志级别,默认是 warning,修改到 debuginfo,这样程序产生的日志应该足以检查各种问题发生的原因。

log_level 是表示输出到终端的日志等级,log_level_logfile 是表示输出到文本文件的日志等级。日志的文本文件路径由 log_file 指定,master 和 minion 分别默认是 /var/log/salt/master, /var/log/salt/minion

启动

刚开始试用时,可以从前台启动 master 和 minion,所有内容都输出到屏幕上,通过 -l 指定输出内容的等级,执行 salt-master -l debug 前台启动 master,输出 debug 级别的日志内容,启动 minion 的命令与之类似。

通过源安装,一般就以启动系统服务的方式启动就可以了,比如 CentOS 上通过 service salt-master start 启动 master。

鉴权

minion 和 master 都启动之后,需要进行前面提到的鉴权过程,master 这一端通过 salt-key 工具来管理 minion 的公钥。

salt-key -L

查看 minion key。所显示内容一般是 minion 的主机名,或者是 minion 配置文件里 id 配置项所指定的名称。还有 minion 的 key 的状态:拒绝(rejected),接受(accepted), 暂未接受(unaccepted)。

salt-key -A xxx

接受名为 xxx 的 key,如果 -A 后不加参数,则添加所有暂未接受的 key。

在 master 接受了 minion 的 key 之后,这个 minion 就可以由 master 来管理了。

因为 master 和 minion 都互相保存了公钥,所以 master 遇到与已存在 minion 同名的 minion 来连接,或者 minion 去连新的 master 都是会鉴权失败的。


之后就可以从 master 对 minion 进行各种 XXXXX 了。

Salt will return in a moment...