fangpsh's blog

saltsatck 动态sls组织方式

假设在 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 放在约定好的目录,就能自动关联上,非常简单。