saltstack部署
saltstack简介
SaltStack是一个运维自动化基础平台管理工具,只需要花费数分钟即可运行起来,可以支撑管理上万台服务器的规模。由于master和minion端数据传输是通过zeromq消息中间件并发异步传输数据,所以数秒钟即可完成数据传递。SaltStack是使用Python语言开发的,同时提供Rest API方便二次开发以及和其它平台进行集成,同时官方也发布了一个Web管理界面halite。
SaltStack常用网址:
- 官方网站:http://www.saltstack.com
- 官方文档:http://docs.saltstack.com 或参考unixhot.com提供的文档:https://www.unixhot.com/docs/saltstack/contents.html
- GitHub:https://github.com/saltstack
- 中国SaltStack⽤户组:http://www.saltstack.cn
SaltStack有四种运行方式:
- Local
- Master/Minion
- Salt SSH
- Salt-Syndic 多机房架构的部署方式
SaltStack的传统运行模式为Master/Minion(C/S结构),需要在被管理的节点上安装Minion。同时SaltStack也支持SSH的方式,无需安装Agent,通过SSH实现管理。
SaltStack目前拥有三大主要功能:
- 远程执行
- 配置管理
- 云管理
saltstack部署及功能运用
SaltStack支持多种操作系统,如CentOS、RedHat、Debian、Ubuntu、FreeBSD、Solaris、Fedora、SuSe、Gentoo、MAC OS X、Archlinux等,以及Windows(仅支持Minion)。
===>>服务器部署saltstack环境
| master端 | minion端 | minion端 |
|
hostname: linux-node1.goser.com ip: 192.168.1.11 |
hostname: linux-node2.goser.com ip: 192.168.1.12 |
hostname: linux-node3.goser.com ip: 192.168.1.13 |
如果没有dns服务器提供域名解析,应该保持各个设备的hosts文件一致:
[root@linux-node1 ~]# cat /etc/hosts 127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4 ::1 localhost localhost.localdomain localhost6 localhost6.localdomain6 192.168.1.11 linux-node1.goser.com linux-node1 192.168.1.12 linux-node2.goser.com linux-node2 192.168.1.13 linux-node3.goser.com linux-node3
saltstack安装,使用yum安装时最直接和快捷的,首先需要安装EPEL仓库,这里使用的是阿里提供epel源。当然也可以使用saltstack官方提供的epel源来安装:下载地址为repo.saltstack.com
#master端saltstack安装salt-master [root@linux-node1 ~]# yum install -y salt-master #2个minion端saltstack安装salt-minion [root@linux-node2 ~]# yum install -y salt-minion [root@linux-node3 ~]# yum install -y salt-minion
修改配置文件,启动saltstack服务。master端的配置文件暂时不需要修改,后期配置状态文件再做修改,现在只需要修改minion端配置文件即可
首先了解saltstack配置文件主要参数说明:
#/etc/salt/master配置文件主要参数
interface: 指定bind 的地址(默认为0.0.0.0)
publish_port: 指定发布端⼝(默认为4505)
ret_port: 指定结果返回端⼝, 与minion配置文件中的master_port对应(默认为4506)
user: 指定master 进程的运行用户, 如果调整, 则需要调整部分目录的权限(默认为root)
timeout: 指定timeout时间, 如果minion规模庞大或网络状况不好,建议增加该值(默认5s)
keep_jobs: 默认情况下, minion 会执行结果会返回master, master会缓存到本地的cachedir 目录, 该参数指定缓存多长时间, 以供查看之前的执行结果, 会占用磁盘空间(默认为24h)
job_cache: master 是否缓存执行结果, 如果规模庞大(超过5000台), 建议使用其他方式来存储jobs, 关闭本选项(默认为True)
file_recv : 是否允许minion传送文件到master 上(默认是Flase)
file_roots: 指定file server目录, 默认为:
file_roots:
base:
- /srv/salt
pillar_roots : 指定pillar 目录, 默认为:
pillar_roots:
base:
- /srv/pillar
log_level: 执行日志级别, 支持的日志级别有'garbage', 'trace', 'debug', info', 'warning', 'error', ‘critical ’ ( 默认为’warning’)
#/etc/salt/minion配置文件主要参数
master: 指定master 主机(默认为salt)
master_port: 指定认证和执行结果发送到master 的哪个端⼝, 与master 配置文件中的ret_port 对应(默认
为4506)
id: 指定本minion的标识. salt内部使用id 作为标识(默认为fqdn主机名)
user: 指定运行minion的用户. 由于安装包,启动服务等操作需要特权用户, 推荐使用root( 默认为root)
cache_jobs : minion 是否缓存执行结果(默认为False)
backup_mode: 在文件操作(file.managed 或file.recurse) 时, 如果文件发生变更,指定备份目标. 当前有效
的值为minion, 备份在cachedir/file_backups目录下, 以原始文件名称加时间戳来命名(默认为Disabled)
providers : 指定模块对应的providers, 如在RHEL系列中, pkg对应的providers 是yumpkg5
renderer: 指定配置管理系统中的渲染器(默认值为:yaml_jinja )
file_client : 指定file clinet 默认去哪里(remote 或local) 寻找文件(默认值为remote),如果环境中无master,这里可以设置成local
loglevel: 指定日志级别(默认为warning)
tcp_keepalive : minion 是否与master 保持keepalive 检查, zeromq3 以下版本存在keepalive bug,会导致某些情况下连接异常后minion无法重连master. 建议有条件的话升级到zeromq 3以上版本(默认为True)
根据上面的配置文件配置参数说明,配置如下:
#修改minion端的配置文件minion,只需要设置master是哪个设备,至于id保持配置默认的使用fqdn即可 [root@linux-node2 ~]# vim /etc/salt/minion master: linux-node1 # Explicitly declare the id for this minion to use, if left commented the id # will be the hostname as returned by the python call: socket.getfqdn() # Since salt uses detached ids it is possible to run multiple minions on the # same machine but with different ids, this can be useful for salt compute # clusters. #id: #如果minion端是windows系统,安装saltsatck如下: #在https://repo.saltstack.com/#windows窗口中下载最新相对应的Salt-Minion-*-Setup.exe 直接运行安装即可 #也可以在cmd窗口,通过命令安装: Salt-Minion-*-Setup.exe /S /master=master-ip /minion-name=minion-name #启动服务,首先启动master,然后再启动minion [root@linux-node1 ~]# /etc/init.d/salt-master start [root@linux-node2 ~]# /etc/init.d/salt-minion start [root@linux-node3 ~]# /etc/init.d/salt-minion start #配置开机自启动 [root@linux-node1 ~]# chkconfig salt-master on [root@linux-node2 ~]# chkconfig salt-minion on [root@linux-node3 ~]# chkconfig salt-minion on
SaltStack认证:
Salt的数据传输是通过AES加密的,Master和Minion之间在通信之前,需要进行认证。通过认证的方式保证安全性,完成一次认证后,Master就可以自由的控制Minion来完成各项工作了。
1、minion在第一次启动时,会在/etc/salt/pki/minion/(该路径在/etc/salt/minion里面设置)下自动生成minion.pem(private key)和minion.pub(public key),然后将minion.pub发送给master,会在master这个目录(/etc/salt/pki/master/minions_pre/)中存放minion端的秘钥文件minion.pub
2、master在第一次启动时,会在/etc/salt/pki/master下自动生成master.pem和master.pub。在接收到minion的public key后,通过salt-key命令accept minion public key,这样在master的/etc/salt/pki/master/minions下的将会存放以minion id命名的public key, 而/etc/salt/pki/master/minions_pre/目录下的public key就会移到/etc/salt/pki/master/minions下,同时客户端会保存一份master的public key,在/etc/salt/pki/minion_master.pub
3、通过两个步骤的验证,master就能对minion发送指令了。
master端认证minion端
只有Master接受了Minion的Key后,才能进行管理,使用salt-key作为master和minion的认证过程。
#salt-key的常用命令如下,当然也可以使用salt-key --help查看命令的详细说明 -a ACCEPT, --accept=ACCEPT Accept the following key -A, --accept-all Accept all pending keys -r REJECT, --reject=REJECT Reject the specified public key -R, --reject-all Reject all pending keys -d DELETE, --delete=DELETE Delete the named key -D, --delete-all Delete all keys #一次只认证一个minion,使用salt-key -a minion-fqdn [root@linux-node1 ~]# salt-key -a linux-node2.goser.com -y Accepted Keys: Denied Keys: Unaccepted Keys: linux-node2.goser.com linux-node3.goser.com Rejected Keys: #一次性全部认证 [root@linux-node1 ~]# salt-key -A -y Accepted Keys: Denied Keys: Unaccepted Keys: linux-node2.goser.com linux-node3.goser.com Rejected Keys: #认证完成后,使用salt-key或者使用salt-key -L查看认证结果 [root@linux-node1 ~]# salt-key -L Accepted Keys: linux-node2.goser.com linux-node3.goser.com Denied Keys: Unaccepted Keys: Rejected Keys:
===>>saltstack功能运用
SaltStack远程执行:
远程执行时SaltStack的核心功能之一。主要使用salt模块可以批量给选定的Minion端执行相应的命令,并获得返回结果。让我们执行第一个Salt命令。
[root@linux-node1 ~]# salt '*' test.ping
linux-node3.goser.com:
True
linux-node2.goser.com:
True
上面的命令用来查看有哪些Minion节点连接到Master。* 指的是选定的目标Minion,很显然代表所有。就是所有Minion端了。test.ping是salt远程执行的一个模块。(注意:这并不是一个ICMP ping。)
1)远程执行之目标选择:
目标选择的方式有:1、通配符;2、列表;3、正则表达式;4、子网或ip地址;5、使用Grains;6、使用Pillar;7、使用混合匹配等
#使用通配符做目标选择
[root@linux-node1 ~]# salt '*' test.ping
linux-node3.goser.com:
True
linux-node2.goser.com:
True
[root@linux-node1 ~]# salt 'linux-node2*' test.ping
linux-node2.goser.com:
True
[root@linux-node1 ~]# salt 'linux-node?.goser.com' test.ping
linux-node3.goser.com:
True
linux-node2.goser.com:
True
[root@linux-node1 ~]# salt 'linux-node[2|3].goser.com' test.ping
linux-node3.goser.com:
True
linux-node2.goser.com:
True
[root@linux-node1 ~]# salt 'linux-node[2-3].goser.com' test.ping
linux-node3.goser.com:
True
linux-node2.goser.com:
True
[root@linux-node1 ~]# salt 'linux-node[!2].goser.com' test.ping
linux-node3.goser.com:
True
#使用列表来选择目标
[root@linux-node1 ~]# salt -L 'linux-node2.goser.com,linux-node3.goser.com' test.ping
linux-node2.goser.com:
True
linux-node3.goser.com:
True
#使用正则表达式来选择目标
[root@linux-node1 ~]# salt -E 'linux-(node2|node3).*' test.ping
linux-node3.goser.com:
True
linux-node2.goser.com:
True
#使用子网或ip地址来选择目标
[root@linux-node1 ~]# salt -S 192.168.1.12 test.ping
linux-node2.goser.com:
True
[root@linux-node1 ~]# salt -S 192.168.1.0/24 test.ping
linux-node2.goser.com:
True
linux-node3.goser.com:
True
#使用grains来匹配目标
[root@linux-node1 ~]# salt -G 'os:CentOS' test.ping
linux-node3.goser.com:
True
linux-node2.goser.com:
True
#使用混合匹配选择目标
[root@linux-node1 ~]# salt -C 'G@os:CentOS or linux-node2.goser.com' test.ping
linux-node2.goser.com:
True
linux-node3.goser.com:
True
2)远程执行之模块
saltstack自带的模块有100多个,生产环境使用完全足够了,但是有时候需要自定义模块来作为个性化配置。
[root@linux-node1 ~]# salt 'linux-node2.goser.com' sys.list_modules|wc -l 112
比如使用pkg模块安装工具包,通过远程执行来安装
#对目标主机linux-node2.goser.com安装lrzsz工具 [root@linux-node1 ~]# salt 'linux-node2.goser.com' pkg.install lrzsz #对目标主机linux-node2.goser.com卸载lrzsz工具 [root@linux-node1 ~]# salt 'linux-node2.goser.com' pkg.remove lrzsz
再比如使用service模块管理远程主机的服务
#查看远程主机的sshd服务状态
[root@linux-node1 ~]# salt 'linux-node2.goser.com' service.status sshd
linux-node2.goser.com:
True
#关闭远程主机的sshd服务
[root@linux-node1 ~]# salt 'linux-node2.goser.com' service.stop sshd
linux-node2.goser.com:
True
#开启远程主机的sshd服务
[root@linux-node1 ~]# salt 'linux-node2.goser.com' service.start sshd
linux-node2.goser.com:
True
使用cmd.run模块来远程执行的话,可以对远程主机任意操作,这个模块使用比较危险,所以一般生产环境中尽可能的对使用者禁用这个模块,可以通过saltstack acl来控制cmd模块的使用
#修改master配置文件,让salt用户只能使用某些模块来操作
#比如下面设置zyx用户只能使用test和network模块来操作远程执行
vim /etc/salt/master
client_acl:
goser:
- test.ping
- network.*
tom:
- test.ping
- service.*
#修改一些文件的权限,让除了root用户外其他用户也能执行
chmod 755 /var/cache/salt /var/cache/salt/master /var/cache/salt/master/jobs /var/run/salt /var/run/salt/master
#这时候切换到zyx用户,验证设置是否生效
[goser@linux-node1 ~]$ salt 'linux-node2.goser.com' test.ping
linux-node2.goser.com:
True
[goser@linux-node1 ~]$ salt 'linux-node2.goser.com' cmd.run 'w'
Failed to authenticate! This is most likely because this user is not permitted to execute commands, but there is a small possibility that a disk error occurred (check disk/inode usage).
#当然也可以使用黑名单的形式来管理salt用户
vim /etc/salt/master
client_acl_blacklist:
users:
- root
- '^(?!sudo_).*$' # all non sudo users
modules:
- cmd
除了使用saltstack提供的模块,也可以自定义模块,因为saltstack的模块都是python写的,我们也可以写个python脚本作为saltstack模块
#修改master配置文件,配置saltstack状态文件目录结构
[root@linux-node1 ~]# vim /etc/salt/master
file_roots:
base:
- /srv/salt/base
prod:
- /srv/salt/prod
#在/srv/salt/base目录中创建_modules文件夹,在_modules文件夹中创建python脚本
[root@linux-node1 base]# mkdir _modules
[root@linux-node1 _modules]# vim my_disk.py
#!/bin/env python
def disk_list():
arg = 'df -h'
res = __salt__['cmd.run'](arg)
return res
#将自定义的模块同步到minion端
[root@linux-node1 _modules]# salt '*' saltutil.sync_modules
#测试远程执行
[root@linux-node1 _modules]# salt 'linux-node2.goser.com' my_disk.disk_list
linux-node2.goser.com:
Filesystem Size Used Avail Use% Mounted on
/dev/sda3 37G 2.0G 34G 6% /
tmpfs 491M 12K 491M 1% /dev/shm
/dev/sda1 283M 59M 209M 22% /boot
#那么这个自定义的模块在minion端就放在缓存目录中
[root@linux-node2 modules]# ls /var/cache/salt/minion/extmods/modules/
my_disk.py my_disk.pyc
3)远程执行之返回
默认情况下,发送给salt-minion的命令执行结果返回给salt master。其实saltstack returner的接口允许将结果发送给任意系统,比如:mysql,redis,syslog。
minion执行结果返回到syslog如下:
[root@linux-node1 ~]# salt 'linux-node2.goser.com' cmd.run 'df -h' --return syslog
linux-node2.goser.com:
Filesystem Size Used Avail Use% Mounted on
/dev/sda3 37G 2.0G 34G 6% /
tmpfs 491M 12K 491M 1% /dev/shm
/dev/sda1 283M 59M 209M 22% /boot
#在linux-node2.goser.com上查看message日志记录如下:
[root@linux-node2 ~]# tail -f /var/log/messages
Jun 16 16:32:22 linux-node2 python2.6: {"fun_args": ["df -h"], "jid": "20180616163222148822", "return": "Filesystem Size Used Avail Use% Mounted on\n/dev/sda3 37G 2.0G 34G 6% /\ntmpfs 491M 12K 491M 1% /dev/shm\n/dev/sda1 283M 59M 209M 22% /boot", "retcode": 0, "success": true, "fun": "cmd.run", "id": "linux-node2.goser.com"}
让minion执行结果返回到mysql,这种方式在生产环境中如果大并发向mysql写入数据可能会导致mysql宕机,如果环境中管理minion不多的话可以使用,不过生产环境中大多数还是使用master缓存数据向mysql写入数据。向mysql写入数据完成后,程序员就可以进行二次开发,从mysql库里找出哪些minion执行成功,哪些执行失败
#使用minion执行完返回到mysql的方式为:
#1.准备一台mysql服务器,这里使用宿主机为mysql服务器,然后建库建表
#打开宿主机的mysql client,输入密码:123,开始建库建表
#创建salt库
CREATE DATABASE `salt`
DEFAULT CHARACTER SET utf8
DEFAULT COLLATE utf8_general_ci;
#创建jid表
USE `salt`;
DROP TABLE IF EXISTS `jids`;
CREATE TABLE `jids` (
`jid` varchar(255) NOT NULL,
`load` mediumtext NOT NULL,
UNIQUE KEY `jid` (`jid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
#创建return表 存放返回的数据
DROP TABLE IF EXISTS `salt_returns`;
CREATE TABLE `salt_returns` (
`fun` varchar(50) NOT NULL,
`jid` varchar(255) NOT NULL,
`return` mediumtext NOT NULL,
`id` varchar(255) NOT NULL,
`success` varchar(10) NOT NULL,
`full_ret` mediumtext NOT NULL,
`alter_time` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
KEY `id` (`id`),
KEY `jid` (`jid`),
KEY `fun` (`fun`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
#创建事件表
DROP TABLE IF EXISTS `salt_events`;
CREATE TABLE `salt_events` (
`id` BIGINT NOT NULL AUTO_INCREMENT,
`tag` varchar(255) NOT NULL,
`data` mediumtext NOT NULL,
`alter_time` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
`master_id` varchar(255) NOT NULL,
PRIMARY KEY (`id`),
KEY `tag` (`tag`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
#授权访问
grant all on salt.* to salt@'%' identified by 'salt123';
#2、minion端安装MySQL-python模块
[root@linux-node2 ~]# yum install MySQL-python -y
#3、minion端修改配置文件
# 修改/etc/salt/minion 在配置文件后面追加以下内容
mysql.host: '·192.168.1.4' #这是宿主机的mysql服务地址
mysql.user: 'salt'
mysql.pass: 'salt123'
mysql.db: 'salt'
mysql.port: 3306
#4、在master端远程执行测试是否写入到mysql中
[root@linux-node1 ~]# salt 'linux-node2.goser.com' test.ping --return mysql
linux-node2.goser.com:
True
mysql> select * from salt_returns\G
*************************** 1. row ***************************
fun: test.ping
jid: 20180616170525266819
return: true
id: linux-node2.goser.com
success: 1
full_ret: {"fun_args": [], "jid": "20180616170525266819", "return": true, "ret
code": 0, "success": true, "fun": "test.ping", "id": "linux-node2.goser.com"}
alter_time: 2018-06-16 18:21:41
#每次在master端远程执行写入到mysql都要写上return mysql感觉很烦,也可以不使用这个参数也可以让minion端写入mysql
#修改master端的配置文件如下,将return:mysql注释去掉即可
[root@linux-node1 ~]# vim /etc/salt/master
return: mysql
[root@linux-node1 ~]# /etc/init.d/salt-master restart
#再执行一次不带return mysql参数是否可以写入mysql
[root@linux-node1 ~]# salt 'linux-node2.goser.com' cmd.run 'df -h'
*************************** 3. row ***************************
fun: cmd.run
jid: 20180616171514850313
return: "Filesystem Size Used Avail Use% Mounted on\n/dev/sda3
37G 2.0G 34G 6% /\ntmpfs 491M 12K 491M 1% /dev/shm\n/dev/sda
1 283M 59M 209M 22% /boot"
id: linux-node2.goser.com
success: 1
full_ret: {"fun_args": ["df -h"], "jid": "20180616171514850313", "return": "F
ilesystem Size Used Avail Use% Mounted on\n/dev/sda3 37G 2.0G 34
G 6% /\ntmpfs 491M 12K 491M 1% /dev/shm\n/dev/sda1 283M
59M 209M 22% /boot", "retcode": 0, "success": true, "fun": "cmd.run", "id": "
linux-node2.goser.com"}
alter_time: 2018-06-16 18:31:21
====================================================
#使用master端在minion执行完状态返回,然后由master端写入mysql的方式:
#首先将上面minion端配置文件的修改恢复到写入mysql功能前,master端配置文件一样要恢复,恢复完重启master和minion
#在master端安装MySQL-python
[root@linux-node1 ~]# yum install MySQL-python -y
#修改master配置文件,在最后添加如下参数,重启master
[root@linux-node1 ~]# vim /etc/salt/master
[root@linux-node1 ~]# /etc/init.d/salt-master restart
#测试通过master端是否可以将返回状态写入mysql
[root@linux-node1 ~]# salt 'linux-node2.goser.com' cmd.run 'echo goser'
linux-node2.goser.com:
goser
*************************** 4. row ***************************
fun: cmd.run
jid: 20180616173520091797
return: "goser"
id: linux-node2.goser.com
success: 1
full_ret: {"fun_args": ["echo goser"], "jid": "20180616173520091797", "return"
: "goser", "retcode": 0, "success": true, "cmd": "_return", "_stamp": "2018-06-1
6T09:35:29.695454", "fun": "cmd.run", "id": "linux-node2.goser.com"}
alter_time: 2018-06-16 18:51:36
配置管理之grains
grains是minion服务启动后,采集的客户端的一些基本信息,硬件信息,软件信息,网络信息,软件版本等。也可以在minion上自定义一些grains信息。它是静态的信息,minion服务启动后采集,如果一些信息变更,需要重启minion服务。grains适合做一些静态的属性值的采集。
比如查看minion端的资产信息
[root@linux-node1 _modules]# salt 'linux-node2.goser.com' grains.items linux-node2.goser.com: ---------- SSDs: biosreleasedate: 07/02/2015 biosversion: 6.00 cpu_flags: - fpu - vme - de - pse - tsc - msr - pae - mce - cx8 - apic - sep - mtrr - pge - mca - cmov - pat - pse36 - clflush - dts - mmx - fxsr - sse - sse2 - ss - syscall - nx - pdpe1gb - rdtscp - lm - constant_tsc - up - arch_perfmon - pebs - bts - xtopology - tsc_reliable - nonstop_tsc - aperfmperf - unfair_spinlock - pni - pclmulqdq - ssse3 - fma - cx16 - pcid - sse4_1 - sse4_2 - x2apic - movbe - popcnt - tsc_deadline_timer - aes - xsave - avx - f16c - rdrand - hypervisor - lahf_lm - abm - ida - arat - xsaveopt - pln - pts - dts - fsgsbase - bmi1 - avx2 - smep - bmi2 - invpcid cpu_model: Intel(R) Core(TM) i5-4460 CPU @ 3.20GHz cpuarch: x86_64 domain: goser.com fqdn: linux-node2.goser.com fqdn_ip4: - 192.168.1.12 fqdn_ip6: gpus: |_ ---------- model: SVGA II Adapter vendor: unknown host: linux-node2 hwaddr_interfaces: ---------- eth0: 00:0c:29:92:f2:36 eth2: 00:0c:29:92:f2:40 lo: 00:00:00:00:00:00 id: linux-node2.goser.com init: upstart ip4_interfaces: ---------- eth0: - 192.168.1.12 - 192.168.1.20 eth2: lo: - 127.0.0.1 ip6_interfaces: ---------- eth0: - fe80::20c:29ff:fe92:f236 eth2: lo: - ::1 ip_interfaces: ---------- eth0: - 192.168.1.12 - 192.168.1.20 - fe80::20c:29ff:fe92:f236 eth2: lo: - 127.0.0.1 - ::1 ipv4: - 127.0.0.1 - 192.168.1.12 - 192.168.1.20 ipv6: - ::1 - fe80::20c:29ff:fe92:f236 kernel: Linux kernelrelease: 2.6.32-504.el6.x86_64 locale_info: ---------- defaultencoding: UTF8 defaultlanguage: en_US detectedencoding: UTF-8 localhost: linux-node2.goser.com lsb_distrib_codename: Final lsb_distrib_id: CentOS lsb_distrib_release: 6.9 machine_id: 2b8fa8d3a129b2426377cf990000000a manufacturer: VMware, Inc. master: linux-node1 mdadm: mem_total: 980 nodename: linux-node2.goser.com num_cpus: 1 num_gpus: 1 os: CentOS os_family: RedHat osarch: x86_64 oscodename: Final osfinger: CentOS-6 osfullname: CentOS osmajorrelease: 6 osrelease: 6.9 osrelease_info: - 6 - 9 path: /sbin:/usr/sbin:/bin:/usr/bin productname: VMware Virtual Platform ps: ps -efH pythonexecutable: /usr/bin/python2.6 pythonpath: - /usr/bin - /usr/lib64/python26.zip - /usr/lib64/python2.6 - /usr/lib64/python2.6/plat-linux2 - /usr/lib64/python2.6/lib-tk - /usr/lib64/python2.6/lib-old - /usr/lib64/python2.6/lib-dynload - /usr/lib64/python2.6/site-packages - /usr/lib64/python2.6/site-packages/gtk-2.0 - /usr/lib/python2.6/site-packages - /usr/lib/python2.6/site-packages/setuptools-0.6c11-py2.6.egg-info pythonversion: - 2 - 6 - 6 - final - 0 saltpath: /usr/lib/python2.6/site-packages/salt saltversion: 2015.5.10 saltversioninfo: - 2015 - 5 - 10 - 0 selinux: ---------- enabled: False enforced: Disabled serialnumber: VMware-56 4d 4a c3 36 50 79 6d-43 36 02 d7 82 92 f2 36 server_id: 299132157 shell: /bin/bash virtual: VMware zmqversion: 3.2.5
再比如使用grains查看minion端的主机名和ip地址信息
[root@linux-node1 _modules]# salt 'linux-node2.goser.com' grains.item fqdn
linux-node2.goser.com:
----------
fqdn:
linux-node2.goser.com
[root@linux-node1 _modules]# salt 'linux-node2.goser.com' grains.item fqdn_ip4
linux-node2.goser.com:
----------
fqdn_ip4:
- 192.168.1.12
可以在minion端自定义grains信息,定义完要重启minion;也可以在master端自定义grains,然后将自定义的grains同步到minion端,生产环境要用自定义grains还是推荐使用在master端自定义,这样设置grains比较方便。
#在minion端通过修改minion配置文件来添加grains信息
[root@linux-node2 minion]# vim /etc/salt/minion
grains:
roles:
- webserver
[root@linux-node2 minion]# /etc/init.d/salt-minion restart
[root@linux-node1 ~]# salt 'linux-node2.goser.com' grains.item roles
linux-node2.goser.com:
----------
roles:
- webserver
#在minion端通过在/etc/salt目录下创建一个grains文件,默认minion端会从这个目录读grains
[root@linux-node2 minion]# vim /etc/salt/grains
name: goser
[root@linux-node2 minion]# /etc/init.d/salt-minion restart
[root@linux-node1 base]# salt 'linux-node2.goser.com' grains.item name
linux-node2.goser.com:
----------
name:
goser
==================================================
#通过在master端file_roots配置的根目录中创建一个_grains文件夹,在_grains文件夹中创建一个python脚本的方式
[root@linux-node1 _grains]# vim my_grains.py
#!/usr/bin/env python
#-*- coding: utf-8 -*-
def my_grains():
names = {}
names['zhangsan'] = 'openstack'
names['lisi'] = 'oldboyedu'
return names
#刷新Grains
[root@linux-node1 _grains]# salt '*' saltutil.sync_grains
#测试自定义的grains
[root@linux-node1 _grains]# salt 'linux-node2.goser.com' grains.item zhangsan
linux-node2.goser.com:
----------
zhangsan:
openstack
配置管理之pillar
grains的特性–每次启动汇报,静态决定了它没有pillar灵活,要知道pillar是随时可变的,只要在master端修改了那一般都会立刻生效的。所以grains更适合做一些静态的属性值的采集,例如设备的角色(role),磁盘个数(disk_num)等诸如此类非常固定的属性。如果你想定义的属性值是经常变化的,那请采用pillar,如果是很固定、不易变的那请用grains。
我们使用pillar,基本上都在使用自定义的pillar,因为saltstack提供的pillar基本上没用。要使用pillar,就需要修改master配置文件,设置pillar的目录结构
[root@linux-node1 salt]# vim /etc/salt/master
pillar_roots:
base:
- /srv/pillar/base
prod:
- /srv/pillar/prod
#重启master
[root@linux-node1 base]# /etc/init.d/salt-master restart
由于pillar关注安全性,所以要使自定义的pillar生效,还必须有top.sls的文件,配置top.sls文件指定哪些minion可以使用自定义的pillar
#创建一个pillar状态文件
[root@linux-node1 base]# mkdir zabbix
[root@linux-node1 zabbix]# vim agent.sls
zabbix-agent:
Zabbix_Server: 192.168.1.11
#在master配置文件里设置的pillar根目录下创建top.sls文件,配置top.sls
[root@linux-node1 base]# vim top.sls
base:
'*':
- zabbix.agent
当然在pillar状态文件里可以使用jinja模板来写些复杂的jinja语言判断,因为默认sls状态文件支持jinja语言的,所以可以根据业务使用jinja模板来设计复杂的pillar状态文件
在自定义完pillar文件后,并且通过top.sls文件制定后,一般是不需要刷新pillar的,因为执行highstate高级状态时master会将pillar数据传输到minion端,minion端通过读取pillar数据返回执行状态给master。这里为了测试自定义pillar是否生效,需要刷新下pillar
[root@linux-node1 base]# salt 'linux-node2.goser.com' saltutil.refresh_pillar
[root@linux-node1 base]# salt 'linux-node2.goser.com' pillar.item zabbix-agent
linux-node2.goser.com:
----------
zabbix-agent:
----------
Zabbix_Server:
192.168.1.11
这样就可以通过pillar来匹配minion
[root@linux-node1 base]# salt -I 'zabbix-agent:Zabbix_Server:192.168.1.11' cmd.run 'echo zabbix'
linux-node2.goser.com:
zabbix
配置管理之状态管理
Salt使用State模块文件进行配置管理,使用YAML编写,以.sls结尾。如果进行配置管理首先需要再Master的配置文件中指定”file roots”的选项,Salt支持环境的配置,比如开发环节、测试环境、生产环境,但是base环境是必须的。而且Base环境必须包含入口文件top.sls。
第一步:设置file_roots和pillar_roots
[root@linux-node1 base]# vim /etc/salt/master
file_roots:
base:
- /srv/salt/base
prod:
- /srv/salt/prod
pillar_roots:
base:
- /srv/pillar/base
prod:
- /srv/pillar/prod
[root@linux-node1 base]# /etc/init.d/salt-master restart
第二步:设置top.sls
[root@linux-node1 base]# vim top.sls
base:
'*':
- init.env_init
第三步:编写状态文件
[root@linux-node1 init]# vim env_init.sls include: - init.dns - init.history - init.audit - init.sysctl - init.zabbix_agent
第四步:执行状态
[root@linux-node1 ~]# salt 'linux-node2.goser.com' state.highstate
项目部署
项目架构如下:

使用saltstack对业务项目的部署和管理,应该对项目划分成:系统初始化、功能模块、业务引用等,
1.系统初始化:就是每个服务设备初始都需要部署的工具,比如统一dns服务,zabbix-agent部署,系统内核调优等
2.功能模块:尽可能的将项目中用到的功能拆分成一个部分,比如lnmp项目,可以将此项目分成几个功能模块:nginx功能、php功能、mysql功能
3.业务引用:对于这个业务需要有什么功能,那么就可以将功能模块定义的功能引用过来
首先规范好file_roots和pillar_roots
[root@linux-node1 init]# vim /etc/salt/master
file_roots:
base:
- /srv/salt/base
prod:
- /srv/salt/prod
pillar_roots:
base:
- /srv/pillar/base
prod:
- /srv/pillar/prod
系统初始化--------一个设备初始要做的操作
[root@linux-node1 base]# mkdir init
#设置dns
[root@linux-node1 init]# vim dns.sls
/etc/resolv.conf:
file.managed:
- source: salt://init/files/resolv.conf
- user: root
- group: root
- mode: 644
#修改history历史记录格式
[root@linux-node1 init]# cat history.sls
/etc/profile:
file.append:
- text:
- export HISTTIMEFORMAT="%F %T `whoami` "
#将用户输入的命令输入到message日志中
[root@linux-node1 init]# cat audit.sls
/etc/bashrc:
file.append:
- text:
- export PROMPT_COMMAND='{ msg=$(history 1 | { read x y; echo $y; });logger "[euid=$(whoami)]":$(who am i):[`pwd`]"$msg"; }'
#设置内核参数调优
[root@linux-node1 init]# cat sysctl.sls
net.ipv4.ip_local_port_range:
sysctl.present:
- value: 10000 65000
fs.file-max:
sysctl.present:
- value: 1000000
net.ipv4.ip_forward:
sysctl.present:
- value: 1
vm.swappiness:
sysctl.present:
- value: 0
#安装zabbix-agent客户端
[root@linux-node1 init]# cat zabbix_agent.sls
zabbix-agent:
pkg.installed:
- name: zabbix22-agent
file.managed:
- name: /etc/zabbix_agentd.conf
- source: salt://init/files/zabbix_agentd.conf
- user: root
- group: root
- mode: 644
- backup: minion
- template: jinja
- defaults:
Server: {{ pillar['zabbix-agent']['Zabbix_Server'] }}
- require:
- pkg: zabbix-agent
service.running:
- enable: True
- watch:
- pkg: zabbix-agent
- file: zabbix-agent
zabbix_agentd.conf.d:
file.directory:
- name: /etc/zabbix_agent.conf.d
- watch_in:
- service: zabbix-agent
- require:
- pkg: zabbix-agent
- file: zabbix-agent
对于上面zabbix-agent客户端的安装,需要找一台设备安装好了zabbix-agent,根据zabbix-agent安装方式来写状态文件
创建一个env_init.sls文件,这个文件将其他系统初始化sls文件include进来,这样在top.sls文件直接引用env_init.sls文件即可
[root@linux-node1 init]# cat env_init.sls
include:
- init.dns
- init.history
- init.audit
- init.sysctl
- init.zabbix_agent
[root@linux-node1 base]# cat top.sls
base:
'*':
- init.env_init
功能模块配置
将一个项目中需要用到的工具全部分成功能模块中,以备后期业务引用
#将功能模块全放在modules文件夹中
[root@linux-node1 prod]# mkdir modules
[root@linux-node1 prod]# cd modules/
#创建各个功能模块的文件夹
[root@linux-node1 modules]# mkdir {haproxy,keepalived,memcached,nginx.php,pkg}
#创建功能模块编译安装需要的依赖包
[root@linux-node1 modules]# cd pkg
[root@linux-node1 pkg]# cat make.sls
make-pkg:
pkg.installed:
- names:
- gcc
- gcc-c++
- glibc
- make
- autoconf
- openssl
- pcre
- openssl-devel
- pcre-devel
部署功能模块haproxy:首先应先找一台设备安装haproxy,根据安装方式和安装后产生的配置文件来写haproxy的sls文件
[root@linux-node1 modules]# cd haproxy/
[root@linux-node1 haproxy]# mkdir files
[root@linux-node1 haproxy]# ls files/
haproxy-1.6.3.tar.gz haproxy.init
#修改haproxy的启动文件,修改其启动路径
[root@linux-node1 haproxy]# vim files/haproxy.init
BIN=/usr/local/haproxy/sbin/$BASENAME
#创建haproxy的安装部署sls文件
[root@linux-node1 haproxy]# vim install.sls
include:
- modules.pkg.make
haproxy-install:
file.managed:
- name: /usr/local/src/haproxy-1.6.3.tar.gz
- source: salt://modules/haproxy/files/haproxy-1.6.3.tar.gz
- user: root
- group: root
- mode: 755
cmd.run:
- name: cd /usr/local/src && tar xf haproxy-1.6.3.tar.gz && cd haproxy-1.6.3 && make TARGET=linux26 PREFIX=/usr/local/haproxy-1.6.3 && make install PREFIX=/usr/local/haproxy-1.6.3 && ln -s /usr/local/haproxy-1.6.3 /usr/local/haproxy
- require:
- file: haproxy-install
- pkg: make-pkg
- unless: test -L /usr/local/haproxy
/etc/init.d/haproxy:
file.managed:
- source: salt://modules/haproxy/files/haproxy.init
- user: root
- group: root
- mode: 755
net.ipv4.ip_nonlocal_bind:
sysctl.present:
- value: 1
/etc/haproxy:
file.directory:
- user: root
- group: root
- mode: 755
haproxy-init:
cmd.run:
- name: chkconfig --add haproxy
- unless: chkconfig --list | grep haproxy
- require:
- file: /etc/init.d/haproxy
部署keepalived功能模块:首先应先找一台设备安装keepalived,根据安装方式和安装后产生的配置文件来写keepalived的sls文件
[root@linux-node1 modules]# cd keepalived/
[root@linux-node1 keepalived]# cd files/
[root@linux-node1 keepalived]# ls files/
keepalived-1.2.17.tar.gz keepalived.init keepalived.sysconfig
#创建keepalived的安装和部署sls文件
[root@linux-node1 keepalived]# cat install.sls
keepalived-install:
file.managed:
- name: /usr/local/src/keepalived-1.2.17.tar.gz
- source: salt://modules/keepalived/files/keepalived-1.2.17.tar.gz
- mode: 755
- user: root
- group: root
cmd.run:
- name: cd /usr/local/src && tar zxf keepalived-1.2.17.tar.gz && cd keepalived-1.2.17 && ./configure --prefix=/usr/local/keepalived --disable-fwmark && make && make install
- unless: test -d /usr/local/keepalived
- require:
- file: keepalived-install
/etc/sysconfig/keepalived:
file.managed:
- source: salt://modules/keepalived/files/keepalived.sysconfig
- mode: 644
- user: root
- group: root
/etc/init.d/keepalived:
file.managed:
- source: salt://modules/keepalived/files/keepalived.init
- mode: 755
- user: root
- group: root
keepalived-init:
cmd.run:
- name: chkconfig --add keepalived
- unless: chkconfig --list | grep keepalived
- require:
- file: /etc/init.d/keepalived
/etc/keepalived:
file.directory:
- user: root
- group: root
对于 memcached nginx php 的安装部署,参考haproxy和keepalived创建的sls文件的方式部署,这里省略
业务应用:
将上面创建的haproxy keepalived memcached nginx php的sls文件引用到业务中
#创建一个业务,可以先创建一个业务文件夹,将业务的sls文件写到这个文件夹中
[root@linux-node1 prod]# mkdir cluster
[root@linux-node1 prod]# cd cluster/
[root@linux-node1 cluster]# mkdir files
#files文件夹下放的是业务相关的配置文件
[root@linux-node1 cluster]# ls files/
haproxy-outside.cfg haproxy-outside-keepalived.conf
#创建业务引用的haproxy的sls文件,对于配置文件最好加上backup: True
#这个backup: True设定表示在执行完这个状态文件后,如果配置文件修改了,会对老的配置文件做备份
[root@linux-node1 cluster]# cat haproxy-outside.sls
include:
- modules.haproxy.install
haproxy-service:
file.managed:
- name: /etc/haproxy/haproxy.cfg
- source: salt://cluster/files/haproxy-outside.cfg
- user: root
- group: root
- mode: 644
- backup: True
service.running:
- name: haproxy
- enable: True
- reload: True
- require:
- cmd: haproxy-init
- watch:
- file: haproxy-service
#创建业务引用的keepalived的sls文件
[root@linux-node1 cluster]# cat haproxy-outside-keepalived.sls
include:
- modules.keepalived.install
keepalived-server:
file.managed:
- name: /etc/keepalived/keepalived.conf
- source: salt://cluster/files/haproxy-outside-keepalived.conf
- mode: 644
- user: root
- group: root
- backup: True
- template: jinja
{% if grains['fqdn'] == 'linux-node2.goser.com' %}
- ROUTEID: haproxy_ha
- STATEID: MASTER
- PRIORITYID: 150
{% elif grains['fqdn'] == 'linux-node3.goser.com' %}
- ROUTEID: haproxy_ha
- STATEID: BACKUP
- PRIORITYID: 100
{% endif %}
service.running:
- name: keepalived
- enable: True
- watch:
- file: keepalived-server
上面的状态文件中使用了jinja模板。其实jinja模板不仅可以在声明了template: jinja的模板文件中可以引用jinja模板,还可以在sls文件中使用jinja模板
上面的业务配置文件为:
[root@linux-node1 files]# cat haproxy-outside.cfg global maxconn 100000 chroot /usr/local/haproxy uid 99 gid 99 daemon nbproc 1 pidfile /usr/local/haproxy/logs/haproxy.pid log 127.0.0.1 local3 info defaults option http-keep-alive maxconn 100000 mode http timeout connect 5000ms timeout client 50000ms timeout server 50000ms listen stats mode http bind 0.0.0.0:8888 stats enable stats uri /haproxy-status stats auth haproxy:saltstack frontend frontend_www_example_com bind 192.168.1.20:80 mode http option httplog log global default_backend backend_www_example_com backend backend_www_example_com option forwardfor header X-REAL-IP option httpchk HEAD / HTTP/1.0 balance source server web-node1 192.168.1.12:8080 check inter 2000 rise 30 fall 15 server web-node2 192.168.1.13:8080 check inter 2000 rise 30 fall 15
[root@linux-node1 files]# cat haproxy-outside-keepalived.conf ! Configuration File for keepalived global_defs { notification_email { saltstack@example.com } notification_email_from keepalived@example.com smtp_server 127.0.0.1 smtp_connect_timeout 30 router_id {{ROUTEID}} } vrrp_instance haproxy_ha { state {{STATEID}} interface eth0 virtual_router_id 36 priority {{PRIORITYID}} advert_int 1 authentication { auth_type PASS auth_pass 1111 } virtual_ipaddress { 192.168.1.20 } }
修改top.sls文件
[root@linux-node1 base]# cat top.sls
base:
'*':
- init.env_init
prod:
'*':
- cluster.haproxy-outside
- cluster.haproxy-outside-keepalived
最后执行saltstack高级状态即可部署haproxy高可用架构,为了保险起见最好在运行状态时使用test=True先检查有没有问题,没问题在正式部署
[root@linux-node1 ~]# salt 'linux-node[2-3].*' state.highstate
到此只是部署完haproxy的高可用架构,至于nginx PHP memcached 的完整部署可以参考:https://github.com/unixhot/saltbook-code
对于使用saltstack来部署运维架构的平台可以参考:https://github.com/yueyongyue/saltshaker_api 和 https://github.com/binbin91/oms/
对于nginx的sls文件的创建,可以设置nginx多目录,比如上线目录和下线目录,这样在需要下载的app设备移动到offline目录,如果需要将下线的app,就可以让其移动到online目录
#nginx状态文件的部分代码如下: nginx-service: service.running: - name: nginx - enable: True - reload: True - require: - cmd: nginx-init - watch: - file: /usr/local/nginx/conf/nginx.conf - file: nginx-online nginx-online: file.directory: - name: /usr/local/nginx/conf/vhost_online nginx-offline: file.directory: - name: /usr/local/nginx/conf/vhost_offline
saltstack-syndic
多机房部署salt的话,可以使用saltstack-syndic作为每个机房的master,然后每个机房的saltstack-syndic master和一个主master建立交互。

部署saltstack-syndic设备上首先要部署salt-master,然后修改安装syndic设备上的master配置文件
[root@linux-node3 ~]# yum install salt-master -y [root@linux-node3 ~]# yum install -y salt-syndic [root@linux-node3 ~]# vim /etc/salt/master syndic_master: linux-node1 #修改master上的master配置文件,配置其同意使用sysdic [root@linux-node1 ~]# vim /etc/salt/master order_masters: True
最后重启master配置文件即可。
注意:sysdic的file_roots和pillar_roots必须与高级的Master一致,可以使用git或svn来管理来保证一致。
salt-ssh
当生产环境中有的app不让装minion的话,可以使用salt-ssh来管理app,但是salt-ssh相对于master-minion的方式功能要弱了许多
要使用salt-ssh的话,首先要在master端安装salt-ssh
[root@linux-node1 ~]# yum install salt-ssh -y #配置salt-ssh配置文件,设置没有安装minion的设备可以被master管理,比如linux-node2没有装minion [root@linux-node1 ~]# vim /etc/salt/roster linux-node2.goser.com: host: 192.168.1.12 user: root port: 22
首次使用salt-ssh来管理无minion的app设备,要求输入密码认证,认证完成后秘钥就会拷贝过来,这样下次再使用salt-ssh就不需要密码了
[root@linux-node1 ~]# salt-ssh 'linux-node2.goser.com' test.ping -i #下次再使用salt-ssh管理app后就不需要-i 参数了 [root@linux-node1 ~]# salt-ssh 'linux-node2.goser.com' test.ping
使用salt-ssh对目标做远程执行,对目标的选择只支持匹配和正则,不支持像salt命令的复杂的选择方式。
#使用-r参数,这个参数跟cmd.run是一样的
[root@linux-node1 ~]# salt-ssh 'linux-node2.goser.com' -r 'uptime'
linux-node2.goser.com:
----------
retcode:
0
stderr:
stdout:
23:25:13 up 1 day, 5:24, 1 user, load average: 0.00, 0.00, 0.00
当然也可以使用salt-ssh来执行高级状态
[root@linux-node1 ~]# salt-ssh 'linux-node2.goser.com' state.highstate
saltstack的job和runner管理
如果对一个正在执行的salt状态杀掉,这时候应该先查看时哪个jid正在运行,然后对这个jid做kill掉
#查看正在运行的jid [root@linux-node1 ~]# salt '*' saltutil.running #对某个正在运行的jid做kill掉 [root@linux-node1 ~]# salt '*' saltutil.kill_job jid号
查看minion端的上下线状态
[root@linux-node1 ~]# salt-run manage.status
down:
up:
- linux-node1.goser.com
- linux-node2.goser.com
- linux-node3.goser.com
#查看下线minion
[root@linux-node1 ~]# salt-run manage.down
#查看上线的minion
[root@linux-node1 ~]# salt-run manage.up
- linux-node1.goser.com
- linux-node2.goser.com
- linux-node3.goser.com
查看salt都运行了哪些job
[root@linux-node1 ~]# salt-run jobs.list_jobs
如果查看某个运行了的job返回的结果,可以使用如下命令
[root@linux-node1 ~]# salt-run jobs.lookup_jid 20180616233934394731
linux-node1.goser.com_master:
----------
_stamp:
2018-06-16T15:39:34.704287
fun:
runner.manage.up
jid:
20180616233934394731
return:
- linux-node1.goser.com
- linux-node2.goser.com
- linux-node3.goser.com
success:
True
user:
root
salt-api
salt-api配置的要求
- 需要https的协议支持,创建https证书
- 创建salt-api的配置文件
- 使用PAM来验证
创建https证书
[root@linux-node1 ~]# cd /etc/pki/tls/certs/ [root@linux-node1 certs]# make testcert Enter pass phrase:123123 Verifying - Enter pass phrase:123123 Enter pass phrase for /etc/pki/tls/private/localhost.key:123123 Country Name (2 letter code) [XX]: State or Province Name (full name) []: Locality Name (eg, city) [Default City]: Organization Name (eg, company) [Default Company Ltd]: Organizational Unit Name (eg, section) []: Common Name (eg, your name or your server's hostname) []: Email Address []: #这样就创建了一个crt证书localhost.crt [root@linux-node1 ~]# ls /etc/pki/tls/certs/ ca-bundle.crt localhost.crt Makefile ca-bundle.trust.crt make-dummy-cert renew-dummy-cert #再创建一个证书的key:salt_nopass.key [root@linux-node1 tls]# cd /etc/pki/tls/private/ [root@linux-node1 private]# openssl rsa -in localhost.key -out salt_nopass.key [root@linux-node1 private]# ll total 8 -rw------- 1 root root 1766 Jun 17 00:16 localhost.key -rw-r--r-- 1 root root 1679 Jun 17 00:17 salt_nopass.key
安装CherryPy==3.2.6,使用pip来安装
#如果没装pip,先装上 [root@linux-node1 ~]# yum install python-pip -y #安装CherryPy [root@linux-node1 ~]# pip install CherryPy==3.2.6
安装salt-api
[root@linux-node1 ~]# yum install salt-api -y
创建salt-api管理salt的用户
[root@linux-node1 ~]# useradd -M -s /sbin/nologin saltapi #设置saltapi用户的密码为saltapi [root@linux-node1 ~]# echo 'saltapi'|passwd --stdin saltapi
创建salt-api的配置文件,需要修改master的配置文件
[root@linux-node1 ~]# vim /etc/salt/master
#这行去掉注释
default_include: master.d/*.conf
#创建salt-api配置文件
[root@linux-node1 ~]# cd /etc/salt/
[root@linux-node1 salt]# mkdir master.d
#创建salt-api认证配置文件
[root@linux-node1 master.d]# vim api.conf
rest_cherrypy:
host: 192.168.1.11
port: 8000
ssl_crt: /etc/pki/tls/certs/localhost.crt
ssl_key: /etc/pki/tls/private/salt_nopass.key
#创建PAM验证认证文件
[root@linux-node1 master.d]# vim eauth.conf
external_auth:
pam:
saltapi:
- .*
- '@wheel'
- '@runner'
启动salt-api并重启master
[root@linux-node1 ~]# /etc/init.d/salt-api start [root@linux-node1 ~]# /etc/init.d/salt-master restart
使用salt-api来管理saltstack,首先获取token
#通过用户名和密码登录salt-api获取token curl -k https://192.168.1.11:8000/login \ -H 'Accept: application/x-yaml' \ -d username='saltapi' \ -d password='saltapi' \ -d eauth='pam' #执行后返回结果,通过结果获取token return: - eauth: pam expire: 1529210720.346725 perms: - .* - '@wheel' - '@runner' start: 1529167520.346724 token: 0b160b9b138c4744cbdb995f1263aa4628fc2d3a user: saltapi
通过获取到的token值来获取minion端的grains数据,
[root@linux-node1 ~]# curl -k https://192.168.1.11:8000/minions/linux-node2.goser.com -H 'Accept: application/x-yaml' -H 'X-Auth-Token: 0b160b9b138c4744cbdb995f1263aa4628fc2d3a' return: - linux-node2.goser.com: SSDs: [] biosreleasedate: 07/02/2015 biosversion: '6.00' cpu_flags: - fpu - vme - de - pse - tsc - msr - pae - mce - cx8 - apic - sep - mtrr - pge - mca - cmov - pat - pse36 - clflush - dts - mmx - fxsr - sse - sse2 - ss - syscall - nx - pdpe1gb - rdtscp - lm - constant_tsc - up - arch_perfmon - pebs - bts - xtopology - tsc_reliable - nonstop_tsc - aperfmperf - unfair_spinlock - pni - pclmulqdq - ssse3 - fma - cx16 - pcid - sse4_1 - sse4_2 - x2apic - movbe - popcnt - tsc_deadline_timer - aes - xsave - avx - f16c - rdrand - hypervisor - lahf_lm - abm - ida - arat - xsaveopt - pln - pts - dts - fsgsbase - bmi1 - avx2 - smep - bmi2 - invpcid cpu_model: Intel(R) Core(TM) i5-4460 CPU @ 3.20GHz cpuarch: x86_64 domain: goser.com fqdn: linux-node2.goser.com fqdn_ip4: - 192.168.1.12 fqdn_ip6: [] gpus: - model: SVGA II Adapter vendor: unknown host: linux-node2 hwaddr_interfaces: eth0: 00:0c:29:92:f2:36 eth2: 00:0c:29:92:f2:40 lo: 00:00:00:00:00:00 id: linux-node2.goser.com init: upstart ip4_interfaces: eth0: - 192.168.1.12 - 192.168.1.20 eth2: [] lo: - 127.0.0.1 ip6_interfaces: eth0: - fe80::20c:29ff:fe92:f236 eth2: [] lo: - ::1 ip_interfaces: eth0: - 192.168.1.12 - 192.168.1.20 - fe80::20c:29ff:fe92:f236 eth2: [] lo: - 127.0.0.1 - ::1 ipv4: - 127.0.0.1 - 192.168.1.12 - 192.168.1.20 ipv6: - ::1 - fe80::20c:29ff:fe92:f236 kernel: Linux kernelrelease: 2.6.32-504.el6.x86_64 lisi: oldboyedu locale_info: defaultencoding: UTF8 defaultlanguage: en_US detectedencoding: UTF-8 localhost: linux-node2.goser.com lsb_distrib_codename: Final lsb_distrib_id: CentOS lsb_distrib_release: '6.9' machine_id: 2b8fa8d3a129b2426377cf990000000a manufacturer: VMware, Inc. master: linux-node1 mdadm: [] mem_total: 980 name: goser nodename: linux-node2.goser.com num_cpus: 1 num_gpus: 1 os: CentOS os_family: RedHat osarch: x86_64 oscodename: Final osfinger: CentOS-6 osfullname: CentOS osmajorrelease: '6' osrelease: '6.9' osrelease_info: - 6 - 9 path: /sbin:/usr/sbin:/bin:/usr/bin productname: VMware Virtual Platform ps: ps -efH pythonexecutable: /usr/bin/python2.6 pythonpath: - /usr/bin - /usr/lib64/python26.zip - /usr/lib64/python2.6 - /usr/lib64/python2.6/plat-linux2 - /usr/lib64/python2.6/lib-tk - /usr/lib64/python2.6/lib-old - /usr/lib64/python2.6/lib-dynload - /usr/lib64/python2.6/site-packages - /usr/lib64/python2.6/site-packages/gtk-2.0 - /usr/lib/python2.6/site-packages - /usr/lib/python2.6/site-packages/setuptools-0.6c11-py2.6.egg-info pythonversion: - 2 - 6 - 6 - final - 0 roles: - webserver saltpath: /usr/lib/python2.6/site-packages/salt saltversion: 2015.5.10 saltversioninfo: - 2015 - 5 - 10 - 0 selinux: enabled: false enforced: Disabled serialnumber: VMware-56 4d 4a c3 36 50 79 6d-43 36 02 d7 82 92 f2 36 server_id: 299132157 shell: /bin/bash virtual: VMware zhangsan: openstack zmqversion: 3.2.5
查看minion端的上下线状态
curl -k https://192.168.1.11:8000 \ -H 'Accept: application/x-yaml' \ -H 'X-Auth-Token: 0b160b9b138c4744cbdb995f1263aa4628fc2d3a' \ -d client='runner' \ -d fun='manage.status'
通过salt-api远程执行操作
#无参的远程执行 curl -k https://192.168.1.11:8000 \ -H 'Accept: application/x-yaml' \ -H 'X-Auth-Token: 0b160b9b138c4744cbdb995f1263aa4628fc2d3a' \ -d client='local' \ -d tgt='linux-node2.goser.com' \ -d fun='test.ping' #带参的远程执行 curl -k https://192.168.1.11:8000 \ -H 'Accept: application/x-yaml' \ -H 'X-Auth-Token: 0b160b9b138c4744cbdb995f1263aa4628fc2d3a' \ -d client='local' \ -d tgt='linux-node2.goser.com' \ -d fun='cmd.run' \ -d arg='df -h' #也可以执行高级状态 curl -k https://192.168.1.11:8000 \ -H 'Accept: application/x-yaml' \ -H 'X-Auth-Token: 0b160b9b138c4744cbdb995f1263aa4628fc2d3a' \ -d client='local' \ -d tgt='linux-node2.goser.com' \ -d fun='state.highstate'
查看jobs及对某个jid查询返回的结果
curl -k https://192.168.1.11:8000/jobs \ -H 'Accept: application/x-yaml' \ -H 'X-Auth-Token: 0b160b9b138c4744cbdb995f1263aa4628fc2d3a' #对某个jid查看曾经的返回结果 curl -k https://192.168.1.11:8000/jobs/20180617010118206336 \ -H 'Accept: application/x-yaml' \ -H 'X-Auth-Token: 0b160b9b138c4744cbdb995f1263aa4628fc2d3a'
salt+etcd自动化扩容: 参考文档https://www.cnblogs.com/reblue520/p/6732985.html
浙公网安备 33010602011771号