salt通过Jinja2模板以及grain和pillar扩展主机状态
简介
1
我们学习了简单状态文件的编写,实际情况我们会遇到更复杂的情况,比如:对不同操作系统安装软件,根据主机CPU梳理,内存动态生成软件配置文件等,这一切都需要Jinja2以及grain和pillar的辅助.
Jinja2
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75Jinja2是一个强大的python模板引擎,可以使用代码动态生成创建文件的内容
//Jinja2 变量
Jinja2包含变量和表达式: 变量用"{{}}"包围,表达式用"{%%}"包围
* 字符串类型: {% set var = 'good' %} {{var}}
* 列表类型: {% list = [1,2,3] %} {{list[0]}}
* 字典类型: {% dict = {'a':1,'b':2} %} {{dict['a']}}
例如:
[root@saltserver ~]# vim /srv/salt/var.sls
{% set var = 'hello world' %}
test_var:
cmd.run:
- name: echo "var is {{var}}"
[root@saltserver ~]# salt '*' state.sls var
192.168.13.187:
----------
ID: test_var
Function: cmd.run
Name: echo "var is hello world"
Result: True
Comment: Command "echo "var is hello world"" run
Started: 11:07:33.190097
Duration: 19.801 ms
Changes:
----------
pid:
29983
retcode:
0
stderr:
stdout:
var is hello world
Summary for 192.168.13.187
------------
Succeeded: 1 (changed=1)
Failed: 0
------------
Total states run: 1
Total run time: 19.801 ms
//Jinja2 流程控制
* for
例一:
{% for user in users %}
{{user}}
{% endfor %}
例二:
{% for key,value in my_dict.iteritems() %}
{{key}}
{{value}}
{% endfor %}
注意: 模板中循环不能有break和continue.但你可以在迭代中过滤序列来跳过项目
{% for user in users if not user.hidden %}
{{user.username}}
{% endfor %}
* if
例一:
{% if users %}
{% for user in users %}
{{user.username}}
{% endfor %}
{% endif %}
例二:
{% if kenny.sick %}
kenny is sick.
{% elif kenny.dead %}
You killed Kennny! You bastard!!!
{% else %}
Kenny looks okay --- so far
{% endif %}grain 和 pillar
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124grain和pillar本质上都是key,value型数据库.
grain存储在minion上的数据,minion启动后就进行grains计算.grain是一种静态数据,包括操作系统类型,版本,CPU数量,内存大小等.这些数据不经常变,即时有所变化重启minion也会重新计算生成
pillar数据存储在master上,指定的minion只能看到自己的pillar数据,其他的minion看不到任何pillar数据,这一点与状态文件正好相反.所有通过认证的minion都可以获取状态文件,但是每个minion却都有自己的一套pillar数据,而且每台minion的pillar都进行了加密,所以很适用于敏感数据
//grain相关命令
* 列出minion上的grains项
[root@saltserver ~]# salt '*' grains.ls
* 查看minion上具体某个grain项
[root@saltserver ~]# salt '*' grains.item os
* 列出所有grain详细信息
[root@saltserver ~]# salt '*' grains.items
* 设置grain数据
[root@saltserver ~]# salt '192.168.13.187' grains.setval my_grain bar
* 设置grain多个值
[root@saltserver ~]# salt '192.168.13.187' grains.setvals "{'k1':'v1','k2':'v2'}"
* 设置列表
[root@saltserver ~]# salt '192.168.13.187' grains.setval my_dict '[1,2,3]'
* 查看item
[root@saltserver ~]# salt '192.168.13.187' grains.item my_grain
[root@saltserver ~]# salt '192.168.13.187' grains.item k1 k2
[root@saltserver ~]# salt '192.168.13.187' grains.item my_dict
* 在saltminion上查看
[root@saltminion ~]# cat /etc/salt/grains
k1: v1
k2: v2
my_dict:
- 1
- 2
- 3
my_grain: bar
* grains_module方式设置
方式一: 在salt-master端设置,下发到minion
创建模块目录:
[root@saltserver ~]# mkdir -p /srv/salt/_grains
编写模块:
[root@saltserver ~]# vim /srv/salt/_grains/my_grain.py
import time
def now():
grains = {}
grains['now'] = time.time()
return grains
同步模块到minion:
[root@saltserver ~]# salt '*' saltutil.sync_all
192.168.13.187:
----------
beacons:
clouds:
engines:
grains:
- grains.my_grain
log_handlers:
modules:
output:
proxymodules:
renderers:
returners:
sdb:
states:
utils:
重新加载一次模块:
[root@saltserver ~]# salt '*' sys.reload_modules
192.168.13.187:
True
查看设置的grains:
[root@saltserver ~]# salt '*' grains.item now
192.168.13.187:
----------
now:
1502076872.27
删除自定义granins:
[root@saltserver ~]# salt '*' grains.delval my_grain
192.168.13.187:
None
方式二: 在minion端设置
在minion上修改grain.conf配置文件:
[root@saltminion ~]# vim /etc/salt/minion.d/grain.conf
grains:
new_grain: bar
new_grain_dict:
- one
- two
- three
重启salt-minion服务:
[root@saltminion ~]# pkill salt-minion
[root@saltminion ~]# salt-minion -c /etc/salt -d
在master端进行验证:
[root@saltserver ~]# salt '*' grains.item new_grain_dict
192.168.13.187:
----------
new_grain_dict:
- one
- two
- three
//pillar相关命令
* 列出minion上所有pillar详细信息
[root@saltserver ~]# salt '*' pillar.items
* 查询minion上某一个具体grain值
[root@saltserver ~]# salt '*' pillar.item foo
* 设置pillar数据
建立pillar目录:
[root@saltserver ~]# mkdir -p /srv/pillar
创建pillar文件(sls文件):
[root@saltserver ~]# vim /srv/pillar/minion_one_key.sls
private_key: minion_one_key
建立入口文件:
[root@saltserver ~]# vim /srv/pillar/top.sls
base:
'192.168.13.187':
- minion_one_key
刷新pillar数据:
[root@saltserver ~]# salt '*' saltutil.refresh_pillar
192.168.13.187:
True
查看下发的pillar数据:
[root@saltserver ~]# salt '*' pillar.items
192.168.13.187:
----------
private_key:
minion_one_key通过Jinja2配合grain和pillar扩展SLS配置文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66//扩展apache.sls配置文件
* apache不同操作系统安装
[root@saltserver ~]# cat /srv/salt/apache.sls
install_apache:
pkg.installed:
{% if grains['os_family'] == 'Debian' %}
- name: apache2
{% elif grains['os_family'] == 'RedHat' %}
- name: httpd
{% endif %}
* vim多系统安装
[root@saltserver ~]# vim /srv/salt/vim.sls
vim:
pkg:
- installed
{% if grains['os_family'] == 'RedHat' %}
- name: vim-enhanced
{% elif grains['os'] == 'Debian' %}
- name: vim-nox
{% endif %}
{% if grains['os'] == 'Arch' %}
/etc/vimrc:
file:
- managed
- source: salt://vim/vimrc
- user: root
- group: root
- mode: 644
- template: jinja
- makedirs: True
- require:
- pkg: vim
{% endif %}
* epel多系统安装
[root@saltserver ~]# vim /srv/salt/epel.sls
epel:
cmd:
- run
{% if grains['osrelease'].startswitch('5') %}
- name: rpm -Uvh http://xx/5/xxx.rpm
{% elif grains['osrelease'].startswitch('6') %}
- name: rpm -Uvh http://xx/6/xxx.rpm
{% endif %}
- unless: test -e /etc/yum.repos.d/epel.repo
* iptables设置
[root@saltserver ~]# vim /srv/salt/iptables.sls
iptables:
pkg:
- installed
service:
- running
- watch:
- pkg: iptables
- file: iptables
file:
- managed
- source: salt://iptables/iptables
{% if grains['os'] == 'CentOS' or grains['os'] == 'Fedora' %}
- name: /etc/sysconfig/iptables
{% elif grains['os'] == 'Arch' %}
- name: /etc/conf.d/iptables
{% endif %}通过Jinja2配合grain和pillar 动态下发配置文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104file模块的一个状态函数managed,这个模块可以从master下发配置文件到匹配的minion上,这种下发方式使所有minion得到同样的配置文件.但现实情况是不同的minion有不同的CPU核心数量,有不同大小内存值.很多软件的配置文件需要根据主机配置的不同进行相应的调整.Jinja2配合grain和pillar可以很好的解决此类问题
* 一个简单的模板文件下发
编写模板文件:
[root@saltserver ~]# vim /srv/salt/templates.sls
template_test:
file.managed:
- source: salt://test.j2
- name: /tmp/test.conf
- user: root
- group: root
- mode: 644
- template: jinja
[root@saltserver ~]# vim /srv/salt/test.j2
cpu_num = {{ grains['num_cpus'] }}
mem_total = {{ grains['mem_total'] }}
hostname = {{ grains['host'] }}
user = {{ pillar['private_key'] }}
测试模板文件下发:
[root@saltserver ~]# salt '*' state.sls templates
192.168.13.187:
----------
ID: template_test
Function: file.managed
Name: /tmp/test.conf
Result: True
Comment: File /tmp/test.conf updated
Started: 15:04:28.737899
Duration: 44.619 ms
Changes:
----------
diff:
New file
mode:
0644
Summary for 192.168.13.187
------------
Succeeded: 1 (changed=1)
Failed: 0
------------
Total states run: 1
Total run time: 44.619 ms
在minion上查看:
[root@saltminion ~]# cat /tmp/test.conf
cpu_num = 4
mem_total = 3832
hostname = saltminion
user = minion_one_key
综上,我们看到配置文件内容的变量已经替换成了对应的值,在这个基础上加上Jinja2的逻辑控制功能:
[root@saltserver ~]# vim /srv/salt/test.j2
{% if grains['num_cpus'] >= 8 %}
cpu_num = {{ grains['num_cpus'] }}
{% endif %}
{% if grains['mem_total'] <= 512 %}
mem_total <= 512
{% elif grains['mem_total'] >= 1024 %}
mem_total >= 1024
{% endif %}
hostname = {{ grains['host'] }}
# 下发配置文件
[root@saltserver ~]# salt '*' state.sls templates
192.168.13.187:
----------
ID: template_test
Function: file.managed
Name: /tmp/test.conf
Result: True
Comment: File /tmp/test.conf updated
Started: 15:10:37.611367
Duration: 48.785 ms
Changes:
----------
diff:
---
+++
@@ -1,4 +1,7 @@
-cpu_num = 4
-mem_total = 3832
+
+
+
+mem_total >= 1024
+
+
hostname = saltminion
-user = minion_one_key
Summary for 192.168.13.187
------------
Succeeded: 1 (changed=1)
Failed: 0
------------
Total states run: 1
Total run time: 48.785 ms
在minion上查看:
[root@saltminion ~]# cat /tmp/test.conf
mem_total >= 1024
hostname = saltminion