saltstack的安装和功能参数使用详解以及YAML语法使用解释
Posted 抛物线.
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了saltstack的安装和功能参数使用详解以及YAML语法使用解释相关的知识,希望对你有一定的参考价值。
由于我也是最近一个月才接触saltstack运维工具,所以学习过程中,避免不了遇到很多问题,现如今,互联网比较发达,各种帮助文档,技术博客,珍贵书籍,技术论坛等 “泛滥成灾”。
所以期间也多多少少搜集了一些saltstack相关资料,那么在这里重新整理后,加上自己实战的结果展示,和一些经验收获,分享给需要的人。
包括一些在操作过程中遇到的问题和报错,甚至是警告,也把我的解决办法,分享给大家。比如典型的问题,在master主控端,发送命令时,minion端反应总是很慢,对于这个,我的解决办法是把LIinux 下的ipv6给禁用掉。由于内容太多了,下一篇博客,将介绍saltstack的管理命令的使用,特别是我这个小项目中涉及到的saltstack的后端使用。
本篇博客内容比较多,主要参考官网官方手册和一些Python自动化运维书上的讲解,这里主要是参考(刘天斯的Python自动化运维),以及各大博客和论坛的关于saltstack自动化运维技术核心资料。
来源:
一、 salt简介:
SaltStack是一个服务器基础架构集中化管理平台,具备配置管理、远程执行、监控等功能,基于Python语言实现,结合轻量级消息队列(ZeroMQ)与Python第三方模块(Pyzmq、PyCrypto、Pyjinjia2、python-msgpack和PyYAML等)构建。
通过部署SaltStack,我们可以在成千万台服务器上做到批量执行命令,根据不同业务进行配置集中化管理、分发文件、采集服务器数据、操作系统基础及软件包管理等,SaltStack是运维人员提高工作效率、规范业务配置与操作的利器。
二、salt基本原理
SaltStack 采用 C/S模式,server端就是salt的master,client端就是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自带的所有东西。
这些模块是python写成的文件,里面会有好多函数,如cmd.run,
当我们执行salt '*' cmd.run 'uptime'的时候,master下发任务匹配到的minion上去,minion执行模块函数,并返回结果。
master监听4505和4506端口,4505对应的是ZMQ的PUB system,
用来发送消息,4506对应的是REP system是来接受消息的。
三、具体步骤如下:
- 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执行结果,将结果输出到终端。
四、安装salt
- 添加rpm源
7版本
rpm --import https://repo.saltstack.com/yum/redhat/7/x86_64/latest/SALTSTACK-GPG-KEY.pub
6版本
rpm --import https://repo.saltstack.com/yum/redhat/6/x86_64/latest/SALTSTACK-GPG-KEY.pub
#新增文件 /etc/yum.repos.d/saltstack.repo
7 & 6版本
[saltstack-repo]
name=SaltStack repo for RHEL/CentOS $releasever
baseurl=https://repo.saltstack.com/yum/redhat/$releasever/$basearch/latest
enabled=1
gpgcheck=1
gpgkey=https://repo.saltstack.com/yum/redhat/$releasever/$basearch/latest/SALTSTACK-GPG-KEY.pub
- 安装 salt-minion, salt-master,或Salt components:
yum install salt-master
yum install salt-minion
yum install salt-ssh
yum install salt-syndic
yum install salt-cloud
五、配置salt
- master:
一般使用默认就好 (/etc/salt/master)
#指定master,冒号后有一个空格
master: 192.168.10.12
user: root
#-------以下为可选--------------
# salt运行的用户,影响到salt的执行权限
user: root
#s alt的运行线程,开的线程越多一般处理的速度越快,但一般不要超过CPU的个数
worker_threads: 10
# master的管理端口
publish_port : 4505
# master跟minion的通讯端口,用于文件服务,认证,接受返回结果等
ret_port : 4506
# 如果这个master运行的salt-syndic连接到了一个更高层级的master,那么这个参数需要配置成连接到的这个高层级master的监听端口
syndic_master_port : 4506
# 指定pid文件位置
pidfile: /var/run/salt-master.pid
# saltstack 可以控制的文件系统的开始位置
root_dir: /
# 日志文件地址
log_file: /var/log/salt_master.log
# 分组设置
nodegroups:
group_all: '*'
# salt state执行时候的根目录
file_roots:
base:
- /srv/salt/
# 设置pillar 的根目录
pillar_roots:
base:
- /srv/pillar
- 启动master:
systemctl start salt-master
systemctl enable salt-master
minion: (/etc/salt/minion)
#指定master,冒号后有一个空格
master: 192.168.10.12
id: minion-01
user: root
#-------以下为可选--------------
# minion的识别ID,可以是IP,域名,或是可以通过DNS解析的字符串
id: 192.168.0.100
# salt运行的用户权限
user: root
# master的识别ID,可以是IP,域名,或是可以通过DNS解析的字符串
master : 192.168.0.100
# master通讯端口
master_port: 4506
# 备份模式,minion是本地备份,当进行文件管理时的文件备份模式
backup_mode: minion
# 执行salt-call时候的输出方式
output: nested
# minion等待master接受认证的时间
acceptance_wait_time: 10
# 失败重连次数,0表示无限次,非零会不断尝试到设置值后停止尝试
acceptance_wait_time_max: 0
# 重新认证延迟时间,可以避免因为master的key改变导致minion需要重新认证的syn风暴
random_reauth_delay: 60
# 日志文件位置
log_file: /var/logs/salt_minion.log
# 文件路径基本位置
file_roots:
base:
- /etc/salt/minion/file
# pillar基本位置
pillar_roots:
base:
- /data/salt/minion/pillar
启动minion:
systemctl start salt-master
systemctl enable salt-master
添加key: master 端查看key
[root@master salt]# salt-key
Accepted Keys:
Denied Keys:
Unaccepted Keys: #可看到 minion已经检测到,没有认证key
minion-01
Rejected Keys:
[root@master salt]# salt-key -a minion-01
The following keys are going to be accepted:
Unaccepted Keys:
minion-01
Proceed? [n/Y] y #Y确认添加
Key for minion minion-01 accepted. #添加成功
[root@master salt]# salt-key
Accepted Keys:
minion-01
Denied Keys:
Unaccepted Keys:
Rejected Keys:
[root@master salt]#
salt-key常用参数:
参数 | 功能 |
---|---|
-a | 添加指定ID 的key |
-A | 添加全部 |
-R | 拒绝全部 |
-d | 删除指定ID的 |
-D | 删除全部 |
测试连通性:
[root@master salt]# salt 'minion-01' test.ping
minion-01:
True #返回结果表示成功
[root@master salt]#
简单服务的安装:
[root/] ]$salt 'minion-01' pkg.install ftp #解释
minion-01:
----------
ftp:
----------
new:
0.17-67.el7
old:
[root/] ]$
#去minion查看
[root@minion-01 tmp]# rpm -qa ftp
ftp-0.17-67.el7.x86_64
#salt 'minion-01' pkg.install ftp
#1.'*' 代表的是target是指在那些minion上操作
#2. 'pkg' 是一个执行模块,就像'test'
#3.'install' 是执行模块下面的函数,像test下的ping
#4.'ftp' 是函数的参数(arg),有的函数需要参数,有的不需要比如test.ping就不需要参数
##查看所有执行模块的doc
salt 'minion' sys.doc
##查看test模块的帮助
salt 'minion' sys.doc test
##查看test.ping函数的帮助
salt 'minion' sys.doc test.ping
六、salt常用命令
**salt: **
该命令执行salt的执行模块,通常在master端运行.常用命令
salt [option] '<target>' <function> [arguments]
#例如
salt 'minion-01' cmd.run 'ip addr'
salt-run
该命令执行runner(salt自带或者自定义的,),通常在master端执行,比如经常用到的manage
salt-run [options] [runner.func]
#例如
salt-run manage.status ##查看所有minion状态
salt-run manage.down ##查看所有没在线minion
salt-run manage.up ##查看所有在线minion
salt-key:
密钥管理,通常在master端执行
salt-key [options]
salt-key -L ##查看所有minion-key
salt-key -a <key-name> ##接受某个minion-key
salt-key -d <key-name> ##删除某个minion-key
salt-key -A ##接受所有的minion-key
salt-key -D ##删除所有的minion-key
salt-call:
该命令通常在minion上执行,minion自己执行可执行模块,不通过master下发job
salt-call [options] <function> [arguments]
salt-call test.ping ##自己执行test.ping命令
salt-call cmd.run 'ifconfig' ##自己执行cmd.run函数
salt-cp
分发文件到minion上,不支持目录分发.运行在master
salt-cp [options] '<target>' SOURCE DEST
#例如
salt-cp '*' testfile.html /tmp
salt-cp 'test*' index.html /tmp/a.html
salt-master
salt-master [options]
salt-master ##前台运行master
salt-master -d ##后台运行master
salt-master -l debug ##前台debug输出
salt-minion
salt-minion [options]
salt-minion ##前台运行
salt-minion -d ##后台运行
salt-minion -l debug ##前台debug输出
1)普通用户执行salt:
两种方法:
1: ACL(修改master)
client_acl:
monitor: #uonghu
- test*: #权限
- test.*
dev:
- service.*
sa:
- .*
#重启master
#给予目录和文件权限
chmod +r /etc/salt/master
chmod +x /var/run/salt
chmod +x /var/cache/salt
2 external_auth(修改master)
pam:
fred:
- test.*
#重启master
#给予目录和文件权限
chmod +r /etc/salt/master
chmod +x /var/run/salt
chmod +x /var/cache/salt
使用Token不必每次都输入账号密码,使用external_auth每次都是需要密码的,这样多麻烦,这里引入了Token,它会保存一串字符到在当前用户家目录下.salt_token中,在有效时间内使用external_auth是不需要输入密码的,默认时间12hour,可以通过master配置文件修改
salt -T -a pam '*' test.ping
七、target
target也就是目标,目的.指定master命令应该对谁执行
- 正则匹配
[root@master /]# salt -E 'mini*' test.ping
minion-02:
True
minion-01:
True
- 列表匹配
[root@master ~]# salt -L minion-01,minion-02 test.ping
minion-02:
True
minion-01:
True
- grains匹配
[root@master ~]# salt -G 'os:CentOs' test.ping
minion-02:
True
minion-01:
True
- 组匹配
#开启master 的default_include
vim /etc/salt/master.d/nodegroup.conf
#写到master中也是这个格式
nodegroups:
test1: 'L@test1,test2 or test3*'
test2: 'G@os:CenOS or test2'
salt -N test1 test.ping #-N指定groupname
在top file中使用nodegroups
'test1':
- match: nodegroup ##没s,匹配的是文件
- webserver
[root@master ~]# salt -N nodegroups test.ping
minion-02:
True
minion-01:
True
#组需要在master中预先定义
- 复合匹配
salt -C 'G@os:MacOS or L@Minion1'
- Pillar匹配
salt -I 'key:value' test.ping
- CIDR匹配
salt -S '192.168.1.0/24' test.ping
在top文件中匹配 grains
% set self = grains['node_type'] %
- match: grain
- self
- 一次在n个minion上执行
-b n
--batch-size n
#例:
salt '*' -b 5 test.ping
#5个5个的ping
多master
2个master并不会共享Minion keys,一个master删除了一个key不会影响另一个
不会自动同步File_roots,所以需要手动去维护,如果用git就没问题了
不会自动同步Pillar_Roots,所以需要手工去维护,也可以用git
Master的配置文件也是独立的
#安装 salt-master
#原master的密钥cp一份到新的master
scp /etc/salt/pki/master/master* newmaster:/etc/salt/pki/master/
#启动新的Master
#修改配置minion的配置
master:
- master1
- master2
#重启minion
#新master接受所有的key
salt-key -L
salt-key -A
八、YAML解释
语法风格
-
空格和TAB
yaml两个空格为缩进, TAB不要使用! -
冒号: 和减号-
: 和- 后面要跟上一个空格在写. -
数字解析
mode: 0644 会解析成为mode: 644 最好使用mode: (0644) -
简写
vim:
pkg.installed #第一个简写
user.present #第二个简写.不被支持,因为不支持双简写
#建议规范书写
vim:
pkg:
- installed
user:
- present
Jinja
Jinja 基于Python模板引擎开发,saltstack默认使用yaml_jinja渲染器,渲染流程时先jinja在yaml解析.所以在开始解析yaml的时候可以使用jinja
- 区分模板文件
在salt中,files和templates都使用file这个state模块.那么如何区分模板是什么文件呢.
- templates: jinja
file.managed:
- name: /tmp/test
- source: salt://tmp/test
- template: jinja
- defaults:
Server: pillar['.....']
- jinja中使用grains
grains['os']
- jinja中使用执行模块
salt['network.hw_addr']('eth0')
- jinja中使用Pillar
pillar['apache']['PORT']
Jinja的逻辑关系
这和Django基本上一样,可以看一下官方手册
% if grains['os'] == 'RedHat' %
apache: httpd
% elif grains['os'] == 'Debian' %
apache: apache2
% endif %
九、salt常用模块和API
查看支持的所有modules
[root/] ]$salt 'minion-01' sys.list_modules
minion-01:
- acl
...
salt.client调用API举例:
[root/] ]$cd /usr/lib/python2.7/site-packages/salt/modules/ 模块path
API调用示例:
[root/] ]$cat test.py
#!/usr/bin/python
import salt.client
client = salt.client.LocalClient()
res = client.cmd('*','test.ping')
print res
[root/] ]$./test.py
'minion-02': True, 'minion-01': True
##解释一下
#当我们调用salt.client.LocalClient的时候,其实就等于我们执行了 salt '*' test.ping
API调用:
client.cmd('*','file.remove',['/tmp/foo'])
salt sys.doc module
可以查看模块支持那些命令
Archive
实现对系统曾经的压缩包调用支持gzip,gunzip.rar,tar,unrar,unzip等
#采用gunzip解压sourcefile.txt.gz包
salt '*' archive.gunzip sourcefile.txt.gz
#采用gzip压缩sourcefile.txt文件
salt '*' archive.gzip sourcefile.txt
API调用:
client.cmd('*','archive.gunzip',['sourcefile.txt.gz'])
cmd
实现对远程命令的调用执行,(默认具备root权限!谨慎使用)
#获取所欲被控主机的内存使用情况
salt '*' cmd.run 'free -m'
#在wx主机上运行test.py脚本,其中script/test.py存放在file_roots指定的目录(默认是在/srv/salt,自定义在/etc/salt/master文件中定义),
#该命令会做2个动作:首先同步test.py到minion的cache目录;起床运行该脚本
salt 'minion-01' cmd.script salt://script/test.py
API调用:
client.cmd('*','cmd.run',['free -m'])
cp
实现远程文件目录的复制,以及下载URL文件等操作
#将被控主机的/etc/hosts文件复制到被控主机本地的salt cache目录(/var/cache/salt/minion/localfiles/)
salt '*' cp.cache_local_file /etc/hosts
#将主控端file_roots指定位置下的目录复制到被控主机/minion/目录下
salt '*' cp.get_dir salt://script/ /minion/
#将主控端file_roots指定位置下的文件复制到被控主机/minion/test.py文件(file为文件名)
salt '*' cp.get_dir salt://script/test.py /minion/test.py
#下载URL内容到被控主机指定位置(/tmp/index.html)
salt '*' cp.get_url http://www.slashdot.ort /tmp/index.html
API调用:
client.cmd('*','cp.get_file',['salt://script/test.py','/minion/test.py'])
cron
实现对minion的crontab控制
#查看指定被控主机、root用户的crontab操作
salt 'minion-01' cron.raw_cron root
#为指定被控主机、root用户添加/usr/local/weekly任务zuoye
salt 'minion-01' cron.set_job root '*' '*' '*' '*' 1 /usr/local/weekly
#删除指定被控主机、root用户crontab的/usr/local/weekly任务zuoye
salt 'minion-01' cron.rm_job root /usr/local/weekly
API调用:
client.cmd('wx','cron.set_job',['root','*','*','*','*',1,'/usr/local/weekly'])
file
对minion的文件操作,包括文件读写,权限,查找校验
#校验所有被控主机/etc/fstab文件的md5值是否为xxxxxxxxxxxxx,一致则返回True值
salt '*' file.check_hash /etc/fstab md5=xxxxxxxxxxxxxxxxxxxxx
#校验所有被控主机文件的加密信息,支持md5、sha1、sha224、shs256、sha384、sha512加密算法
salt '*' file.get_sum /etc/passwd md5
#修改所有被控主机/etc/passwd文件的属组、用户权限、等价于chown root:root /etc/passwd
salt '*' file.chown /etc/passwd root root
#复制所有被控主机/path/to/src文件到本地的/path/to/dst文件
salt '*' file.copy /path/to/src /path/to/dst
#检查所有被控主机/etc目录是否存在,存在则返回True,检查文件是否存在使用file.file_exists方法
salt '*' file.directory_exists /etc
#获取所有被控主机/etc/passwd的stats信息
salt '*' file.stats /etc/passwd
#获取所有被控主机/etc/passwd的权限mode,如755,644
salt '*' file.get_mode /etc/passwd
#修改所有被控主机/etc/passwd的权限mode为0644
salt '*' file.set_mode /etc/passwd 0644
#在所有被控主机创建/opt/test目录
salt '*' file.mkdir /opt/test
#将所有被控主机/etc/httpd/httpd.conf文件的LogLevel参数的warn值修改为info
salt '*' file.sed /etc/httpd/httpd.conf 'LogLevel warn' 'LogLevel info'
#给所有被控主机的/tmp/test/test.conf文件追加内容‘maxclient 100’
salt '*' file.append /tmp/test/test.conf 'maxclient 100'
#删除所有被控主机的/tmp/foo文件
salt '*' file.remove /tmp/foo
network
返回minion的主机信息
#在指定被控主机获取dig、ping、traceroute目录域名信息
salt 'minion-01' network.dig www.qq.com
salt 'minion-01' network.ping www.qq.com
salt 'minion-01' network.traceroute www.qq.com
#获取指定被控主机的mac地址
salt 'minion-01' network.hwaddr eth0
#检测指定被控主机是否属于10.0.0.0/16子网范围,属于则返回True
salt 'minion-01' network.in_subnet 10.0.0.0/16
#获取指定被控主机的网卡配置信息
salt 'minion-01' network.interfaces
#获取指定被控主机的IP地址配置信息
salt 'minion-01' network.ip_addrs
#获取指定被控主机的子网信息
salt 'minion-01' network.subnets
API调用:
client.cmd('minion-01','network.ip_addrs')
pkg
minion的程序包管理,如yum, apt-get等
#为所有被控主机安装php环境,根据不同系统发行版调用不同安装工具进行部署,如redhat平台的yum,等价于yum -y install php
salt '*' pkg.install php
#卸载所有被控主机的PHP环境
salt '*' pkg.remove php
#升级所有被控主机的软件包
salt '*' pkg.upgrade
API调用:
client.cmd('*','pkg.remove',['php'])
status
salt '*' status.version
API调用:
import salt.client
client = salt.client.LocalClient()
client.cmd('*','status.uptime')
system
用来日常操作计算机
system.halt #停止正在运行的系统
system.init 3 #切换到字符界面,5是图形界面
system.poweroff
system.reboot
system.shutdown
systemd(service)
service.available sshd #查看服务是否可用
service.disable <service name> #设置开机启动的服务
service.enable <service name>
service.disabled <service name> #查看服务是不是开机启动
service.enabled <service name>
service.get_disabled #返回所有关闭的服务
service.get_enabled #返回所有开启的服务
service.get_all #返回所有服务
service.reload <service name> #重新载入指定的服务
service.restart <service name> #重启服务
service.start <service name>
service.stop <service name>
service.status <service name>
service.force_reload <service name> #强制载入指定的服务
使用:
[root@mail python]# salt '*' service.available sshdmonitor: True
api调用:
>>> client.cmd(Saltstack批量安装部署Zabbix代理(附zabbix自动注册详解)