在用saltstack实现lamp架构时,总结了远程执行的原理和JInja2模版以及Grain和Pillar对主机状态的扩展,解决了不少我所疑惑的问题,再此分享出来。
1.原理:saltstack到底是怎么让远程主机minion去执行它所推送的命令的呢?
saltstack是基于pub/sub模式的,举个例子:就像超市广播找人,master就像广播,去把消息发送出去,这就是pub实现的,minion就相当超市里的所有人,所有人都可以听见这个消息,那到底哪个人听到消息去广播室呢?就由sub基于匹配规则来实现,叫的是我名字,那我接收消息并执行消息赶紧去广播室,(我妈妈可能急坏了zzzz) ,那么问题又来了,我到底听哪家广播?播广播的人怎么承认我就是那个要找的人呢? 这就是通过在minion端的配置文件里(/etc/salt/minion)去定义master的地址,开启以后minion就会连接到master的4506端口去进行认证,若认证通过则再连接到master的4505端口,去准备接收远程命令,master通过4505端口去发送远程命令,minion接收以后发现与本机匹配则接收命令并执行,再将返回结果发到 master的4506端口,由master处理,这样便完成了一次远程命令的执行。(~~~例子有点牵强~溜)
总之:master端有两个接口----4505:向总线发送远程命令的
4506:进行认证和结果收集功能
2.saltstack推送远程命令的几种机制:
a.直接采用命令行方式:
salt '*' pkg.install httpd
b.state模块完成部署:
mkdir -p /srv/salt
vim /srv/salt/apache.sls
install_httpd:
pkg.installed:
- name: httpd
salt '*' state.sls apache
区别:执行模块是过程式的,就是重复执行时执行了相同的逻辑和指令,而状态模块是描述性的,就是先会判断一下,当检测到真实状态和所需状态不一致时才会去执行,否则什么也不做。
注意:sls文件使用YAML语言描述,它有很严格的语法,缩进级别由两个空格组成,冒号后面有一个空格隔开,还有短斜杠加空格等,一定要格外留心。
3.很多时候我们需要在不同系统上去部署同一个服务,但是不同的系统服务又会有所差异,要是为每台写一个状态文件那就太麻烦了,这时候Jinja2和Grain模版就可以来解决了,那要是想根据变化动态的生成呢?这就要用到Pillar模版,所以将Jinja2、Grain和Pillar结合起来就能实现主机状态的一个扩展。
Jinja2: 以我的理解,就是通过通过表达式和变量去匹配你所需要的minion。
Grain: 是存储在minion端的静态数据,是minion的固有静态属性(cpu,os,mem...)
Pillar: 是存储在master端的数据,指定的minion只能看见自己的pillar数据,而且每台minion的pillar都进行了加密,所以适用于敏感数据。
用Jinja2配合Grain和Pillar可以实现在动态下发配置文件
a. 编辑状态文件:
vim /srv/salt/template.sls
template_test:
file.managed:
- source: salt://test.j2
- name: /tmp/test.conf
- user: root
- group: root
- mode: 644
- template: jinja
b. 编辑模版文件:
vim /srv/salt/test.j2
cpu_num = {{ grains['num_cpus'] }}
mem_total = {{ grains['mem_total'] }}
user = {{ pillar['user'] [0] }}
..........
salt '*' state.sls template
测试:在minion端查看下发的配置文件:
cat /tmp/test.conf
cpu_num = 8
mem_total = 497
user = web1