假设在 CMDB 中,有类似如下的树状结构:
- 中心/center
- 平台/platform
- 服务/service
- 集群/cluster
- 服务器
- CDN 中心
- 静态分发平台
- 边缘调度服务
- 集群 A
- server101
可以使用gitfs 将 sls 文件都托管在内部仓库中,进行跨部门协作,共同维护。
当 salt-minion state.highstate 应用时,可以按照当前机器在 CMDB 中所属的层次/角色,进行 动态应用 sls。
例如上文中的 server101,先应用CDN 中心下的 sls,再应用静态分发平台下的 sls,一层一层往下(可以按需加更多的层级,例如 集群层级下再加角色等)。
要做到这个效果,首先CMDB 需要能输出机器的动态 pillar,在 salt-master 配置好ext_pillar ,可以指定shell 脚本:
ext_pillar:
- cmd_json: /path/get_cmdb_pillar.sh %s
机器的 pillar 输出:
{
"center": [
cdn,
...
],
"platform": [
"cdn/static_cdn",
...
],
"service": [
"cdn/static_cdn/dispatch"
],
"cluster": [
"cdn/static_cdn/dispatch/mainland"
],
....
}
全局的 top.sls 按照如下写法:
base:
'*':
- base
{% set center_list = salt.pillar.get('center', [])-%}
{% if center_list -%}
{% for c in center_list -%}
{% if salt['state.sls_exists']('{0}.base'.format(c)) %}
'center:{{ c }}':
- match: pillar
- {{ c }}.base
{% endif -%}
{% endfor -%}
{% endif -%}
{% set platform_list = salt.pillar.get('platform', [])-%}
{% if platform_list -%}
{% for p in platform_list -%}
{% if salt['state.sls_exists']('{0}.base'.format(p)) %}
'platform:{{ p }}':
- match: pillar
- {{ p }}.base
{% endif -%}
{% endfor -%}
{% endif -%}
.....
{% endif -%}
当然,按如上写法,要对 sls 仓库目录进行一些约定,按每一个层级组织放置 sls,base 目录放每一层的公共基础 sls 。公共复用的 sls 抽象出来,例如放在 addon/ 之类的目录中。制定协作公约,在仓库 pr 流程中code review。
.
├── addon addon sls,供其他sls include,分目录组织
│ ├── x1
│ └── x2
├── base 全局基础初始化sls
│ ├── init.sls
│ ├── c1.sls
│ └── ...
├── cdn CDN 中心
│ ├── base CDN 中心的全局初始化/基础sls
│ │ └── init.sls
│ └── static_cdn 静态 CDN 平台
│ ├── base 平台的全局初始化/基础sl s
│ └── dispatch 调度服务
| ├── base 调度服务的sls
| │ └── init.sls
| └── mainland 大陆集群
| | 大陆集群下的sls
| └── init.sls
|
└── top.sls 全局路由文件
最后达到的效果是,当运维人员给特定集群,或特定服务的机器安装某些软件包,或者渲染生成配置等,写好 sls 放在约定好的目录,就能自动关联上,非常简单。