Salt搭建主备master及问题

"备份不做,十恶不赦,冗余不做,日子甭过"。Saltstack提供了一个方便的master冗余方案,使得我们在master服务器宕机后不至于无法工作。按照以下步骤,我们可以搭建具有主备master的Saltstack系统,平时在主master上工作,万一发生宕机异常时,切换到备master上继续干活。

同步配置文件

首先,要同步主备的/etc/salt/master文件,该文件包括nodegroupsexternal_auth等配置。

同步master的公私钥

由于Salt的通信都是加密的,minion只保存一份master的公钥(/etc/salt/pki/minion/minion_master.pub),为了保证其和主备master都能通信,需要两个master使用同一套公私钥。Salt master在启动时会自动生成一份公私钥,在主master启动后备master启动前,同步这套公私钥到备机同样位置:

/etc/salt/pki/master/master.pem
/etc/salt/pki/master/master.pub

之后启动备master。

配置minion

minion的配置也非常简单,只需要罗列master的地址:

master: 
  - master01.opjasee.com
  - master02.opjasee.com

同步minion公钥

如果master没有开启auto_accept并且不想每次都在主备上重复执行接受、拒绝或删除minion公钥的命令,那么可以选择同步minion的公钥保存目录:

/etc/salt/pki/master/minions
/etc/salt/pki/master/minions_pre
/etc/salt/pki/master/minions_rejected

同步pillar_roots和file_roots

fileserver_backend这个地方最开始想使用gitfs的,但是考虑再三还是决定使用file_roots,直接克隆一个git项目到/srv/salt。放弃gitfs的原因有三个,也可能是我理解有误:

  1. 我们的Gitlab是部署在办公区的一台虚拟机上的,平时上上线没问题,但是考虑到机房和办公区直接的VPN质量和物业断电的频率,还是不能将这么明显的单点挂在Salt上,虽然其能保证主备master的文件一致,但得不偿失。
  2. file_roots支持gitfs,但是没看到什么地方说pillar_roots也支持,如果后者还是需要定期进行同步,那么gitfs的便利也带来了一种环境两种同步方式的问题。
  3. 直接从Git仓库里取文件不如本地直观,感觉也没有git pull前再检查一遍安全。

因此目前暂定不直接使用gitfs,而是通过多个git项目分别管理pillar_rootsfile_roots,这时候备master上可以通过rsyncgit pull来定期同步,一个参考的命令:

$ rsync -av --progress --delete --timeout=30 root@master01.opjasee.com:/srv/pillar /srv/

另外,可以在master的配置中使用正则或通配排除一部分无关或临时文件,避免minion自动同步时将这些目录或文件也同步过去:

file_ignore_regex:
  - '/\.git($|/)'

file_ignore_glob:
  - '*.pyc'
  - '*.bak'
  - '*.swp'

这时候在minion看来master上的这些文件或目录都不存在了,包括直接使用cp.get_file salt://xxx/.git/config /tmp/这种命令也无法读取.git目录下的文件了。

一个问题

乐滋滋的写完准备收工,突然发现了一问题!
虽然Salt号称目前minion已经可以与多个master同时连接,也不需要在minion中配置master_type了,我在测试环境里也确实可以在主备master上都可以执行命令,但是过了几分钟后,备master就开始陆续无法获取minion的执行结果了,主master的日志里记录以下错误:

[salt.loaded.int.returner.local_cache       ][ERROR   ] An inconsistency occurred, a job was received with a job id that is not present in the local cache: 20150202190624634189

从minion的debug日志来看,其能够接收并执行job,应该是返回发错了地方。
继续观察与测试,发现了一个有趣的现象:

  1. 当所有minion重启后,主备master都能够正常执行命令。
  2. 如果此时在某台master上执行了state.highstate,那么这台master就会出现上述问题,再也获取不到minion的返回了。
  3. 此时在另一台master上执行state.highstate和其他命令,都不会有问题。

看来第一个在某minion上调度highstate的master将会丢失该minion后续命令的返回,由于我配置了highstate的定时调度,所以过了几分钟一个master就出问题了。
目前已经向开发者反馈了该问题,暂不确定是不是我个人环境或使用的问题,还是确实是一个bug,待续。

如果这个问题暂时不能解决,那么要么关闭备master,将其做成冷备;要么重启所有minion后直接在备master上执行highstate自废武功,以便主master能保持正常,经测试,在这种情况下,如果主master异常,重启所有minion后,备master执行highstate是不会引发问题的,可以暂用这个方案。感觉多master存活时,highstate将使minion只与一个master正常连接。

又一个问题

在双master的情况下,使用-G-I进行Targeting的话,不匹配的机器也会出现在结果中,返回Minion did not return. [No response]。虽然这些不匹配的节点并未执行操作,但是这种输出挺烦的。没办法,暂时用冷备吧。

另外Salt丢节点默认也没个提示,暂时先alias salt='salt -v'吧。

Loading Disqus comments...
Table of Contents