简介
SaltStack是一个服务器基础架构集中化管理平台,具备配置管理、远程执行、监控等功能,一般可以理解为简化版的puppet和加强版的func。SaltStack基于Python语言实现,结合轻量级消息队列(ZeroMQ)
与Python第三方模块(Pyzmq、PyCrypto、Pyjinjia2、python-msgpack和PyYAML等)构建。有如下特性:
(1)、部署简单、方便;
(2)、支持大部分UNIX/Linux及Windows环境;
(3)、主从集中化管理;
(4)、配置简单、功能强大、扩展性强;
(5)、主控端(master)和被控端(minion)基于证书认证,安全可靠;
(6)、支持API及自定义模块,可通过Python轻松扩展。
通过部署SaltStack环境,我们可以在成千上万台服务器上做到批量执行命令,根据不同业务特性进行配置集中化管理、分发文件、采集服务器数据、操作系统基础及软件包管理等,SaltStack是运维人员提高工作效率、规范业务配置与操作的利器。
SaltStack master启动后默认监听4505和4506两个端口。
4505(publish_port)为saltstack的消息发布系统,
4506(ret_port)为saltstack被控端与服务端通信的端口。
如果使用lsof 查看4505端口,会发现所有的minion在4505端口持续保持在ESTABLISHED状态。minion与master之间的通信模式如下:
被控端直接于主控端的zeromq建立长连接,接收广播到的任务消息并执行。即在主控端配置iptables规则:
iptables -I INPUT -m state --state new -m tcp -p tcp --dport 4505 -j ACCEPT
iptables -I INPUT -m state --state new -m tcp -p tcp --dport 4506 -j ACCEPT
saltstack认证原理:
会在/etc/salt/pki/minion/(该路径在/etc/salt/minion里面设置)下自动生成minion.pem(private key)和 minion.pub(public key),然后将 minion.pub发送给master。
通过salt-key命令accept minion public key,这样在
master的/etc/salt/pki/master/minions下的将会存放以minion id命名的 public key,然后master就
能对minion发送指令了。
依赖情况:
SaltStack的通信模式分为2种模式:ZeroMQ、REAT,鉴于REAT目前还不是太稳定,选择ZeroMQ模式。
安装
本例采用centos6。5默认的Python2。6。6。。若更改Python版本,
同时要修改
vim /usr/bin/yum。
此处仅介绍通过yum安装saltstack。
默认的yum 源没有saltstack包,需要改为epel 源。
https://dl.fedoraproject.org/pub/epel/epel-release-latest-6.noarch.rpm
若安装时出现报错:
Error: Package: salt-2015.5.10-2.el6.noarch (epel)
Requires: python-requests
Error: Package: salt-2015.5.10-2.el6.noarch (epel)
Requires: PyYAML
You could try using --skip-broken to work around the problem
You could try running: rpm -Va --nofiles --nodigest
需要在/etc/yum.repos.d/加上centos自带的yum源--CentOS-Base.repo。
yum -y install salt-master
chkconfig salt-master on
yum -y install salt-minion
chkconfig salt-minion on
调整salt配置并检验
saltstack的配置文件格式都是YAML 的,配置的时候需要注意语法
master端:
vi /etc/salt/master
interface: masterIP #绑定master通信IP。
auto_accept: True #设为自动认证,避免繁琐的手动运行salt-key确认证书信任。
#指定salt文件根目录的位置
base:
- /srv/salt
更改完成后启动该服务
minion端:
vi /etc/salt/minion
master: masterIP #绑定master主机IP地址。
id: JYD-test-2 #更改被控端主机识别id,建议用主机名来配置
更改完成后启动该服务
应用
salt-key -L # 显示当前所有被控端id
-D 删除所有认证id
-d id 删除某个id证书
-A 接受所有id证书请求
-a id 接受某个id证书请求
salt '*' test.ping # 测试所有主机的连通性(此处*为通配符)
salt -E '^JYD-test.*' cmd.run 'free -m' # -E使用正则,cmd.run执行远程命令
-L 以主机id名列表的形式操作部分主机
-G 根据被控主机的grains过滤(后续详细介绍)
-I 根据被控主机的pillar过滤 (后续详细介绍)
-N 根据分组名称过滤(分组在/etc/salt/master里定义)
-C 根据条件符not and or 匹配
-S 根据被控主机的IP或子网匹配
常用模块学习
cp模块(实现远程文件、目录的复制,以及下载URL文件等操作)(参数 cache_local_file、get_file、get_dir、get_url)
## 将主服务器file_roots指定位置下的目录复制到被控主机
# salt '*' cp.get_dir salt://hellotest /data
##将主服务器file_roots指定位置下的文件复制到被控主机
# salt '*' cp.get_file salt://hellotest/rocketzhang /root/rocketzhang
## 下载指定URL内容到被控主机指定位置
# salt '*' cp.get_url http://xxx.xyz.com/download/0/files.tgz /root/files.tgz
API调用:client.cmd('*','cp.get_dir',['salt://path/to/dir','/minion/dest'])
cmd模块(实现远程的命令行调用执行,默认是root权限,使用注意)
# salt '*' cmd.run 'netstat -ntlp'
API调用:client.cmd('*','cmd.run',['命令'])
★此模块较常用,可实现多个模块的功能。
cron模块(实现被控主机的crontab操作)(raw_cron查,cron.set_job加,rm_job删)
## 为指定的被控主机、root用户添加crontab信息
# salt '*' cron.set_job root '*/5' '*' '*' '*' '*' 'date >/dev/null 2>&1'
# salt '*' cron.raw_cron root
## 删除指定的被控主机、root用户的crontab信息
# salt '*' cron.rm_job root 'date >/dev/null 2>&1'
API调用:client.cmd('*','cron.rm_job',['root','命令']
dnsutil模块(实现被控主机通用DNS操作)
## 为被控主机添加指定的hosts主机配置项
# salt '*' dnsutil.hosts_append /etc/hosts 127.0.0.1 test.com
API调用:client.cmd('*','dnsutil.hosts_remove',['/etc/hosts','域名']
file模块(被控主机文件常见操作,包括文件读写、权限、查找、校验等)(参数有check_hash md5加密值对比、get_sum 指定加密方式、chown、copy、dirctory_exists目录是否存在、stats、get_mode、set_mode、mkdir、sed内容修改、append追加、remove)
# salt '*' file.get_sum /etc/resolv.conf md5
# salt '*' file.stats /etc/resolv.conf
API调用:client.cmd('*',fiel.append /文件 "增加字段")
archive模块,在系统层面实现压缩包的调用(gzip,gunzip,tar,unzip等)
# salt '*' archive.gzip /tmp/abc.txt
API调用:client.cmd('*','archive.gunzip ',['/tmp/qq.gz'])
network模块(返回被控主机网络信息)(参数有 dig、ping、traceroute 跟域名,hwaddr 跟网卡、in_subnet 跟网段、interfaces、ip_addrs、subnet 无字段)
# salt '*' network.ip_addrs
# salt '*' network.interfaces
API调用:client.cmd('*','network.in_subnet','网段')
pkg包管理模块(被控主机程序包管理,如yum、apt-get等)(参数有 install、remove 跟软件包,upgrade升级所有)
# salt '*' pkg.install nmap
# salt '*' pkg.file_list nmap
API调用:client.cmd('*','pkg.upgrade')
service 服务模块(被控主机程序包服务管理)(参数有 enable、disable、reload、restart、start、stop、status)
# salt '*' service.enable crond
# salt '*' service.reload crond
API调用:client.cmd('*','service.stop' 'httpd')
1、安装
安装saltstack用EPEL源安装简单快捷,实际部署的时候可以将saltstack相关的rpm包放到本地的yum源用本地源安装。
安装EPEL源:
[root@saltstack ~]#wget -c http://dl.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm
[root@saltstack ~]#rpm -ivh epel-release-6-8.noarch.rpm
安装salt-master,如果master要对自己进行配置管理则服务器master端本地也要安装minion
yum install salt-master
#安装salt-minion可选
yum install salt-minion
2、修改配置文件并启动服务。saltstack配置比较简单,一般不需要修改太多的参数。
salt-master端,暂时没有什么配置的,默认就好。
grep -Ev "^#|^$" /etc/salt/master
file_roots:
base:
- /srv/salt
pillar_roots:
base:
- /srv/pillar
salt-master -d
salt-minion端,配置 “master”项指向master的IP地址,配置 “id” 项为主机名(一般用主机名,也可以配成其它的标识符)
grep -Ev "^#|^$" /etc/salt/minion
master: 192.168.186.134
id: minion01
salt-minion -d
[root@minion01 ~]#
[root@minion02 ~]# grep -Ev "^#|^$" /etc/salt/minion
master: 192.168.186.134
id: minion02
[root@minion02 ~]# salt-minion -d
[root@minion02 ~]#
3、master认证端添minion的key,并做简单的存活测试。
salt-key管理所有的key,-L参数列出所有的key.”Unaccepted Keys”就是所有未认证minion端的key。
[root@saltstack ~]# salt-key -L
Accepted Keys:
Unaccepted Keys:
minion01
minion02
Rejected Keys:
-A参数接纳(认证)所有未被接纳(认证)的key,-a参数认证单个指定的key。
[root@saltstack ~]# salt-key -A
The following keys are going to be accepted:
Unaccepted Keys:
minion01
minion02
Proceed? [n/Y] y
Key for minion minion01 accepted.
Key for minion minion02 accepted.
再查看下所有key的情况,可以看到”Accepted Keys”已经认证的key。
salt-key -L
Accepted Keys:
minion01
minion02
Unaccepted Keys:
Rejected Keys:
用test.ping测试下minion端的存活,可以从返回值看到minion01和minion02在线
salt \* test.ping
minion01:
True
minion02:
True
[root@saltstack ~]#
用test.ping命令测试时,如果等待的返回时间较长有可能是某些minion已经不在线了,可以用salt-run来查看所有minion的存活状态。
salt-run manage.status
down:
up:
- minion01
- minion02
[root@saltstack ~]#
salt相关的管理命令:
# 查看存活的minion
# 查看死掉的minion
# 查看down掉的minion,并将其删除
# 查看minion的相关状态
# 查看salt的所有master和minion的版本信息
# 查看哪些系统任务还在处理中
# 显示所有的已完成或部分完成的任务信息
# 查看运行的jobs ID
salt \* saltutil.kill_job 20151209034239907625 # kill掉进程ID
# 查看帮助文档
# 查看service相关模块命令
# 查看帮助文档
# 查询所有接收到的证书
# 接收单个证书
# 接受所有证书
# 删除单个证书
# 删除所有证书
# 获取主机所有服务
# 重载sshd服务
# 显示软件包版本列表
# 显示软件包版本信息
# 安装软件包
# 查看mysql服务状态
# 启动mysql服务
# 模块列表
# 把master上的hosts文件分发到所有主机
# 把salt-master端相应的目录,分发文件到minion端
# 远程命令执行测试
远程执行脚本:
'cmd.script:'
salt '*' cmd.script salt://scripts/runme.sh
salt '*' cmd.script salt://scripts/runme.sh 'arg1 arg2 "arg 3"'
salt '*' cmd.script salt://scripts/windows_task.ps1 args=' -Input c:\tmp\infile.txt' shell='powershell'
salt '*' cmd.script salt://scripts/runme.sh stdin='one\ntwo\nthree\nfour\nfive\n'
'cmd.shell:'
This passes the cmd argument directly to the shell
salt '*' cmd.shell "ls -l | awk '/foo/{print \$2}'"
salt '*' cmd.shell template=jinja "ls -l /tmp/{{grains.id}} | awk '/foo/{print \$2}'"
salt '*' cmd.shell "Get-ChildItem C:\ " shell='powershell'
salt '*' cmd.shell "grep f" stdin='one\ntwo\nthree\nfour\nfive\n'
salt '*' cmd.shell cmd='sed -e s/=/:/g'
'cmd.shells:'
salt '*' cmd.shells
'cmd.tty:'
salt '*' cmd.tty tty0 'This is a test'
salt '*' cmd.tty pts3 'This is a test'
'cmd.which:'
salt '*' cmd.which cat
grains选项:
salt '*' grains.ls # 查看grains分类
salt '*' grains.items # 查看grains所有信息
salt '*' grains.item osrelease # 查看grains某个信息
说明:state模块是salt state的管理模块,可以通过state模块简单的对minion操作sls状态
salt 'node1.com' state.highstate # 更新指定minons的所有sls状态
salt 'node1.com' state.running # 查看当前运行的sls状态
相关例子:
salt \* saltutil.running
node02.saltstack.com:
|_
----------
arg:
- egrep -v ^#
fun:
cmd.run
jid:
20170221141733009548
pid:
5922
ret:
tgt:
*
tgt_type:
glob
user:
root
|_
----------
arg:
- egrep -v ^#
fun:
cmd.run
jid:
20170221141748160358
pid:
5927
ret:
tgt:
*
tgt_type:
glob
user:
root
node01.saltstack.com:
|_
----------
arg:
- egrep -v ^#
fun:
cmd.run
jid:
20170221141733009548
pid:
6252
ret:
tgt:
*
tgt_type:
glob
user:
root
|_
----------
arg:
- egrep -v ^#
fun:
cmd.run
jid:
20170221141748160358
pid:
6256
ret:
tgt:
*
tgt_type:
glob
user:
root
[root@master ~]# salt \* saltutil.kill_job 20170221141748160358
node01.saltstack.com:
Signal 9 sent to job 20170221141748160358 at pid 6256
node02.saltstack.com:
Signal 9 sent to job 20170221141748160358 at pid 5927
[root@master ~]# salt \* saltutil.kill_job 20170221141733009548
node02.saltstack.com:
Signal 9 sent to job 20170221141733009548 at pid 5922
node01.saltstack.com:
Signal 9 sent to job 20170221141733009548 at pid 6252
[root@master ~]# salt \* saltutil.running
node01.saltstack.com:
node02.saltstack.com:
salt-run manage.versions
Master:
2015.5.10
Up to date:
----------
node01.saltstack.com:
2015.5.10
node02.saltstack.com:
2015.5.10
salt-run manage.status
down:
up:
- minion.saltstack.com
- minion2.saltstack.com
salt-run manage.versions
#查看salt的所有master和minion的版本信息
Master:
2015.5.10
Up to date:
----------
minion.saltstack.com:
2015.5.10
minion2.saltstack.com:
2015.5.10
salt '*' test.ping -v
# 使用-v参数,能够查看到job的jid
Executing job with jid 20170214142709337088
-------------------------------------------
minion.saltstack.com:
True
minion2.saltstack.com:
True
说明:每执行一个任务,都会有一个对应的jid
salt '*' saltutil.running
# 查看minion当前正在运的jobs
minion2.saltstack.com:
|_
----------
arg:
fun:
state.highstate
jid:
20170214143846076337
pid:
5488
ret:
tgt:
*
tgt_type:
glob
user:
root
minion.saltstack.com:
|_
----------
arg:
fun:
state.highstate
jid:
20170214143846076337
pid:
6384
ret:
tgt:
*
tgt_type:
glob
user:
root
salt '*' saltutil.kill_job 20170214143846076337
#取消正在执行的某个jid,例如:20170214143846076337
salt-run jobs.list_jobs
20170221155927733273:
----------
Arguments:
Function:
state.running
StartTime:
2017, Feb 21 15:59:27.733273
Target:
node01.saltstack.com
Target-type:
glob
User:
root
20170221160325920754:
----------
Arguments:
Function:
sys.doc
StartTime:
2017, Feb 21 16:03:25.920754
Target:
*
Target-type:
glob
User:
root
20170221161556599324:
----------
Arguments:
- cat
Function:
cmd.which
StartTime:
2017, Feb 21 16:15:56.599324
Target:
*
Target-type:
glob
User:
root
20170221161641114901:
----------
Arguments:
Function:
grains.ls
StartTime:
2017, Feb 21 16:16:41.114901
Target:
*
Target-type:
glob
User:
root
目的:用Saltstack工具去部署批量服务器,自动化安装(卸载)服务(比如MySQL)。
[root@node2 ~]# ll
总用量 304228
-rw-r--r-- 1 root root 311516309 3月 10 2015 mysql-5.6.21-linux-glibc2.5-x86_64.tar.gz
-rwxr-xr-x 1 root root 6628 3月 25 12:52 MySQL_二进制安装.sh
-rwxr-xr-x 1 root root 590 3月 25 12:53 MySQL_二进制卸载.sh
[root@node2 ~]#
1、查看Master和minion状态。
node2
node4
1.1)查看master状态信息:
netstat -atupn|grep --color -E '4505|4506'
tcp 0 0 0.0.0.0:4505 0.0.0.0:* LISTEN 2897/python2.6
tcp 0 0 0.0.0.0:4506 0.0.0.0:* LISTEN 2915/python2.6
tcp 0 0 192.168.1.221:4505 192.168.1.223:58448 ESTABLISHED 2897/python2.6
tcp 0 0 192.168.1.221:4506 192.168.1.223:53904 ESTABLISHED 2915/python2.6
[root@node2 ~]#
1.2)查看当前的salt key信息(minion)我只配置了一个:
salt-key -L
Accepted Keys:
node4
Denied Keys:
Unaccepted Keys:
Rejected Keys:
[root@node2 ~]#
1.3)查看minion状态信息:
salt 'node4' cmd.run 'netstat -atupn|grep python'
node4:
tcp 0 0 192.168.1.223:53904 192.168.1.221:4506 ESTABLISHED 2846/python2.6
tcp 0 0 192.168.1.223:58448 192.168.1.221:4505 ESTABLISHED 2846/python2.6
[root@node2 ~]#
1.4)分发Shell脚本和包并授权:
1.4.1)常用cp模块介绍:(其它模块可看我其它相关博客)
cp.get_file 从主服务器下载目录
cp.get_dir 从主服务器下载文件
cp.get_url 从服务器下载指定URL文件
salt 'node4' cp.get_file salt://mysql-5.6.21-linux-glibc2.5-x86_64.tar.gz /root/mysql-5.6.21-linux-glibc2.5-x86_64.tar.gz
node4:
/root/mysql-5.6.21-linux-glibc2.5-x86_64.tar.gz
[root@node2 ~]#
salt 'node4' cp.get_file salt://MySQL_install.sh /root/MySQL_install.sh
node4:
/root/MySQL_install.sh
salt 'node4' cp.get_file salt://MySQL_remove.sh /root/MySQL_remove.sh
node4:
/root/MySQL_remove.sh
[root@node2 ~]#
1.4.2)minion查看;
[root@node4 ~]# ll
总用量 304232
-rw-r--r-- 1 root root 311516309 3月 25 14:06 mysql-5.6.21-linux-glibc2.5-x86_64.tar.gz
-rw-r--r-- 1 root root 6628 3月 25 14:09 MySQL_install.sh
-rw-r--r-- 1 root root 590 3月 25 14:10 MySQL_remove.sh
[root@node4 ~]#
1.4.3)脚本加权:
salt 'node4' cmd.run 'chmod +x /root/*.sh'
node4:
[root@node2 ~]#
1.5)脚本安装:
1.5.1)安装
salt 'node4' cmd.run '/root/MySQL_install.sh'
node4:
?[37;32m 开始MySQL的安装! ?[0m
?[37;32m MySQL安装目录已经创建完成![/usr/local/mysql下] ?[0m
########################################################!
?[37;32m MySQL需要的的用户和组创建完成! ?[0m
########################################################!
安装MySQL需要的基本依赖包!
?[37;32m MySQL需要的基本依赖包已安装完成! ?[0m
########################################################!
初始化MySQL!
?[37;32m MySQL初始化成功! ?[0m
########################################################!
更改MySQL权限属组权限
?[37;32m 更改MySQL目录权限属组权限成功! ?[0m
########################################################!
创建并配置mysql的启动文件!
?[37;32m MySQL启动文件已经创建配置完成! ?[0m
########################################################!
导入优化好的my.cnf到/etc/下
?[37;32m MySQL的配置文件已准备完毕! ?[0m
########################################################!
启动MySQL服务
?[37;32m MySQL服务启动成功! ?[0m
########################################################!
配置MySQL的root账号密码!
?[37;32m MySQL的root默认账号密码是renzhiyuan ?[0m
########################################################!
[root@node2 ~]#
1.5.2)卸载:
salt 'node4' cmd.run '/root/MySQL_remove.sh'
node4:
?[37;32m 开始MySQL卸载! ?[0m
########################################################!
?[37;32m MySQL卸载成功! ?[0m
########################################################!
[root@node2 ~]#
saltstack-master配置文件详解
vim /etc/salt/master
interface: 192.168.28.141 #绑定到本地的某个网络地址
publish_port: 4505 #默认端口4505,设置master与minion通信端口
user: root #运行salt进程的用户
max_open_files: 100000 #master可以打开的最大句柄数
worker_threads: 5 #启动用来接收或应答minion的线程数
ret_port: 4506 #master用来发送命令或接受minions的命令执行返回信息
pidfile: /var/run/salt-master.pid #指定master的pid文件位置
root_dir: / #该目录为salt运行的根目录,改变它可以使salt从另外一个目录运行,好比chroot
pki_dir: /etc/salt/pki/master #存放pki认证密钥
cachedir: /var/cache/salt #存放缓存信息,salt工作执行的命令信息
verify_env: True #启动验证和设置权限配置目录
keep_jobs: 24 #保持工作信息的过期时间,单位小时
job_cache: True #设置master维护的工作缓存.当minions超过5000台时,它将很好的承担这个大的架构
timeout: 5 #master命令执可以接受的延迟时间
output: nested #salt命令的输出格式
minion_data_cache: True #关于minion信息存储在master上的参数,主要是pilar和grains数据
auto_accept: False #默认值False. master自动接受所有发送公钥的minion
file_recv: False #允许minion推送文件到master上
file_recv_max_size: 100 #默认值100,设置一个hard-limit文档大小推送到master端
state_top: top.sls #状态入口文件
renderer: yaml_jinja #使用渲染器用来渲染minions的状态数据
failhard: False #当单个的状态执行失败后,将会通知所有的状态停止运行
saltstack的master以及minion的安装
master:
查看主机解析(如果内网有自己的DNS主从,那就更省事情了)
cat /etc/hosts
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
10.10.10.140mastermaster.saltstack.com
10.10.10.141node01node01.saltstack.com
10.10.10.142node02node02.saltstack.com
安装外部epel源,然后安装salt-master
rpm -ivh http://dl.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm
yum -y install salt-master
/etc/init.d/salt-master start
Starting salt-master daemon: [确定]
[root@master ~]# chkconfig --add salt-master
[root@master ~]# chkconfig salt-master on
[root@master ~]# chkconfig --list | grep salt-master
salt-master 0:关闭1:关闭2:启用3:启用4:启用5:启用6:关闭
[root@master ~]# netstat -tunlp | grep python
tcp 0 0 0.0.0.0:4505 0.0.0.0:* LISTEN 2907/python2.6
tcp 0 0 0.0.0.0:4506 0.0.0.0:* LISTEN 2927/python2.6
备注:
SaltStack是基于python进行开发,server端监听的是4505以及4506两个端口
b) SaltStack master启动后默认监听4505和4506两个端口。
4505(publish_port)为saltstack的消息发布系统,
4506(ret_port)为saltstack客户端与服务端通信的端口。
c) 如果使用lsof 查看4505端口,会发现所有的minion在4505端口持续保持在ESTABLISHED状态。
[root@master ~]# lsof -i :4505
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
salt-mast 2907 root 12u IPv4 16492 0t0 TCP *:4505 (LISTEN)
[root@master ~]# lsof -i :4506
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
salt-mast 2927 root 20u IPv4 16519 0t0 TCP *:4506 (LISTEN)
进入salt的目录,查看目录结构:
[root@master ~]# cd /etc/salt/
[root@master salt]# tree
.
├── master
├── pki
│ └── master
│ ├── master.pem
│ ├── master.pub
│ ├── minions
│ ├── minions_autosign
│ ├── minions_denied
│ ├── minions_pre
│ ├── minions_rejected
│ └── ssh
│ ├── salt-ssh.rsa
│ └── salt-ssh.rsa.pub
├── roster
├── roster.bak
└── roster.org
8 directories, 8 files
备注:/etc/salt/master这个文件,为saltstack master的主配置文件
salt master端的几个重要命令说明:
rpm -ql salt-master
/etc/rc.d/init.d/salt-master # salt-master服务器启动脚本
/etc/salt/master # salt master配置文件
/usr/bin/salt # salt master核心操作命令
/usr/bin/salt-cp # salt文件传输命令
/usr/bin/salt-key # salt证书管理命令
/usr/bin/salt-master # salt master服务命令
/usr/bin/salt-run # salt master runner命令
/usr/bin/salt-unity
/usr/share/man/man1/salt-cp.1.gz
/usr/share/man/man1/salt-key.1.gz
/usr/share/man/man1/salt-master.1.gz
/usr/share/man/man1/salt-run.1.gz
/usr/share/man/man1/salt-unity.1.gz
/usr/share/man/man7/salt.7.gz
minion:
安装和配置minion端
[root@node01 ~]# rpm -ivh http://dl.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm
yum -y install salt-minion
[root@node01 ~]# /etc/init.d/salt-minion start
Starting salt-minion daemon: [确定]
[root@node01 ~]# chkconfig --list | grep salt
salt-minion 0:关闭1:关闭2:启用3:启用4:启用5:启用6:关闭
tree /etc/salt/
/etc/salt/
├── minion
├── minion.d
├── minion_id
└── pki
└── minion
├── minion.pem
└── minion.pub
3 directories, 4 files
You have new mail in /var/spool/mail/root
[root@node01 ~]# cd /etc/salt/
修改前备份minion端配置文件(运维要养成好习惯)
cp minion minion.bak
设置master的名称:(这里也可以写为master: 10.10.10.140)
sed -i "16s/#master: salt/master: master.saltstack.com/" /etc/salt/minion
设置minion端的ID
sed -i "78s/#id:/id: minion.saltstack.com/" /etc/salt/minion
[root@node01 salt]# diff /etc/salt/minion /etc/salt/minion.bak
16c16
< master: master.saltstack.com
---
> #master: salt
78c78
< id: node01.saltstack.com
---
> #id:
egrep -v '#|^$' /etc/salt/minion |uniq
id: node01.saltstack.com
[root@node01 salt]# /etc/init.d/salt-minion restart
Stopping salt-minion daemon: [确定]
Starting salt-minion daemon:
[确定]
在master端接受指定的key:
salt-key -L
Accepted Keys:
Denied Keys:
Unaccepted Keys:
node01.saltstack.com
Rejected Keys:
使用salt-key -L表明查看key的信息
salt-key -a node01.saltstack.com
The following keys are going to be accepted:
Unaccepted Keys:
node01.saltstack.com
Proceed? [n/Y] Y
Key for minion node01.saltstack.com accepted.
说明:如上所示,在服务端允许node01.saltstack.com成为被信任的key
[root@master ~]# salt-key -L
Accepted Keys:
node01.saltstack.com
Denied Keys:
Unaccepted Keys:
Rejected Keys:
salt minion端的几个重要命令说明:
rpm -ql salt-minion
/etc/rc.d/init.d/salt-minion # salt minion服务启动脚本
/etc/salt/minion # salt minion配置文件
/usr/bin/salt-call # salt call拉取命令
/usr/bin/salt-minion # salt minion服务命令
/usr/share/man/man1/salt-call.1.gz
/usr/share/man/man1/salt-minion.1.gz
使用salt推送几个常用的命令进行测试:
salt '*' test.ping
node01.saltstack.com:
True
说明:返回值为True,表明执行的结果是正确的
salt 'node01.saltstack.com' cmd.run 'df -h'
node01.saltstack.com:
Filesystem Size Used Avail Use% Mounted on
/dev/sda5 14G 8.4G 4.5G 66% /
tmpfs 932M 84K 932M 1% /dev/shm
/dev/sda1 190M 42M 139M 23% /boot
/dev/sda3 2.0G 18M 1.8G 1% /tmp
salt 'node01.saltstack.com' cmd.run 'ntpdate -u 10.203.10.20'
node01.saltstack.com:
15 Feb 13:37:12 ntpdate[9245]: step time server 10.203.10.20 offset -28800.128648 sec
salt-cp是个非常常用的命令,下面举例说明下常见的用法
[root@master ~]# echo "welcome to China">>test.txt
salt-cp '*' test.txt /tmp/
{'node01.saltstack.com': {'/tmp/test.txt': True},
'node02.saltstack.com': {'/tmp/test.txt': True}}
[root@master ~]# salt '*' cmd.run 'cat /tmp/test.txt'
node01.saltstack.com:
welcome to China
node02.saltstack.com:
welcome to China
salt-cp -E 'node[0-9][1-9].saltstack.com' test.txt /tmp/test2.txt
{'node01.saltstack.com': {'/tmp/test2.txt': True},
'node02.saltstack.com': {'/tmp/test2.txt': True}}
[root@master ~]# salt-cp -G 'os:CentOS' test.txt /tmp/test3.txt
{'node01.saltstack.com': {'/tmp/test3.txt': True},
'node02.saltstack.com': {'/tmp/test3.txt': True}}
到此,salt的master以及minion端的安装就已完成
saltstack项目实战_安装nginx
创建nginx所需目录
[root@node1 ~]# cd /data/etc/salt/
[root@node1 salt]# mkdir -p nginx/files
[root@node1 salt]# cd nginx/files/
[root@node1 files]# wget http://nginx.org/download/nginx-1.11.3.tar.gz
[root@node1 salt]# tree nginx/
nginx/
|-- conf.sls
|-- files
| |-- nginx
| |-- nginx-1.11.3.tar.gz
| |-- nginx.conf
| |-- nginx_log_cut.sh
| `-- vhost.conf
|-- init.sls
|-- install.sls
`-- vhost.sls
cat nginx/init.sls
include:
- nginx.install
- nginx.conf
- nginx.vhost
cat top.sls
base:
'*':
- nginx.init
2. 安装nginx文件
vim install.sls
nginx_source:
file.managed:
- name: /usr/local/src/nginx-1.11.3.tar.gz
- unless: test -e /usr/local/src/nginx-1.11.3.tar.gz
- user: root
- group: root
- source: salt://nginx/files/nginx-1.11.3.tar.gz
nginx_pkg:
pkg.installed:
- pkgs:
- openssl-devel
- pcre-devel
- zlib-devel
- unzip
nginx_user:
user.present:
- name: www
- createhome: False
- shell: /sbin/nologin
nginx_extrace:
cmd.run:
- cwd: /usr/local/src
- names:
- tar zxf nginx-1.11.3.tar.gz && chown -R root:root nginx-1.11.3
- unless: test -d /usr/local/src/nginx-1.11.3
- require:
- pkg: nginx_pkg
nginx_compile:
cmd.run:
- name: cd /usr/local/src/nginx-1.11.3 && ./configure --prefix=/usr/local/nginx --user=www --group=www --with-http_stub_status_module --with-http_gzip_static_module --with-http_ssl_module --with-http_realip_module && make && make install
- unless: test -d /usr/local/nginx
- require:
- cmd: nginx_extrace
- user: nginx_user
create_dir:
cmd.run:
- names:
- chown -R www:www /usr/local/nginx/html && mkdir -p /usr/local/nginx/conf/vhost
- unless: test -d /usr/local/nginx/conf/vhost
- require:
- cmd: nginx_compile
3. 管理nginx配置文件
cat conf.sls
include:
- nginx.install -> 引用nginx目录下install.sls文件
{% set nginx_user = 'www' %}
nginx_conf:
file.managed: -> nginx主配置文件
- name: /usr/local/nginx/conf/nginx.conf
- source: salt://nginx/files/nginx.conf
- template: jinja
- defaults:
nginx_user: {{ nginx_user }}
num_cpus: {{ grains['num_cpus'] }}
nginx_service: -> nginx服务管理
file.managed:
- name: /etc/init.d/nginx
- user: root
- group: root
- mode: 755
- source: salt://nginx/files/nginx
cmd.run:
- names:
- /sbin/chkconfig --add nginx && /sbin/chkconfig nginx on
- unless: /sbin/chkconfig --list nginx
service.running:
- name: nginx
- enable: True
- reload: True
- watch:
- file: /usr/local/nginx/conf/vhost/*.conf
nginx_log_cut:
file.managed:
- name: /usr/local/nginx/sbin/nginx_log_cut.sh
- source: salt://nginx/files/nginx_log_cut.sh
cron.present:
- name: sh /usr/local/nginx/sbin/nginx_log_cut.sh
- user: root
- minute: 10
- hour: 0
- require:
- file: nginx_log_cut
4. 使用pillar适合针对不同的主机动态生成配置文件
[root@node1 ~]# cd /data/etc/salt/pillar/
[root@node1 pillar]# cat top.sls
base:
'*':
- vhost
[root@node1 pillar]# cat vhost.sls
vhost:
{% if 'node2' in grains['id'] %} -> 如果id中有node2字符, 使用www配置文件, 反之使用bbs.conf
- name: www
target: /usr/local/nginx/conf/vhost/www.conf
{% else %}
- name: bbs
target: /usr/local/nginx/conf/vhost/bbs.conf
{% endif %}
5. 生成虚拟主机配置文件
[root@node1 pillar]# cd /data/etc/salt/nginx/
[root@node1 nginx]# cat vhost.sls
include:
- nginx.install
{% for vhostname in pillar['vhost'] %}
{{ vhostname['name'] }}:
file.managed:
- name: {{ vhostname['target'] }}
- source: salt://nginx/files/vhost.conf
- target: {{ vhostname['target'] }}
- template: jinja
- defaults:
server_name: {{grains['fqdn']}}
log_name: {{vhostname['name']}}
- watch_in:
service: nginx
{% endfor %}
6. nginx主配置文件模版
vim files/nginx.conf
user {{ nginx_user }};
worker_processes {{grains['num_cpus']}};
error_log logs/nginx_error.log notice;
pid logs/nginx.pid;
worker_rlimit_nofile 65535;
events{
use epoll;
worker_connections 65535;
}
http{
include mime.types;
default_type application/octet-stream;
charset utf-8;
server_names_hash_bucket_size 128;
client_header_buffer_size 32k;
large_client_header_buffers 4 32k;
client_max_body_size 128m;
sendfile on;
tcp_nopush on;
keepalive_timeout 60;
tcp_nodelay on;
server_tokens off;
client_body_buffer_size 512k;
gzip on;
gzip_min_length 1k;
gzip_buffers 4 16k;
gzip_http_version 1.1;
gzip_comp_level 2;
gzip_types text/plain application/x-javascript text/css application/xml;
gzip_vary on;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for" "$host"' ;
include vhost/*.conf;
}
7. nginx服务管理脚本
[root@node1 nginx]# cat files/nginx
#!/bin/sh
# chkconfig: - 30 21
# description: http service.
# Source Function Library
. /etc/init.d/functions
# Nginx Settings
NGINX_SBIN="/usr/local/nginx/sbin/nginx"
NGINX_CONF="/usr/local/nginx/conf/nginx.conf"
NGINX_PID="/usr/local/nginx/logs/nginx.pid"
RETVAL=0
prog="Nginx"
start() {
echo -n $"Starting $prog: "
mkdir -p /dev/shm/nginx_temp
daemon $NGINX_SBIN -c $NGINX_CONF
RETVAL=$?
echo
return $RETVAL
}
stop() {
echo -n $"Stopping $prog: "
killproc -p $NGINX_PID $NGINX_SBIN -TERM
rm -rf /dev/shm/nginx_temp
RETVAL=$?
echo
return $RETVAL
}
reload(){
echo -n $"Reloading $prog: "
killproc -p $NGINX_PID $NGINX_SBIN -HUP
RETVAL=$?
echo
return $RETVAL
}
restart(){
stop
start
}
configtest(){
$NGINX_SBIN -c $NGINX_CONF -t
return 0
}
case "$1" in
start)
start
;;
stop)
stop
;;
reload)
reload
;;
restart)
restart
;;
configtest)
configtest
;;
*)
echo $"Usage: $0 {start|stop|reload|restart|configtest}"
RETVAL=1
esac
exit $RETVAL
8. nginx日志切割脚本
[root@node1 nginx]# cat files/nginx_log_cut.sh
#!/bin/bash
logs_path=/usr/local/nginx/logs
yesterday=`date -d "yesterday" +%F`
mkdir -p $logs_path/$yesterday
cd $logs_path
for nginx_logs in `ls *log` ;do
mv $nginx_logs ${yesterday}/${yesterday}-${nginx_logs}
kill -USR1 `cat /data/src/nginx/logs/nginx.pid`
done
9. 虚拟主机配置文件
[root@node1 nginx]# cat files/vhost.conf
server
{
listen 80;
server_name {{ server_name }}; -> 调用vhosts.sls中配置
index index.html index.htm ;
root html;
#location ~ .*\.(php|php5)?$
# {
# try_files $uri =404;
# fastcgi_pass unix:/tmp/php-cgi.sock;
# fastcgi_index index.php;
# include fcgi.conf;
# }
location /status {
stub_status on;
}
location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)$
{
expires 30d;
}
location ~ .*\.(js|css)?$
{
expires 1d;
}
access_log logs/{{ log_name }}-access.log main;
}
10. SaltStack install Nginx
[root@node1 nginx]# salt 'node2' state.highstate test=True -> 无报错既可
[root@node1 nginx]# salt 'node2' state.highstate
[root@node1 nginx]# curl 172.168.200.211 -I
HTTP/1.1 200 OK
Server: nginx
Date: Mon, 29 Aug 2016 08:28:25 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 612
Last-Modified: Mon, 29 Aug 2016 07:55:02 GMT
Connection: keep-alive
ETag: "57c3ea56-264"
Accept-Ranges: bytes
saltstack项目实战_安装mysql
1.1安装mysql
2.2查看salt-master、salt-minion配置文件
grep -Ev '^#|^$' /etc/salt/master
interface: 0.0.0.0
file_roots:
base:
- /data/etc/salt
prod:
- /data/etc/salt/prod
log_file: /data/logs/salt/master
grep -Ev '^#|^$' /etc/salt/minion
master: 172.168.200.210
id: node2
log_file: /data/logs/salt/minion
2.3 查看salt mysql目录结构
[root@node1 ~]# cd /data/etc/salt
[root@node1 salt]# tree mysql/
mysql/
|-- conf.sls -> mysql salt配置文件
|-- files
| |-- my.cnf -> mysql配置文件
| |-- mysql-5.6.32.tar.gz -> mysql软件包
| `-- mysqld -> mysql启动脚本
|-- init.sls -> salt初始化文件
`-- install.sls -> mysql install文件
2.4 编写 mysql sls文件
cat top.sls
base:
'*':
- mysql.init
[root@node1 salt]# cd mysql/
cat init.sls
include:
- mysql.install
- mysql.conf
cat install.sls
#mysql pkg.install
mysql_pkg:
pkg.installed:
- names:
- gcc
- gcc-c++
- autoconf
- automake
- openssl
- openssl-devel
- zlib
- zlib-devel
- ncurses-devel
- libtool-ltdl-devel
- cmake
#install source mysql
mysql_source:
file.managed:
- name: /usr/local/src/mysql-5.6.32.tar.gz
- unless: test -e /usr/local/src/mysql-5.6.32.tar.gz
- source: salt://mysql/files/mysql-5.6.32.tar.gz
#tar source mysql
extract_mysql:
cmd.run:
- cwd: /usr/local/src
- names:
- tar zxf mysql-5.6.32.tar.gz
- chown -R root:root /usr/local/src/mysql-5.6.32
- unless: tests -d /usr/local/src/mysql-5.6.32
- require:
- file: mysql_source
#useradd for mysql
mysql_user:
user.present:
- name: mysql
- uid: 1024
- createhome: False
- gid_from_name: True
- shell: /sbin/nologin
#mysql source install
mysql_commpile:
cmd.run:
- name: cd /usr/local/src/mysql-5.6.32 && cmake . -DCMAKE_INSTALL_PREFIX=/usr/local/mysql-5.6 -DMYSQL_DATADIR=/usr/local/mysql-5.6/data -DMYSQL_UNIX_ADDR=/usr/local/mysql-5.6/data/mysql.sock -DDEFAULT_CHARSET=utf8 -DDEFAULT_COLLATION=utf8_general_ci -DENABLED_LOCAL_INFILE=ON -DWITH_INNOBASE_STORAGE_ENGINE=1 -DWITH_FEDERATED_STORAGE_ENGINE=1 -DWITH-BLACKHOLE_STORAGE_ENGINE=1 -DWITHOUT_EXAMPLE_STORAGE_ENGINE=1 -DWITHOUT_PARTITION_STORAGE_ENGING=1 -DWITH_FAST_MUTEXES=1 -DWITH_ZLIB=bundled -DENABLED_LOCAL_INFIL=1 -DWITH_READLINE=1 -DWITH_EMBEDDED_SERVER=1 -DWITH_DEBUG=0 && make && make install && /usr/local/mysql-5.6/scripts/mysql_install_db --basedir=/usr/local/mysql-5.6/ --datadir=/usr/local/mysql-5.6/data/ --user=mysql
- require:
- cmd: extract_mysql
- pkg: mysql_pkg
- unless: test -d /usr/local/mysql-5.6
#mysql initialize
#mysql_initialize:
# cmd.run:
# - cwd: /usr/local/mysql-5.6/scripts/
# - names:
# - ./mysql_install_db --basedir=/usr/local/mysql-5.6/ --datadir=/usr/local/mysql-5.6/data/ --user=mysql
cat conf.sls
include:
- mysql.install
#mysql for config
mysql_cnf:
file.managed:
- name: /usr/local/mysql-5.6/my.cnf
- user: root
- mode: 755
- source: salt://mysql/files/my.cnf
#myql server
mysql_service:
file.managed:
- name: /etc/init.d/mysqld
- source: salt://mysql/files/mysqld
- user: root
- mode: 755
cmd.run:
- names:
- /sbin/chkconfig --add mysqld
- /sbin/chkconfig --level 35 mysqld on
- unless: /sbin/chkconfig --list mysqld
2.5 mysql配置文件
[root@node1 ~]# cd /data/etc/salt/mysql/files/
[root@node1 files]# cat my.cnf
[mysqld]
socket=/usr/local/mysql-5.6/data/mysql.sock
datadir=/usr/local/mysql-5.6/data
symbolic-links=0
log-error=/var/log/mysql_error.log
pid-file=/usr/local/mysql-5.6/data/mysqld.pid
slow-query-log-file = /var/log/mysql_slow_querys.log
skip-name-resolve
skip-grant-tables
2.6 mysql启动脚本添加下面路径
[root@node1 files]# cat mysqld
#!/bin/sh
basedir=/usr/local/mysql-5.6/
datadir=/usr/local/mysql-5.6/data/
2.7 模拟执行salt
1
salt 'node2' state.highstate test=True
salt 'node2' state.highstate