在一套完整的CMDB系统中,需要能对整个服务器集群进行统一的管理。在RDS中,我们选用了SaltStack来管理所有的数据库服务器和上面的实例。
一 SaltStack简介
SaltStack是一款Python编写的,结合了消息队列服务ZeroMQ,用于大规模批量管理服务器的工具,支持在管理端主节点(Master)执行命令来远程配置复数客户端从节点(Minion),包括执行特定命令、传输文件、安装服务、配置定时任务等常用操作。
一个完整的通讯流程包括如下几步:
1.Master执行salt命令,命令通过salt.client.LocalClient.cmd_cli方法发送到Master,Master生成一个jid,并根据jid等待获取执行结果。
2.Master将salt命令通过ret_port端口,发送给客户端Minion。
3.Minion收到消息后发起一个线程执行salt命令,调用Minion._return_pub方法将执行结果返回给Master。
4.Master接收Minion返回的结果,并调用 Master.handle_aes将结果写入文件中。
5.salt.client.LocalClient.cmd_cli通过轮询获取到Job执行结果,并将结果输出到终端。
一次salt请求执行完毕,下面我们安装并部署服务。
二 安装部署
我们选择两台主机:Master:10.0.0.1,Slave:10.0.0.2(Minion1)来演示部署SaltStack服务的流程。
在Master节点部署服务
[[email protected] ~]# yum install –y epel-release
[[email protected] ~]# yum install –y salt-master salt-minion
[[email protected] ~]# vi /etc/salt/master
cachedir: /var/cache/salt
keep_jobs: 24
file_roots:
base:
- /srv/salt/
dev:
- /srv/salt/dev/services
- /srv/salt/dev/states
prod:
- /srv/salt/prod/services
- /srv/salt/prod/statesq
publish_port: 4505
ret_port: 4506
/etc/salt/master是salt-master的默认配置文件,每次修改后都需要重启该服务。在这里我们主要关注如上几个参数,并可根据需求进行修改:
1.cachedir:放置salt命令执行的缓存信息,大量的调用会使该目录存在过多缓存,可以更换存放路径
2.keep_jobs:cachedir中保持缓存信息的时间,默认为24小时
3.file_roots:salt执行文件时默认的脚本所在地址,后文涉及到的sls文件也在该目录中
4.publish_port,ret_port:代表salt的消息发布系统端口和节点间通信端口,默认为4505,4506,请避免这两个端口被占用。
配置完成后启动salt-master服务
[[email protected] ~]# service salt-master start
[[email protected] ~]# service salt-master status
● salt-master.service - The Salt Master Server
Loaded: loaded (/usr/lib/systemd/system/salt-master.service; enabled; vendor preset: disabled)
Active: active (running) since Mon 2018-07-16 19:30:59 CST; 3 weeks 6 days ago
在Minion节点部署服务
[[email protected] ~]# yum install –y salt-minion
[[email protected] ~]# vi /etc/salt/minion
master: 10.0.0.1
id: Minion1
/etc/salt/minion是salt-minion的默认配置文件,需要修改两个参数:
1.master:可以配置为Master主机的IP或是hostname。
2.id:Minion的标识,Master通过Minion的id发送命令,请根据业务关系进行配置。
启动salt-minion服务
[[email protected] ~]# service salt-minion start
[[email protected] ~]# service salt-minion status
Redirecting to /bin/systemctl status salt-minion.service
● salt-minion.service - The Salt Minion
Loaded: loaded (/usr/lib/systemd/system/salt-minion.service; enabled; vendor preset: disabled)
Active: active (running) since Mon 2018-07-16 19:31:55 CST; 3 weeks 6 days ago
启动后,为了配置Master和Minion节点间的互信关系,Minion会生成公私钥一对,并将公钥发送给Master。Master需要执行命令接受该minion-key来确认互信关系。
[[email protected] ~]# salt-key –L
Accepted Keys:
Denied Keys:
Unaccepted Keys:
Minion1
Rejected Keys:
[[email protected] ~]# salt-key –A –y
The following keys are going to be accepted:
Unaccepted Keys:
Minion1
Key for minion Minion1 accepted.
这样Minion端及与Master的互信就配置完毕,我们简单测试下配置是否成功。
[[email protected] ~]# salt ‘*’ test.ping
Minion1:
True
三 SaltStack管理功能服务器匹配SaltStack支持向多台服务器发送命令,以下实现了多种服务器匹配方式。
salt '*' test.ping //全部匹配
salt 'Minion*' test.ping //部分模糊匹配
salt –L Minion1 test.ping //列表匹配
salt –G ‘os:RedHat’ test.ping //grains类型匹配
salt –S ’10.0.0.0/24’ test.ping //CIDR匹配
以上命令执行结果皆为:
Minion1:
True
执行命令SaltStack支持Master向Minion发送特定的命令来执行各类型功能,常用的有如下几种。① 执行特定命令
[[email protected] ~]# salt Minion1 cmd.run 'uptime' // 执行特定命令
Minion1:
03:58:16 up 435 days, 20:56, 3 users, load average: 0.50, 0.59, 0.48
[[email protected] ~]# salt-run manage.up // 检查所有存活Minion
- Minion1
[[email protected] ~]# salt Minion1 service.get_all // 获取全部服务
...
② 拷贝文件
[[email protected] ~]# salt Minion1 cp.get_file salt://a.sh /tmp/a.sh
Minion1:
/tmp/a.sh
其中salt://目录需要跟上文中Master配置的file_roots目录一致 ③ 远程执行脚本
[[email protected] ~]# salt Minion1 cmd.script salt://a.sh 'a' runas
Minion1:
----------
pid:
9368
retcode:
0
stderr:
stdout:
a
[[email protected] ~]# salt Minion1 cmd.script salt://a.sh 'a' runas='mysql' cwd='/home'
远程脚本默认在/tmp目录执行,可以增加runas和cwd参数修改执行用户和默认路径。④ 部署定时任务
[[email protected] ~]# salt Minion1 cron.set_job root '0' '' '' '' '' 'sh /home/a.sh' '每小时0分执行命令,直接写入Minion的对应用户的crontab中'
Minion1:
new
grains命令
获取服务器的信息可以使用SaltStack自带的grains模块,例如查看Minion1的os信息。
[[email protected] ~]# salt Minion1 grains.item os
Minion1:
RedHat
[[email protected] ~]# salt Minion1 grains.items //查看所有item
...
我们也可以自定义grains信息,修改Minion的配置文件并重启。
[[email protected] ~]# vi /etc/salt/minion
grains:
roles:
- Database
[[email protected] ~]# service salt-minion restart
[[email protected] ~]# salt Minion1 grains.item roles
Minion1:
Database
也可以直接在Master上执行命令来设置grains的值。
[[email protected] ~]# salt Minion1 grains.setval environment 'dev'
Minion1:
----------
environment :
dev
[[email protected] ~]# salt Minion1 grains.item environment
Minion1:
----------
environment :
dev
grains值默认写在Minion的/etc/minion/grains中。
pillar命令
除了grains外,我们还可以用pillar来获取minion的信息。与grains不同的是,pillar是在master节点上配置的,存储一些动态的、比较敏感的数据,默认使用sls文件格式进行存储。
根据/etc/salt/master的默认配置,pillar信息是保存在/srv/pillar中的,我们录入一下pillar信息。在pillar的配置方法中,我们首先要建立一个top.sls文件,用来作为pillar的入口文件,之后再根据不同的配置信息来对应minion的信息。
[[email protected] ~]# mkdir /srv/pillar
[[email protected] ~]# vi /srv/pillar/top.sls
base:
Minion1:
- minion1
之后我们配置对应的minion1.sls文件。
[[email protected] ~]# vi /srv/pillar/minion1.sls
db_user: username
db_passwd: passwd
[[email protected] ~]# salt '*' saltutil.refresh_pillar
里面可以保存一些敏感的信息,例如数据库的用户密码等,之后我们刷新Master的pillar配置来应用新的配置内容。
[[email protected] ~]# salt '*' saltutil.refresh_pillar
[[email protected] ~]# salt Minion1 pillar.items
Minion1:
----------
db_user:
username
db_passwd:
passwd
通过跟grains类似的方式,获取到了item的值。在实际的应用中,我们可以使用grains和pillar完成各种参数和文件的动态配置,这里就不再涉及。下面我们通过安装MySQL实例详细介绍下SaltStack中sls文件的应用。
四 安装MySQL
SLS(Salt State)是SaltStack的配置文件,存放于Master,描述了系统的目标状态,数据格式为YAML。Minion通过从Master上拉取文件来保持状态的一致性,包括配置、服务等一致性,我们可以以此来为Minion安装MySQL服务。
top.sls文件是配置管理的入口文件,默认配置在file_roots上,即/srv/salt目录。sls文件默认从base标签开始解析,来执行分支下面的各类型salt命令或是sls文件等内容。
首先我们看下MySQL安装的目录树。
├── top.sls // 入口文件
├── mysql
│ ├── files // 存放安装配置文件
│ │ ├── my.cnf
│ │ └── mysql-5.6.34.tar.gz
│ │ └── mysqld
│ ├── init.sh // 配置功能
│ ├── init.sls // 环境配置
│ └── install.sls // 安装文件
入口文件:
[[email protected] salt]# cat top.sls
base:
Minion1:
- mysql.init
- mysql.install
环境配置文件:
[[email protected] salt]# cat mysql/init.sls
pkg-init:
pkg.installed:
- names:
- gcc
- gcc-c++
- glibc
- make
- cmake
- autoconf
- libxml2
- libxml2-devel
- zlib
- zlib-devel
- libcurl
- libcurl-devel
- openssl
- openssl-devel
- ncurses
- ncurses-devel
- libtool
安装文件:
[[email protected] salt]# cat mysql/install.sls
include:
- mysql.init
mysql-source-install:
file.managed:
- name: /data/mysql-5.6.34.tar.gz
- source: salt://mysql/files/mysql-5.6.34.tar.gz
- user: root
- group: root
- mode: 755
cmd.run:
- name: cd /data && tar xf mysql-5.6.34.tar.gz && cd mysql-5.6.34 && cmake -DCMAKE_INSTALL_PREFIX=/usr/local/mysql -DMYSQL_DATADIR=/usr/local/mysql/data -DWITH_MYISAM_STORAGE_ENGINE=1 -DWITH_INNOBASE_STORAGE_ENGINE=1 -DWITH_MEMORY_STORAGE_ENGINE=1 -DWITH_READLINE=1 -DMYSQL_UNIX_ADDR=/var/lib/mysql/mysql.sock -DMYSQL_TCP_PORT=3306 -DENABLED_LOCAL_INFILE=1 -DWITH_PARTITION_STORAGE_ENGINE=1 -DEXTRA_CHARSETS=all -DDEFAULT_CHARSET=utf8 -DDEFAULT_COLLATION=utf8_general_ci && make && make install
- require:
- file: mysql-source-install
- unless: test -d /usr/local/mysql
mysql-init:
file.managed:
- name: /data/init.sh
- source: salt://mysql/init.sh
- user: root
- group: root
- mode: 755
cmd.script:
- name: /data/init.sh
- require:
- cmd: mysql-source-install
mysql-config:
file.managed:
- name: /etc/my.cnf
- source: salt://mysql/files/my.cnf
- user: root
- group: root
- mode: 644
- require:
- file: mysql-init
mysql-service:
file.managed:
- name: /etc/init.d/mysqld
- source: salt://mysql/files/mysqld
- user: root
- group: root
- mode: 755
cmd.run:
- name: chkconfig --add mysqld
- unless: chkconfig --list |grep mysqld
- require:
- file: mysql-service
service.running:
- name: mysqld
- require:
- cmd: mysql-service
配置文件:
[[email protected] salt]# cat mysql/init.sh
!/bin/bash
groupadd mysql
useradd -r -g mysql mysql
chown mysql:mysql /usr/local/mysql/ -R
ln -sv /usr/local/mysql/bin/mysql /usr/bin
/usr/local/mysql/scripts/mysql_install_db --user=mysql --basedir=/usr/local/mysql --datadir=/usr/local/mysql/data
上文中详细的步骤就不再赘述,主要是使用salt命令编译安装MySQL的流程,包括检查环境、配置文件、编译安装、初始数据库、启动服务等流程。之后我们执行state命令。
[[email protected] salt]# salt Minion1 state.highstate
...
编译安装耗时较长,安装完成后查看MySQL状态。
[[email protected] ~]# ps -ef|grep mysql
mysql 4981 4801 9 20:33 pts/1 00:00:00 /usr/local/mysql/bin/mysqld --basedir=/usr/local/mysql --datadir=/usr/local/mysql/data --plugin-dir=/usr/local/mysql/lib/plugin --user=mysql --log-error=/usr/local/mysql/data/Minion1.err --pid-file=/usr/local/mysql/data/Minion1.pid --socket=/tmp/mysql_3306.sock --port=3306
五Python API
SaltStack提供了的一套较为完整的Python API,我们的RDS系统也主要通过这些API来实现salt调度。在这里我们简要的介绍下salt.client.LocalClient方法。
[[email protected] ~]# python
import salt.config
master_opts = salt.config.client_config('/etc/salt/master') // 加载并输出salt-master配置文件配置,可选
import salt.client
local = salt.client.LocalClient()
这样便启动了一个salt客户端,之后我们介绍下各种功能。
① cmd: 向目标Minion同步执行命令。
local.cmd(salt_list,
commands,
args,
kwargs)
上文中的salt命令可改写为:
local.cmd('Minion1', 'cmd.run', 'uptime')
local.cmd('Minion1', 'cmd.script', ['salt://a.sh', 'a', 'cwd=/home', 'runas=mysql', 'shell="'/bin/bash"'], expr_form='list', show_timeout=True)
salt_list:上文服务器匹配一节中对应的Minion列表。
commands:可以写入单条或多条命令,如'cmd.run',['cmd.run', 'cmd.script'],对应的args参数列表为[args],[[args1], [args2]]。
args:参数列表,与对应salt命令所支持的参数一致。
kwargs:额外参数,如show_timeout等。
② cmd_async: 向目标Minion异步执行命令。
local.cmd_async(salt_list,commands,args,kwargs)
local.cmd_async('Minion1', 'test.ping')
'20180926174113609129'
local.get_cache_returns('20180926174113609129')
{'Minion1': {'ret': True}}
可看出参数结构与cmd一致,区别是返回一条jid。我们需要执行get_cache_returns来判断salt命令是否完成。这个命令常用在耗时较长的任务上。
欢迎关注乐得DBA,微信号关注lede_dba