[toc]
线上所有的统一配置管理工具均有saltstack完成 完成的线上任务:
用于系统的初始化
用于开源软件的配置管理,包括
用于管理c++开发的所有组件配置已经更新
SaltStack,一种全新的基础设施管理方式,部署轻松,在几分钟内可运行起来,扩展性好,很容易管理上万台服务器,速度够快,服务器之间秒级通讯。
SaltStack采用C/S模式,server端就是salt的salt-master,client端为salt-minion,minion与master之间通过ZeroMQ消息队列通信
minion上线后先与master端联系,把自己的pub key发过去,这时master端通过salt-key -L命令就会看到minion的key,接受该minion-key后,也就是master与minion已经互信
master可以发送任何指令让minion执行了,salt有很多可执行模块,比如说cmd模块,在安装minion的时候已经自带了,它们通常位于你的python库中,locate salt | grep /usr/ 可以看到salt自带的所有东西。
具体步骤如下
Salt stack的Master与Minion之间通过ZeroMq进行消息传递,使用了ZeroMq的发布-订阅模式,连接方式包括tcp,ipc
salt命令,将cmd.run ls命令从salt.client.LocalClient.cmd_cli发布到master,获取一个Jodid,根据jobid获取命令执行结果。
master接收到命令后,将要执行的命令发送给客户端minion。
minion从消息总线上接收到要处理的命令,交给minion._handle_aes处理
minion._handle_aes发起一个本地线程调用cmdmod执行ls命令。线程执行完ls后,调用minion._return_pub方法,将执行结果通过消息总线返回给master
master接收到客户端返回的结果,调用master._handle_aes方法,将结果写的文件中
salt.client.LocalClient.cmd_cli通过轮询获取Job执行结果,将结果输出到终端。
saltstack的包已经加入EPEL源,可以直接通过yum安装
salt-master 安装
yum install salt-master
salt-minion 安装
wget -O install_salt.sh https://bootstrap.saltstack.com --no-check-certificate && sh install_salt.sh
指定执行命令或者模块应用在哪个Minion上
bash
salt 'Dy-JXQ-101' test.ping
bash
salt -E 'Dy-JXQ-9(1-2)$' test.ping
grains
salt -G "os:CentOS" test.ping
# 查看所有grains的键值
salt 'test' grains.items
# 查看所有grains项
salt 'test' grains.ls
# 查看某个grains的值
salt 'test' grains.item num_cpus
在top file中匹配grains ```bash 'node_type:webserver':
nodegroups 是对minion分组
# /etc/salt/master.d/nodegroup.conf
nodegroups:
test1: 'L@test1, test2 or test3'
test2: 'G@os:CentOS or test2'
salt -N test1 test.ping
同Target类似例子 使用命令可以执行各种命令
salt -E 'Dy-JXQ-10[1-9]$' cmd.run "uptime"
多个Master,在我们的生产环境中还未正式使用 多Master需要注意的地方:
Pillar在salt中是非常重要的组成部分,利用它可以完成动态的数据调整,可以使用sls文件编写 适用场景
salt '*' pillar.items
salt '*' pillar.item <key>
salt '*' pillar.get <key>:<key>
指定pillar_roots,默认是/srv/pillar
在top file中使用pillar ```bash '*':
在state中通过jinja使用pillar数据
{% set zabbix_conf = salt['pillar.get']('zabbix_agent:config_settings', config_map, merge=True) %}
Grains主要提供一种对服务器静态信息的描述,可以对Grains增加自己对服务器节点的描述 grains的解析使用yaml模块进行解析,所以对齐是必须的,否则会出现不可预料的错误
通常Grains所提供的键值对有以下三种:
针对常用的键值对,比如系统版本号,网卡地址,mac地址,salt有一套原生的grains定义,该定义均由salt官方提供的python脚本提供,这些python脚本均内置到salt中
通过编写minion端的/etc/salt/grains 加入额外的grains定义
environment: live
node_type:
- webserver
- memcache
- room_service
- redis
- nginx_lua
通过编写master端的/etc/salt/_grains目录下的python脚本,自定义需要的grains值
def hello():
agrain = {}
agrain['hello'] = 'saltstack'
return agrain
符合salt自己自定义的要求返回一个字典即可 在三种情况下,会执行_grains目录下的py脚本
它的核心是SLS(salt state file),文件默认是YAML格式,并默认使用jinja模板 该State是salt的配置管理核心,所有的配置定义均由state文件通过salt解析完成
选取自ntp中的init.sls
# Include :download:`map file <map.jinja>` of OS-specific package names and
# file paths. Values can be overridden using Pillar.
{% from "ntp/map.jinja" import ntp with context %}
{% set service = {True: 'running', False: 'dead'} %}
ntp:
pkg.installed:
- name: {{ ntp.lookup.package }}
{% if 'ntp_conf' in ntp.lookup %}
ntpd_conf:
file.managed:
- name: {{ ntp.lookup.ntp_conf }}
- source: salt://ntp/files/ntp.conf
- template: jinja
- context:
config: {{ ntp.settings.ntp_conf }}
- require:
- pkg: ntp
{% endif %}
{% if salt['service.status']('ntpd') != True %}
correct_time:
cmd.run:
- name: ntpdate 2.asia.pool.ntp.org
{% endif %}
{% if 'ntpd' in ntp.settings %}
ntpd:
service.{{ service.get(ntp.settings.ntpd) }}:
- name: {{ ntp.lookup.service }}
- enable: {{ ntp.settings.ntpd }}
- require:
- pkg: ntp
{% if salt['service.status']('ntpd') != True %}
- cmd: correct_time
{% endif %}
- watch:
- file: ntpd_conf
{% endif %}
通过适当的配置,配置管理的功能和便利性会远超puppet
salt默认的渲染器是yaml_jinja,salt处理我们的sls文件时,会先把文件用jinja2处理,然后传给ymal处理器在处理,然后生成的是salt需要的python数据类型。除了yaml_jinja还有yaml_mako,yaml_wempy,py,pydsl yaml_jinja是默认的,而py是用纯python来写的。
针对我们的业务需求和基于一定的安全考虑 线上的saltstack使用上会区分为
* 北京机房,一个独立的salt-master
* 外网机房,一个独立的salt-master
两个salt-master的代码基本一样,基于room_service和nginx的配置有些微不同 nginx的模块主要是外网代理vhost的不同 room_service外网主要使用MsgRepeater的配置
salt的state配置采用归一化的编排,而针对不同环境的不同变量配置采用pillar的动态特性进行区分 具体实施上采用以下的目录结构
├── pillar
│ ├── bj-test
│ │ ├── douyu_sudo.sls
│ │ ├── epel.sls
│ │ ├── init.sls
│ │ ├── memcache.sls
│ │ ├── mongodb.sls
│ │ ├── nginx_lua.sls
│ │ ├── nginx.sls
│ │ ├── ntp.sls
│ │ ├── openssh.sls
│ │ ├── phpfpm.sls
│ │ ├── redis.sls
│ │ ├── room_service.sls
│ │ ├── systembase.sls
│ │ └── zabbix_agent.sls
│ ├── dev
│ │ ├── douyu_sudo.sls
│ │ ├── epel.sls
│ │ ├── init.sls
│ │ ├── memcache.sls
│ │ ├── mongodb.sls
│ │ ├── nginx.sls
│ │ ├── ntp.sls
│ │ ├── openssh.sls
│ │ ├── phpfpm.sls
│ │ ├── redis.sls
│ │ ├── room_service.sls
│ │ ├── systembase.sls
│ │ └── zabbix_agent.sls
│ ├── live
│ │ ├── douyu_sudo.sls
│ │ ├── epel.sls
│ │ ├── init.sls
│ │ ├── memcache.sls
│ │ ├── mongodb.sls
│ │ ├── nginx_lua.sls
│ │ ├── nginx.sls
│ │ ├── ntp.sls
│ │ ├── openssh.sls
│ │ ├── phpfpm.sls
│ │ ├── redis.sls
│ │ ├── room_service.sls
│ │ ├── systembase.sls
│ │ └── zabbix_agent.sls
│ ├── pressure
│ │ ├── douyu_sudo.sls
│ │ ├── epel.sls
│ │ ├── init.sls
│ │ ├── memcache.sls
│ │ ├── mongodb.sls
│ │ ├── nginx.sls
│ │ ├── ntp.sls
│ │ ├── openssh.sls
│ │ ├── phpfpm.sls
│ │ ├── redis.sls
│ │ ├── room_service.sls
│ │ ├── systembase.sls
│ │ └── zabbix_agent.sls
│ ├── prod
│ │ ├── douyu_sudo.sls
│ │ ├── epel.sls
│ │ ├── init.sls
│ │ ├── memcache.sls
│ │ ├── mongodb.sls
│ │ ├── nginx.sls
│ │ ├── ntp.sls
│ │ ├── openssh.sls
│ │ ├── phpfpm.sls
│ │ ├── redis.sls
│ │ ├── room_service.sls
│ │ ├── systembase.sls
│ │ └── zabbix_agent.sls
│ └── top.sls
└── salt
├── douyu_sudo
├── epel
├── _grains
├── memcache
├── mongodb
├── mysql
├── nginx
├── nginx_lua
├── ntp
├── openssh
├── phpfpm
├── redis
├── room_service
├── systembase
├── zabbix_agent
└── top.sls
利用pillar的top.sls入口文件,对符合的主机进行环境区分
所有主机都必须在/etc/salt/grains中指定 'environment:prod/live/pressure/dev/bj-test‘ 用于标示主机是否属于生产环境或者测试环境
top.sls文件示例 ```python
{% set environment = salt['grains.get']('environment', '') %} include:
{{ environment }}
python
{% set environment = salt['grains.get']('environment', '') %} {{ saltenv if saltenv != None else env }}: '*':
{{ environment }}.epel
{{ environment }}.ntp
{{ environment }}.systembase
{{ environment }}.openssh
{{ environment }}.zabbix_agent
{{ environment }}.douyu_sudo
'node_type:webserver':
- match: grain
- {{ environment }}.nginx
- {{ environment }}.phpfpm
'node_type:nginx':
- match: grain
- {{ environment }}.nginx
'node_type:nginx_lua':
- match: grain
- {{ environment }}.nginx_lua
'node_type:phpfpm':
- match: grain
- {{ environment }}.phpfpm
'node_type:memcache':
- match: grain
- {{ environment }}.memcache
'node_type:redis':
- match: grain
- {{ environment }}.redis
'node_type:mongodb':
- match: grain
- {{ environment }}.mongodb
'node_type:room_service':
- match: grain
- {{ environment }}.room_service
其中的node_type为自定义grains,用来区分主机需要安装的服务类型
#### 典型的salt模块目录组成
salt的所有使用的模块基本是自有,线上所提供的各种开源模块无法符合自身业务的需求
以nginx目录结构为例
```nginx
nginx
├── files
│ ├── conf
│ │ ├── mime.types
│ │ └── nginx.conf
│ ├── initd
│ │ └── nginxd
│ ├── logrotate
│ │ ├── nginxd
│ │ └── nginx_logfile_logrotate.py
│ ├── monitor
│ │ ├── nginx.conf
│ │ ├── nginx_monitor.conf
│ │ └── nginx_status.sh
│ ├── nginx_install.sh
│ ├── ssl_conf
│ │ ├── server.key
│ │ ├── server.pem
│ │ ├── ybadmin.crt
│ │ └── ybadminv1.key
│ ├── tar_package
│ │ ├── nginx-1.8.0.tar.gz
│ │ ├── Nginx-accesskey-2.0.3.tar.gz
│ │ └── ngx_cache_purge-master.zip
│ ├── vhost
│ │ ├── cooperate
│ │ │ ├── backend
│ │ │ │ ├── cooperate.backend.036yx.com.conf
│ │ │ │ ├── cooperate.backend.2144.com.conf
│ │ │ │ └── cooperate.backend.ilongyuan.com.cn.conf
│ │ │ └── edge
│ │ │ ├── cooperate.proxy.036yx.com.conf
│ │ │ ├── cooperate.proxy.2144.com.conf
│ │ │ └── cooperate.proxy.ilongyuan.com.cn.conf
│ │ └── core
│ │ ├── backend
│ │ │ ├── adsys.douyutv.com.conf
│ │ │ ├── api.douyutv.com.conf
│ │ │ ├── file.douyutv.com.conf
│ │ │ ├── ssl.douyutv.com.conf
│ │ │ ├── static2.douyutv.com.conf
│ │ │ ├── staticdn.douyutv.com.conf
│ │ │ ├── staticlive.douyutv.com.conf
│ │ │ ├── uc.douyutv.com.conf
│ │ │ ├── upload.douyutv.com.conf
│ │ │ └── www.douyutv.com.conf
│ │ └── edge
│ │ ├── proxy_adsys.douyutv.com.conf
│ │ ├── proxy_api.douyutv.com.conf
│ │ ├── proxy_ssl.douyutv.com.conf
│ │ ├── proxy_static2.douyutv.com.conf
│ │ ├── proxy_staticlive.douyutv.com.conf
│ │ ├── proxy_uc.douyutv.com.conf
│ │ ├── proxy_www.douyutv.com.conf
│ │ └── proxy_ybadmin.douyutv.com.conf
│ └── web_rsync
│ ├── exclude.txt
│ ├── rsync.pwd
│ └── webrsync.sh
├── init.sls
├── map.jinja
└── states
├── config.sls
├── install.sls
├── logrotate.sls
├── monitor.sls
├── service.sls
├── user.sls
└── vhost_conf
├── cooperate_backend_vhost_group.sls
├── cooperate_proxy_vhost_group.sls
├── core_backend_vhost_adsys.sls
├── core_backend_vhost_fileupload.sls
├── core_backend_vhost_group.sls
├── core_backend_vhost_ssl.sls
├── core_backend_vhost_staticdn.sls
├── core_backend_vhost_uc.sls
├── core_proxy_vhost_group.sls
├── core_proxy_vhost_ssl.sls
├── douyu.sls
└── yuba_proxy_vhost_ybadmin.sls
现在使用的模块分为
salt
├── douyu_sudo # 控制服务器的sudo权限
├── epel # 控制所有CentOS主机的epel源
├── _grains # 扩展grains
├── memcache # memcache的配置管理
├── mongodb # mongodb的配置管理,暂时未上线
├── mysql # mysql的配置管理,暂时未上线
├── nginx # nginx的配置管理,包括所有在线使用的webserver
├── nginx_lua # nginx_lua环境模块,应php要求新加入的配置管理
├── ntp # ntp配置管理,控制所有服务器的ntp client同步时间
├── openssh # 服务器的ssh服务管理
├── phpfpm # phpfpm进程配置管理,线上使用的配置统一一致,个别phpfpm特殊需求
├── redis # redis的配置管理,负责控制所有redis主从关系
├── room_service # c++组件的配置管理,部分功能未启用
├── systembase # 系统初始化的配置管理,包括安装包,kernel参数优化
├── zabbix_agent # zabbix_agent的配置管理,监控客户端
└── top.sls # 入口文件