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文件清晰的目录结构
示例:
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
top文件:
1 base: 2 'web*': 3 - mysql.client 4 - mysql.python 5 'db*': 6 - mysql.server
这样定义的结构比较清晰。
STRUCTURING PILLAR FILES
pillar文件结构
默认pillar环境目录被定义在/srv/pillar/中,pillar文件一般被用来包含其他pillar文件和设置基于环境和grains的匹配关系。
示例:
1 base: 2 '*': 3 - packages
复杂一点的示例:
1 base: 2 '*': 3 - packages 4 'web*': 5 - apache 6 - vim
多环境的配置示例:
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
这可以避免为每一个环境设置一个pillar环境目录,如果配置不当容易引起混乱,每一个在pillar中被包含的sls文件都必须位于定义pillar目录下。
一个pillar中的sls文件示例:
1 /srv/pillar/apache.sls: 2 apache: 3 lookup: 4 name: httpd 5 config: 6 tmpl: /etc/httpd/httpd.conf
VARIABLE FLEXIBILITY
灵活的使用变量,并且为变量设置默认值
一个sls文件中的变量使用示例:
/srv/salt/apache/conf.sls:
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
变量可以在sls文件中被定义,但是不推荐,这样丧失了变量使用的灵活性。
上面这种情况可以使用pillar存储这些变量信息,也便于其他state文件引用:
/srv/pillar/apache.sls:
1 apache: 2 lookup: 3 name: httpd 4 config: 5 tmpl: salt://apache/files/httpd.conf
/srv/salt/apache/conf.sls:
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
上例可以提供一个为用户集中处理和引用变量的环境。
MODULARITY WITHIN STATES
模块化的状态文件配置,当配置一个sls文件的时候,要考虑要这个文件会被重用多少次
/srv/salt/apache/init.sls:
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
上面的sls文件配置是一个相当糟糕的示例,利用state ID作为配置的一部分,非常不利于重用,且source等配置都是写死了。
优化的示例,使用-name参数来取代state ID作为需要安装的包名,state ID应该被定义为一个配置的描述字段。
/srv/salt/apache/init.sls:
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
同样上例也存在一些问题,当配置需要依赖的环境较多的时候,类似的配置将被重复进行定义很多次
进一步优化的示例,将配置逻辑判断放在一个jinja文件中:
/srv/salt/apache/map.jinja:
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')) %}
/srv/pillar/apache.sls:
1 apache: 2 lookup: 3 config: 4 tmpl: salt://apache/files/httpd.conf
/srv/salt/apache/init.sls:
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
上面的例子就显得比较灵活了,将minion的判断逻辑抽象在map.jinja中,master需要引入的配置变量放在pillar中,这样的sls文件在配置变更上就显得比较灵活,但是还是存在一个问题,就是功能模块不够清晰,一个sls文件中包含了两个不同功能的类型配置,包安装和配置文件同步应该进行拆解,如下例:
/srv/salt/apache/init.sls:
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
/srv/salt/apache/conf.sls:
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
STORING SECURE DATA
存储数据的安全性
当我们有一些敏感信息需要在服务器端被定义的时候,如果将这些敏感信息直接放在sls文件中,那么minion端将都会收到这些敏感信息,最好的办法是将敏感的数据放在pillar中,确保指定的机器能够去访问这些数据,示例:
/srv/salt/mysql/testerdb.sls:
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
将数据放在pillar中的实例:
/srv/pillar/mysql.sls:
1 mysql: 2 lookup: 3 name: testerdb 4 password: test3rdb 5 user: frank 6 host: localhost
/srv/salt/mysql/testerdb.sls:
1 testdb: 2 mysql_database.present: 3 - name: {{ salt['pillar.get']('mysql:lookup:name') }}
/srv/salt/mysql/user.sls:
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