SALT BEST PRACTICES(最佳实践)

时间:2022-11-11 08:12:25

SALT BEST PRACTICES

salt由于可以配置的相当灵活,可能会导致配置结构会变得比较混乱。


 

GENERAL RULES

一般性的规则:
  1、尽可能的将配置定义的突出模块性和足够清晰度
  2、将pillar与states文件之间建立明确的关系,可以将state文件目录和pillar目录定义在同一级下面,放在同一部署环境中。
  3、使用有意义的变量,不要过度的去使用,过度灵活的变量配置也会导致配置的复杂度过大,耦合性过高。
  4、敏感数据存放在pillar中
  5、在pillar的top文件中不要使用grains匹配,对于敏感的pillar数据


STRUCTURING STATES AND FORMULAS

定义出states文件清晰的目录结构
示例:

SALT BEST PRACTICES(最佳实践)SALT BEST PRACTICES(最佳实践)
1 /srv/salt/mysql/files/
2 /srv/salt/mysql/client.sls
3 /srv/salt/mysql/map.jinja
4 /srv/salt/mysql/python.sls
5 /srv/salt/mysql/server.sls
View Code

top文件:

SALT BEST PRACTICES(最佳实践)SALT BEST PRACTICES(最佳实践)
1 base:
2   'web*':
3     - mysql.client
4     - mysql.python
5   'db*':
6     - mysql.server
View Code

这样定义的结构比较清晰。


STRUCTURING PILLAR FILES

pillar文件结构

默认pillar环境目录被定义在/srv/pillar/中,pillar文件一般被用来包含其他pillar文件和设置基于环境和grains的匹配关系。

示例:

SALT BEST PRACTICES(最佳实践)SALT BEST PRACTICES(最佳实践)
1 base:
2   '*':
3     - packages
View Code

复杂一点的示例:

SALT BEST PRACTICES(最佳实践)SALT BEST PRACTICES(最佳实践)
1 base:
2   '*':
3     - packages
4   'web*':
5     - apache
6     - vim
View Code

多环境的配置示例:

SALT BEST PRACTICES(最佳实践)SALT BEST PRACTICES(最佳实践)
 1 base:
 2   '*':
 3     - apache
 4 dev:
 5   'os:Debian':
 6     - match: grain
 7     - vim
 8 test:
 9   '* and not G@os: Debian':
10     - match: compound
11     - emacs
View Code

 

这可以避免为每一个环境设置一个pillar环境目录,如果配置不当容易引起混乱,每一个在pillar中被包含的sls文件都必须位于定义pillar目录下。

一个pillar中的sls文件示例:

SALT BEST PRACTICES(最佳实践)SALT BEST PRACTICES(最佳实践)
1 /srv/pillar/apache.sls:
2 apache:
3   lookup:
4     name: httpd
5     config:
6       tmpl: /etc/httpd/httpd.conf
View Code

VARIABLE FLEXIBILITY

灵活的使用变量,并且为变量设置默认值

一个sls文件中的变量使用示例:

/srv/salt/apache/conf.sls:

SALT BEST PRACTICES(最佳实践)SALT BEST PRACTICES(最佳实践)
 1 {% set name = 'httpd' %}
 2 {% set tmpl = 'salt://apache/files/httpd.conf' %}
 3 
 4 include:
 5   - apache
 6 
 7 apache_conf:
 8   file.managed:
 9     - name: {{ name }}
10     - source: {{ tmpl }}
11     - template: jinja
12     - user: root
13     - watch_in:
14       - service: apache
View Code

变量可以在sls文件中被定义,但是不推荐,这样丧失了变量使用的灵活性。

上面这种情况可以使用pillar存储这些变量信息,也便于其他state文件引用:

/srv/pillar/apache.sls:

SALT BEST PRACTICES(最佳实践)SALT BEST PRACTICES(最佳实践)
1 apache:
2   lookup:
3     name: httpd
4     config:
5       tmpl: salt://apache/files/httpd.conf
View Code

/srv/salt/apache/conf.sls:

SALT BEST PRACTICES(最佳实践)SALT BEST PRACTICES(最佳实践)
 1 {% from "apache/map.jinja" import apache with context %}
 2 
 3 include:
 4   - apache
 5 
 6 apache_conf:
 7   file.managed:
 8     - name: {{ salt['pillar.get']('apache:lookup:name') }}
 9     - source: {{ salt['pillar.get']('apache:lookup:config:tmpl') }}
10     - template: jinja
11     - user: root
12     - watch_in:
13       - service: apache
View Code

上例可以提供一个为用户集中处理和引用变量的环境。


MODULARITY WITHIN STATES

模块化的状态文件配置,当配置一个sls文件的时候,要考虑要这个文件会被重用多少次

/srv/salt/apache/init.sls:

SALT BEST PRACTICES(最佳实践)SALT BEST PRACTICES(最佳实践)
 1 httpd:
 2   pkg.installed: []
 3   service.running:
 4     - enable: True
 5 
 6 /etc/httpd/httpd.conf:
 7   file.managed:
 8     - source: salt://apache/files/httpd.conf
 9     - template: jinja
10     - watch_in:
11       - service: httpd
View Code

上面的sls文件配置是一个相当糟糕的示例,利用state ID作为配置的一部分,非常不利于重用,且source等配置都是写死了。

优化的示例,使用-name参数来取代state ID作为需要安装的包名,state ID应该被定义为一个配置的描述字段。

/srv/salt/apache/init.sls:

SALT BEST PRACTICES(最佳实践)SALT BEST PRACTICES(最佳实践)
 1 apache:
 2   pkg.installed:
 3     - name: httpd
 4   service.running:
 5     - name: httpd
 6     - enable: True
 7 
 8 apache_conf:
 9   file.managed:
10     - name: /etc/httpd/httpd.conf
11     - source: salt://apache/files/httpd.conf
12     - template: jinja
13     - watch_in:
14       - service: apache
View Code

同样上例也存在一些问题,当配置需要依赖的环境较多的时候,类似的配置将被重复进行定义很多次
进一步优化的示例,将配置逻辑判断放在一个jinja文件中:

/srv/salt/apache/map.jinja:

SALT BEST PRACTICES(最佳实践)SALT BEST PRACTICES(最佳实践)
 1 {% set apache = salt['grains.filter_by']({
 2     'Debian': {
 3         'server': 'apache2',
 4         'service': 'apache2',
 5         'conf': '/etc/apache2/apache.conf',
 6     },
 7     'RedHat': {
 8         'server': 'httpd',
 9         'service': 'httpd',
10         'conf': '/etc/httpd/httpd.conf',
11     },
12 }, merge=salt['pillar.get']('apache:lookup')) %}
View Code

/srv/pillar/apache.sls:

SALT BEST PRACTICES(最佳实践)SALT BEST PRACTICES(最佳实践)
1 apache:
2   lookup:
3     config:
4       tmpl: salt://apache/files/httpd.conf
View Code

/srv/salt/apache/init.sls:

SALT BEST PRACTICES(最佳实践)SALT BEST PRACTICES(最佳实践)
 1 {% from "apache/map.jinja" import apache with context %}
 2 
 3 apache:
 4   pkg.installed:
 5     - name: {{ apache.server }}
 6   service.running:
 7     - name: {{ apache.service }}
 8     - enable: True
 9 
10 apache_conf:
11   file.managed:
12     - name: {{ apache.conf }}
13     - source: {{ salt['pillar.get']('apache:lookup:config:tmpl') }}
14     - template: jinja
15     - user: root
16     - watch_in:
17       - service: apache
View Code

上面的例子就显得比较灵活了,将minion的判断逻辑抽象在map.jinja中,master需要引入的配置变量放在pillar中,这样的sls文件在配置变更上就显得比较灵活,但是还是存在一个问题,就是功能模块不够清晰,一个sls文件中包含了两个不同功能的类型配置,包安装和配置文件同步应该进行拆解,如下例:

/srv/salt/apache/init.sls:

SALT BEST PRACTICES(最佳实践)SALT BEST PRACTICES(最佳实践)
1 {% from "apache/map.jinja" import apache with context %}
2 
3 apache:
4   pkg.installed:
5     - name: {{ apache.server }}
6   service.running:
7     - name: {{ apache.service }}
8     - enable: True
View Code

/srv/salt/apache/conf.sls:

SALT BEST PRACTICES(最佳实践)SALT BEST PRACTICES(最佳实践)
 1 {% from "apache/map.jinja" import apache with context %}
 2 include:
 3   - apache
 4 
 5 apache_conf:
 6   file.managed:
 7     - name: {{ apache.conf }}
 8     - source: {{ salt['pillar.get']('apache:lookup:config:tmpl') }}
 9     - template: jinja
10     - user: root
11     - watch_in:
12       - service: apache      
View Code

STORING SECURE DATA

存储数据的安全性

当我们有一些敏感信息需要在服务器端被定义的时候,如果将这些敏感信息直接放在sls文件中,那么minion端将都会收到这些敏感信息,最好的办法是将敏感的数据放在pillar中,确保指定的机器能够去访问这些数据,示例:

/srv/salt/mysql/testerdb.sls:

SALT BEST PRACTICES(最佳实践)SALT BEST PRACTICES(最佳实践)
 1 testdb:
 2   mysql_database.present:
 3     - name: testerdb
 4 
 5 /srv/salt/mysql/user.sls:
 6 include:
 7   - mysql.testerdb
 8 
 9 testdb_user:
10   mysql_user.present:
11     - name: frank
12     - password: "test3rdb"
13     - host: localhost
14     - require:
15       - sls: mysql.testerdb
View Code

将数据放在pillar中的实例:

/srv/pillar/mysql.sls:

SALT BEST PRACTICES(最佳实践)SALT BEST PRACTICES(最佳实践)
1 mysql:
2   lookup:
3     name: testerdb
4     password: test3rdb
5     user: frank
6     host: localhost
View Code

/srv/salt/mysql/testerdb.sls:

SALT BEST PRACTICES(最佳实践)SALT BEST PRACTICES(最佳实践)
1 testdb:
2   mysql_database.present:
3     - name: {{ salt['pillar.get']('mysql:lookup:name') }}
View Code

/srv/salt/mysql/user.sls:

SALT BEST PRACTICES(最佳实践)SALT BEST PRACTICES(最佳实践)
 1 include:
 2   - mysql.testerdb
 3 
 4 testdb_user:
 5   mysql_user.present:
 6     - name: {{ salt['pillar.get']('mysql:lookup:user') }}
 7     - password: {{ salt['pillar.get']('mysql:lookup:password') }}
 8     - host: {{ salt['pillar.get']('mysql:lookup:host') }}
 9     - require:
10       - sls: mysql.testerdb
View Code