通过部署SaltStack,我们可以在成千万台服务器上做到批量执行命令,根据不同业务进行配置集中化管理、分发文件、采集服务器数据、操作系统基础及软件包管理等。
自动化运维工具——saltstack(基于python语言开发)具备配置管理、远程执行、监控等功能
saltstack一种基于C/S架构的服务器基础架构集中化管理平台,管理端称为master,客户端称为minion
具备配置管理、远程执行、监控等功能
采用C/S结构的方式来进行配置管理,运行速度快、部署轻松,几分钟内便可运行起来,而且服务器之间能够做到秒级通讯,容易批量管理上万台服务器,显著降低人力与运维成本
可结合轻量级的消息队列软件ZeroMQ与Python第三方模块(Pyzmq、PyCrypto、Pyjinjia2、 python-msgpack 和 PyYAML 等)构建
SaltStack是基础架构管理的一种自动化工具。部署轻松,在几分钟内可运行起来,扩展性好,很容易管理上万台服务器,速度够快。与服务器之间的交流,以毫秒为单位。
SaltStack提供了一个动态基础设施通信总线用于编排,远程执行、配置管理等等。
saltstack是运维人员提高工作效率、规范业务配置与操作的利器,是一个配置管理系统,能够维护预定义状态的远程节点。 是一个分布式远程执行系统,用来在远程节点上执行命令和查询数据
saltstack是基于python开发的一套C/S自动化运维工具,通信采用了zeromq消息队列的(pub/sub),ZeroMQ本身数据传输不支持加密,数据传输采用了AES(高级加密)保证安全性,认证采用了SSL方式
saltstack特点:
部署简单方便
主从集中化管理
配置简单、功能强大、扩展性强
主控端(master)和被控端(minion)基于证书认证,安全可靠
支持API自定义模块,可通过Python扩展
因为saltstack时基于python开发的C/S架构配置管理工具
底层使用ZeroMQ消息队列pub/sub方式通信
使用SSL证书签发的方式进行认证管理,传输采用AES加密
saltstack运行模式: (经过三种模式对比 得知一般都是采用Master/Minion来进行自动化运维管理的 Master/Minion的架构图:F:\linux操作系统笔记\docker\k8s\Ansible saltstack\自动化运维工具-saltstack
local:本地单点(不建议这么做,不然就没意义了)
Master/Minion:通过server/client的方式进行管理,效率很高
Salt SSH:通过SSH方式进行管理(类似于ansible),效率相对来说比较低
Master/Minion的架构图:F:\linux操作系统笔记\docker\k8s\Ansible saltstack\自动化运维工具-saltstack
minion:客户端安装组件,配置好之后会主动去连接master,从master端得到资源状态信息,并同步资源管理信息
master:服务端安装组件,运行在主服务器上,负责salt命令运行和资源的管理
saltstack如何实现批量操作?
master与minion之间通过Zero进行消息传递,使用ZeroMQ进行消息传递,以及Zero-MQ的发布订阅模式,连接方式包括tcp、ipc
master将要执行的操作或命令发送给minion,minion从消息总线上收到要进行的操作或要处理的命令,之后交给minion_handle_aes处理
之后minion_handle_aes发起一个本地线程去调用cmdmod去执行操作或命令,线程执行完毕后调用minion.return_pub方法,将执行结果通过消息总线返回给master
master接收到客户端返回的结果,调用master._handle_aes方法,将结果写进文件中
salt.client.LocalClient.cmd_cli通过轮询获取执行结果,将结果输出到终端
master&minion
在saltstack中有两种角色——master(主控端)和minion(被控端),master来管理minion
master和minion之间是怎么通信的
1.认证
F:\linux操作系统笔记\docker\k8s\Ansible saltstack\自动化运维工具-saltstack
2.连接
master启动后默认监听4505和4506两个端口 !!!
4505端口为saltstack的消息发布系统端口;4506端口为 saltstack minion与master 通信的端口
查看4505的端口状态我们会发现所有的minion在4505端口持续保持在ESTABLISHED状态
saltstack通信机制
SaltStack 采用 C/S模式,minion与master之间通过ZeroMQ消息队列通信,默认监听4505端口。
Salt Master运行的第二个网络服务就是ZeroMQ REP系统,默认监听4506端口。
安装&部署
192.168.244.141作为主控端master
192.168.244.128/129都是被控端minion
我们先分别在三台服务器上安装依赖包
#安装saltstack存储库和密钥
rpm --import https://repo.saltproject.io/py3/redhat/7/x86_64/3002/SALTSTACK-GPG-KEY.pub
#配置镜像源
touch /etc/yum.repos.d/salt.repo
curl -fsSL https://repo.saltproject.io/py3/redhat/7/x86_64/3002.repo | tee /etc/yum.repos.d/salt.repo
#清缓存
yum clean expire-cache
然后我们根据不同的角色来安装不同组件
#master
[root@master ~]# yum install salt-master -y salt-minion
#minion
[root@minion1 ~]# yum install salt-minion -y
[root@minion2 ~]# yum install salt-minion -y
安装完毕后开启并设置自启动
[root@master ~]#systemctl enable salt-master && systemctl start salt-master systemctl enable salt-minion && systemctl start salt-minion
[root@minion1 ~]#systemctl enable salt-minion && systemctl start salt-minion
[root@minion2 ~]#systemctl enable salt-minion && systemctl start salt-minion
1.配置 (配置文件件/etc/salt/master默认的配置就可以很好的工作,故无需过多的修改此配置文件)
修改master配置文件
master配置文件路径:vim /etc/salt/master
[root@master ~]# vim /etc/salt/master
[root@master ~]# grep -Ev "^$|#" /etc/salt/master
file_root:
base:
- /home/salt
pillar_roots:
base:
- /home/salt/pillar
order_masters: True
auto_accept: True
##file_roots:主目录
##pillar_roots:pillar组件主目录
##order_masters:允许开启多层master
##auto_accept:自动认证
[root@master ~]#systemctl restart salt-master
修改minion配置文件
minion配置文件路径:vim /etc/salt/minion
我只展示操作minion1的过程,minion2同理的
[root@minion1 ~]# vim /etc/salt/minion
[root@minion1 ~]# grep -Ev "^$|#" /etc/salt/minion
master: 192.168.244.141
id: 192.168.244.129
user: root
#重启服务
[root@minion1 ~]# systemctl restart salt-minion
看到4505和4506就说明成功
[root@master salt]# ss -anlt
# minion的识别ID,可以是IP,域名,或是可以通过DNS解析的字符串
id: 192.168.244.128
# salt运行的用户权限
user: root
# master的识别ID,可以是IP,域名,或是可以通过DNS解析的字符串
master : 192.168.244.141
# 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
2.认证并连接
minion在第一次启动时,会在/etc/salt/pki/minion/下自动生成minion.pem(private key)和 minion.pub(public key),然后将minion.pub发送给master
我们在master端来进行key认证,使用salt-key命令
/salt-key常用选项
-L //列出所有公钥信息
-a minion //接受指定minion等待认证的key
-A //接受所有minion等待认证的key
-r minion //拒绝指定minion等待认证的key
-R //拒绝所有minion等待认证的key
-f minion //显示指定key的指纹信息
-F //显示所有key的指纹信息
-d minion //删除指定minion的key
-D //删除所有minion的key
-y //自动回答yes
[root@master ~]# salt-key
Accepted Keys: #可以看到master已经检测到minion,且已认证key
192.168.244.128
192.168.244.129
Denied Keys:
Unaccepted Keys:
Rejected Keys:
#如果没有认证,手动输入认证一下
[root@master ~]# salt-key -a id
认证成功之后我们来验证一下
[root@master ~]# salt '192.168.244.128' test.ping
192.168.244.128:
True #返回结果表示成功
[root@master ~]# salt '192.168.244.129' test.ping
192.168.244.129:
True
查看当前证书情况
[root@master salt]# salt-key -L
Accepted Keys: //已经接受的证书
Denied Keys: //已经拒绝的证书
Unaccepted Keys: //还没有授权允许的
master
Rejected Keys: //拒绝的证书
saltstack进阶
Grains (静态)
Grains是saltstack的一个组件,存放在minion端
当minion启动时会把收集到的数据静态存放在Grains中,只有minion重启时才会进行数据的更新
1.应用场景
信息查询,用于查询minion的IP、OS等静态信息
在target(目标)中使用,匹配minion
在SLS中使用,配置管理模块
2.常用命令
列出minion1所有的静态数据key
salt 'minion1' grains.list
列出node1所有的静态数据key与value
salt 'minion1' grains.items
列出所有minion的OS
salt '*' grains.item os
对匹配到的minion执行操作
salt -G 'os:CentOS' cmd.run ‘echo haha’
3.Grains配置
我们可以在/etc/salt/grains中定义
[root@minion1 ~]#vim /etc/salt/grains
role: nginx
env: test
myname: edison
也可以在/etc/salt/minion中定义,但是要满足YAML格式
[root@minion1 ~]#vim /etc/salt/minion
grains:
role:
- nginx
env:
- test
myname:
- edison
4.自定义Grains
我们可以定制Grains来用于分组管理
写一个python脚本,在/srv/salt/下创建一个_grains的目录,然后在这个目录中创建.py文件
[root@minion1 ~]# mkdir /srv/salt/_grains
[root@minion1 ~]# vim /srv/salt/_grains/test.py
#!/usr/bin/env python
def my_grains():
grains = {}
grains['os'] = 'Redhat'
grains['name'] = 'Python'
return grains
然后在master端获取Grains
#列出多个
[root@master ~]# salt '192.168.244.129' grains.item role env myname
#列出一个
[root@master ~]# salt '192.168.244.129' grains.get myname
Grains在远程执行命令时很方便,可以按照Grains的一些指标来操作
比如把所有的web服务器的grains的role设置为nginx,这样我们就可以批量对nginx服务器进行操作
[root@minion1 ~]# vim /srv/salt/_grains/test.py
#!/usr/bin/env python
def my_grains():
grains = {}
grains['os'] = 'Redhat'
grains['role'] = 'nginx'
return grains
[root@master ~]# salt -G role:nginx cmd.run 'hostname'
[root@master ~]# salt -G os:Redhat cmd.run 'hostname'
5.优先级
系统自带——>grains文件写的——>minion配置文件写的——>自己写的
##每次修改数据都需要重启服务或刷新grains操作才会生效,这也印证了是静态数据
[root@master ~]# salt '*' saltutil.sync_grains ##用于刷新grains的数据
Pillar (动态)
Pillar和Grains不同,Pillar是在master上定义的,并且是针对minion而去定义的信息,不需要到minion上进行操作
像一些重要的数据密码都可以存储在pillar上,pillar存储的是动态信息
pillar是存储在master端,缓存在minion端,存储的是minion的一些配置信息
1.应用场景
比较敏感的数据,比如密码,key等
特殊数据到特定Minion上
动态的内容
2.常用命令
查看minion的pillar信息
salt '*' pillar.items
查看某个pillar值
salt '*' pillar.item <key> #只能看到顶级的
salt '*' pillar.get <key>:<key> #可以取到更小粒度的
刷新pillar
salt '*' saltutil.refresh_pillar
3.Pillar配置
Pillar需要一个pillar_roots来维护pillar的配置
• 默认pillar_roots为/srv/pillar !!!!!!!!!!
• pillar_roots在Master配置文件中定义
先在master端修改配置文件,打开pillar组件目录
[root@master ~]# vim /etc/salt/master
//找到如下内容,去掉注释
pillar_roots:
base:
- /srv/pillar
自定义配置文件
[root@master ~]# vim /srv/pillar/test.sls
conf: /etc/test.conf | myname: tpp
入口文件
[root@master ~]# vim /srv/pillar/top.sls
base:
'slaver.test.com':
- test
配置好后重启
[root@master ~]# systemctl restart salt-master
更改完配置文件后,我们可以通过·刷新pillar配置来获取新的动态
[root@master ~]# salt '*' saltutil.refresh_pillar
验证
[root@master ~]# salt 'slaver.test.com' pillar.items
[root@master ~]# salt 'slaver.test.com' pillar.item conf
[root@master ~]# salt 'slaver.test.com' pillar.item mynam
pillar同样可以用来作为salt的匹配对象
[root@master ~]# salt -I 'conf:/etc/123.conf' test.ping
[root@master ~]# salt -I 'conf:/etc/123.conf' cmd.run 'w'
4.Pillar案例
案例一:通过yum方式安装apache
配置文件
[root@master ~]# vim /etc/salt/master //打开如下内容的注释,添加主目录
file_roots:
base:
- /srv/salt
pillar_roots:
base:
- /srv/pillar
创建目录以及编写入口文件
[root@master ~]# mkdir /srv/salt
[root@master ~]# vim /srv/salt/top.sls
base:
'slaver.test.com': #如果换成*,表示在所有minion执行apache模块
- apache
写pillar文件
[root@master ~]# vim /srv/salt/apache.sls
apache-service: #自定义标签名
pkg.installed: #函数以及方法
- name: #如果只有一个服务,写成-name: httpd 一行即可
- httpd
- httpd-devel
service.running:
- name: httpd
- enable: True
执行命令
[root@master ~]# salt 'slaver.test.com' state.highstate
案例二:目录管理
编辑pillar文件
[root@master ~]# vim /srv/salt/editdir.sls
edit-dir:
file.recurse:
- name: /tmp/testdir
- source: salt://test1
- user: root
- file_mode: 644
- dir_mode: 755
- mkdir: True
- clean: True
#clean: True master处删除文件或目录,目标也会跟着删除,否则不会删除。可以默认设置为 False
新建测试目录
[root@master ~]# mkdir -p /srv/salt/test1
[root@master ~]# vim /srv/salt/test1/1.txt
hello world
验证
[root@master ~]# salt 'slaver.test.com' state.sls editdir
在master新建 my_dir 目录以及 test_dir.add 文件,删除 1.txt 文件
[root@master ~]# mkdir /srv/salt/test1/my_dir
[root@master ~]# touch /srv/salt/test1/my_dir/2.txt
[root@master ~]# touch /srv/salt/test1/testdir.add
[root@master ~]# rm -rf /srv/salt/test1/1.txt
[root@master ~]# salt 'slaver.test.com' state.sls editdir
成功在minion /tmp/testdir/ 目录下创建了my_dir目录和test_dir.add文件,并删除了1.txt文件
值得注意的是要成功创建 my_dir 目录,前提是 master端的my_dir 目录下要有文件,比如这里的2.txt 文件,如若没有,客户端是不会创建 my_dir 目录的
案例三:远程执行
前面提到的远程执行命令 test.ping、cmd.run,直接敲在命令行不太规范和优雅,我们可以通过pillar实现远程执行命令
编写pillar文件
[root@master ~]# vim /srv/salt/cmdtest.sls
cmd-test:
cmd.run:
- onlyif: test -f /tmp/123.txt
- names:
- touch /tmp/cmdtest.txt
- mkdir /tmp/cmdtest
- user: root
#onlyif条件:如果/tmp/123.txt存在,执行后面的命令;unless与之相反
unless条件
• 当unless条件不满足时,需要执行令
onlyif条件
• 当onlyif条件满足时,需要执行令
执行命令
[root@master ~]# salt 'slaver.test.com' state.sls cmdtest
案例四:任务计划cron
编写pillar文件
[root@master ~]# vim /srv/salt/crontest.sls
cron-test:
cron.present: #cron.absent是删除cron
- name: /bin/touch /tmp/111.txt #创建111.txt
- user: root
- minute: '*'
- hour: 20
- daymonth: 1-10
- month: '3,5'
- dayweek: '*'
# *需要用单引号引起来。当然我们还可以使用 file.managed 模块来管理 cron,因为系统的 cron都是以配置文件的形式存在的
执行
[root@master ~]# salt "slaver.test.com" state.sls crontest
ZeroMQ介绍
ZeroMQ是由一套组件组成,内封装的有网络通信,消息队列,线程调度等功能并向上层提供了简洁的API接口,应用程序通过加载库文件,调用API函数来实现高性能网络通信。
ZeroMQ的常用的两种模型
请求回应模型
由请求端发起请求,然后等待回应端应答。一个请求必须对应一个回应,从请求端的角度来看是发-收配对,从回应端的角度是收-发对。跟一对一结对模型的区别在于请求端可以是1~N个。该模型主要用于远程调用及任务分配等。Echo服务就是这种经典模型的应用。
发布订阅模型(这也时saltstack的主要的模型)
发布端单向分发数据,且不关心是否把全部信息发送给订阅端。如果发布端开始发布信息时,订阅端尚未连接上来,则这些信息会被直接丢弃。订阅端未连接导致信息丢失的问题,可以通过与请求回应模型组合来解决。订阅端只负责接收,而不能反馈,且在订阅端消费速度慢于发布端的情况下,会在订阅端堆积数据。该模型主要用于数据分发。天气预报、微博明星粉丝可以应用这种经典模型。
saltstack服务架构
在saltstack架构中服务器端叫Master,客户端叫Minion。
在Master和Minion端都是以守护进程的模式运行,一直监听配置文件里面定义的ret_port(接受minion请求)和publish_port(发布消息)的端口。
当Minion运行时会自动连接到配置文件里面定义的Master地址ret_port端口进行连接认证。
saltstack除了传统的C/S架构外,其实还有一种叫做masterless的架构,其不需要单独安装一台 master 服务器,只需要在每台机器上安装 Minion端,然后采用本机只负责对本机的配置管理机制服务的模式。
saltstack四大功能与四大运行方式
saltstack四大功能,分别是:
远程执行 (批量执行命令)在master上执行命令时,会在所有的minion上执行。
配置管理/状态管理 (描述想到达到的状态,saltstack就会去执行)
云管理(cloud) 用于管理云主机
事件驱动 被动执行的,当达到某个值会自动触发
saltstack可以通过远程执行实现批量管理,并且通过描述状态来达到某些功能的目的。
saltstack四大运行方式:
local本地运行 (masterless模式)
master/minion传统方式 这是saltstack的主要模式
syndic 分布式
salt ssh (agentless模式)
saltstack组件介绍
组件 功能
salt master 用于将命令和配置发送到在受管系统上运行的Salt minion
Salt Minions 从Salt master接收命令和配置
Execution Modules 从命令行针对一个或多个受管系统执行的临时命令。应用场景,例如:1. 实时监控,状态和库存,2. 一次性命令和脚本,3. 部署关键更新
Formulas (States) 系统配置的声明性或命令式表示
Grains Grains是有关底层受管系统的静态信息,包括操作系统,内存和许多其他系统属性。
Pillar 用户定义的变量。这些安全变量被定义并存储在Salt Master中,然后使用目标“分配”给一个或多个Minion。
https://www.jianshu.com/p/9fc253c35189
Salt的核心功能
1)使命令发送到远程系统是并行的而不是串行的
2)使用安全加密的协议
3)使用最小最快的网络载荷
4)提供简单的编程接口
Salt同样引入了更加细致化的领域控制系统来远程执行,使得系统成为目标不止可以通过主机名,还可以通过系统属性
在server4上查看对端口
[root@server4 ~]# yum install -y losf
lsof -i :端口
远程控制测试一下:在server4上查看server5的df挂载信息(远程发送指令):salt server5 cmd. run df
远程执行
远程执行shell命令
Salt命令由三个主要部分构成:
salt '<target>' <function> [arguments]
target: 指定哪些minion, 默认的规则是使用glob匹配minion id
#salt '*' test.ping
Targets也可以使用正则表达式:
# salt -E 'server[5-6]' test.ping
Targets也可以指定列表:
# salt -L 'server5,server6' test.ping
funcation是module提供的功能,Salt内置了大量有效的functions.
# salt '*' cmd.run 'uname -a' cmd.ru远程执行参数后面跟命令,使用单引号
arguments通过空格来界定参数:
# salt 'server2' sys.doc pkg #查看模块文档
# salt 'server2' pkg.install httpd 远程安装httpd
# salt 'server2' pkg.remove httpd 远程卸载httpd
salt内置的执行模块列表:
网站地址:http://docs.saltstack.cn/ref/modules/all/index.html
编写远程执行模块
创建模块目录固定路径:
[root@server4 ~]# mkdir /srv/salt/_modules
编写模块文件:
[root@server4 ~]# vim /srv/salt/_modules/mydisk.py
def df():
return __salt__['cmd.run']('df -h')
同步模块:
[root@server4 _modules]# salt server5 saltutil.sync_modules
server5:
- modules.mydisk
模块同步之后在minion端查看
tree minion/
创建一个sls文件
vim /srv/salt/apache.sls
httpd: # ID声明 也是软件包名称
pkg: # 状态声明
- installed # 函数声明
指定主机执行:
salt server5 state.sls apache 文件后缀不用添加
查看目录结构apache.sls文件已经被推送到位:tree minion/
安装多个软件包
[root@server4 salt]# vim apache.sls
[root@server4 salt]# cat apache.sls
web:
pkg.installed:
- pkgs:
- httpd
- php
salt-stack自动化工具只会达到你想要的的状态
比如上面安装两个软件包,php在安装过程中会有依懒性,那么在安装的过程中为了达到安装成功会自动解决php所需要软件包,注意:但当在卸载php时,就只是卸载php这个软件,其他的依赖软件包则不会卸载。也就是不会回滚到原始状态。
编写一个远程执行的源码包安装.sls脚本
[root@server4 salt]# mkdir nginx
[root@server4 salt]# cd nginx/
[root@server4 nginx]# touch init.sls
[root@server4 nginx]# mkdir files
[root@server4 nginx]# ll
total 0
drwxr-xr-x 2 root root 6 Jun 9 07:58 files
-rw-r--r-- 1 root root 0 Jun 9 07:58 init.sls
[root@server4 nginx]# pwd
/srv/salt/nginx
[root@server4 nginx]# cd files/
[root@server4 files]# ls
nginx-1.18.0.tar.gz
nginx-install: 声明:每个声明下不能重复使用模块
pkg.installed: 安装模块
- pkgs: 指定软件
- openssl-devel
- pcre-devel
- gcc
file.managed: 推送软件
- name: /mnt/nginx-1.18.0.tar.gz 指定软件推送的目的路径
- source: salt://nginx/files/nginx-1.18.0.tar.gz 软件获取路径
cmd.run: 命令运行模块
&&为命令分割符
- name: cd /mnt/ 进入目录 && tar zxf nginx-1.18.0.tar.gz 解压压缩包 && cd nginx-1.18.0 进入解压后的目录 && sed -i 's/CFLAGS="$CFLAGS -g"/#CFLAGS="$CFLAGS -g"/g' auto/cc/gcc 关闭debug && ./configure --prefix=/usr/local/nginx --with-http_ssl_module 预编译 &> /dev/null 过程导入垃圾箱 && make 编译 &> /dev/null && make install 编译安装 &> /dev/null
- creates: /usr/local/nginx 检测/usr/local/nginx此目录;是否安装过nginx服务,没有判断条件那么每安装一次都编译安装覆盖之前的文件
启动nginx服务脚本
cd /srv/salt/nginx/
[root@server4 nginx]# vim init.sls
开始编写脚本:
nginx-install:
pkg.installed:
- pkgs:
- openssl-devel
- pcre-devel
- gcc
file.managed:
- name: /mnt/nginx-1.18.0.tar.gz
- source: salt://nginx/files/nginx-1.18.0.tar.gz
cmd.run:
- name: cd /mnt/ && tar zxf nginx-1.18.0.tar.gz && cd nginx-1.18.0 && sed -i 's/CFLAGS="$CFLAGS -g"/#CFLAGS="$CFLAGS -g"/g' auto/cc/gcc && ./configure --prefix=/usr/local/nginx --with-http_ssl_module &> /dev/null && make &> /dev/null && make install &> /dev/null
- creates: /usr/local/nginx
/usr/local/nginx/conf/nginx.conf: 声明:nginx配置文件
file.managed:
- source: salt://nginx/files/nginx.conf 文件调取路径
nginx-service: systemd服务启动脚本调取位置
file.managed:
- name: /usr/lib/systemd/system/nginx.service 指定推送路径
- source: salt://nginx/files/nginx.service 提取路径
service.running: nginx服务运行
- name: nginx 服务名称
- enable: True 开机启动
- reload: True 刷新(当watch监测到配置文件有改动)
- watch: 监测
- file: /usr/local/nginx/conf/nginx.conf 指定监测文件
把nginx配置文件和nginx启动脚本放到/srv/salt/nginx/files下
代码获取方式 https://www.nginx.com/resources/wiki/start/topics/examples/systemd/
[root@server4 files]# vim nginx.service
[Unit]
Description=The NGINX HTTP and reverse proxy server
After=syslog.target network-online.target remote-fs.target nss-lookup.target
Wants=network-online.target
[Service]
Type=forking
PIDFile=//usr/local/nginx/logs/nginx.pid 注意路径
ExecStartPre=/usr/local/nginx/sbin/nginx -t 注意路径
ExecStart=/usr/local/nginx/sbin/nginx 注意路径
ExecReload=/usr/local/nginx/sbin/nginx -s reload 注意路径
ExecStop=/bin/kill -s QUIT $MAINPID
PrivateTmp=true
[Install]
WantedBy=multi-user.target
[root@server4 nginx]# salt server6 state.sls nginx 给server6推送
案例1 系统初始化
配置所有机器的DNS为 202.101.224.68
修改所有机器的yum 源为本机器网络yum
修改history 能显示命令执行时间
开启路由转发功能 net.ipv4.ip_forward=1
添加用户zhangsan
为用户zhuangsan 设置默认密码 zhangsan
要求zhangsan 在第一次登录是的时候修改密码
[root@sm base]# vim top.sls
base:
'*':
- init.dns
- init.yum
- init.adduser
- init.history
- init.ip_forward
[root@sm base]# mkdir init
[root@sm base]# cd init/
[root@sm init]# vim dns.sls
add_dns:
file.managed:
- name: /etc/resolv.conf
- source: salt://file/dns.conf
- user: root
- group: root
- mode: 644
- template: jinja
- defaults:
DNS_IP: 202.101.224.68
[root@sm init]# vim yum.sls
create_yum:
file.managed:
- name: /etc/yum.repos.d/test.repo
- source: salt://file/yum.repo
- user: root
- group: root
- mode: 644
unless条件
• 当unless条件不满足时,需要执行令
onlyif条件
• 当onlyif条件满足时,需要执行令
[root@sm init]# vim adduser.sls
useradd zhangsan:
cmd.run:
- unless: id zhangsan
echo '123456' | passwd --stdin zhangsan:
cmd.run:
- onlyif: id zhangsan
chage -d 0 zhangsan:
cmd.run:
- onlyif: id zhangsan
[root@sm init]# vim history.sls
history:
file.append:
- name: /etc/profile
- text:
- export HISTTIMEFORMAT='%F %T'
[root@sm init]# cat ip_forward.sls
alter_ip_forward:
sysctl.present:
- name: net.ipv4.ip_forward
- value: 1
[root@sm init]# cat ip_forward.sls
alter_ip_forward:
sysctl.present:
- name: net.ipv4.ip_forward
- value: 1
[root@sm init]# mkdir file
[root@sm init]# cd file/
[root@sm file]# vim dns.conf
nameserver {{DNS_IP}}
[root@sm file]# vim yum.repo
[test]
name=test
baseurl=http://192.168.4.254/rhel7
gpgcheck=0
state.highstate会读取所有环境的top.sls文件,并且执行top.sls文件内容里面定义的sls文件,不在top.sls文件里面记录的sls则不会被执行;
state.sls也可以指定读取哪个环境 使用 saltenv = 读取环境
test = True 测试执行 不真正执行
# salt '*' state.highstate saltenv=base test=True
# salt '*' state.highstate saltenv=base
案例2 部署httpd web 服务器
在实验的 web1 web2 上自动安装httpd软件包
更改httpd监听端口为8080
启动httpd 服务
pkg模块
• pkg模块可以实现软件包管理
• 管理的软件包包括红帽RPM包和Ubuntu的deb包等
• 主要的方法有:
– pkg.installed:安装软件包
– pkg.latest:保持软件包为最新版本
– pkg.remove:卸载软件包
– pkg.purge:下载软件包,删除配置文件
require条件
• 只有httpd安装了才分发配置文件
service模块
• 软件部署完毕后,需要确保服务处于运行状态,并且能够实现开机自启,这就用到了service模块
– service.running:确保服务处于运行状态
– service.enabled:开机自启
– service.disabled:开机不启动
– service.dead:确保服务处于未运行状态
使用watch
• 服务如果能够正常启动,需要确保存在配置文件,设置如果配置文件存在,才启动服务
[root@sm ~]# cd /srv/prod/
[root@sm prod]# vim top.sls
prod:
'E@web[0-9]':
- install_httpd
[root@sm prod]# vim install_httpd.sls
httpd_pkg_installed:
pkg.installed:
- name: httpd
alter_httpd:
cmd.run:
- name: sed -i '/Listen 80/s/80/8080/' /etc/httpd/conf/httpd.conf
- unless: sed -n '/Listen 80$/p' /etc/httpd/conf/httpd.conf
- require:
- pkg: httpd_pkg_installed
running_httpd:
service.running:
- name: httpd
- enable: true
- restart: true
- watch:
- cmd: alter_httpd
# salt '*' state.highstate saltenv=prod test=True
# salt '*' state.highstate saltenv=prod
//这里因为配置文件中只需要更改一行 我使用的是sed 更改
//也可以使用 file.managed 方法 将master的配置文件分发到客户端
案例3 部署nginx 源码包
[root@sm ~]# cd /srv/dev/
[root@sm dev]# vim top.sls
dev:
'L@db1,db2':
- nginx_install
[root@sm dev]# mkdir nginx_install
[root@sm dev]# cd nginx_install
[root@sm nginx_install]# vim init.sls
include:
- .initpkg
- .install
- .nginx_init
[root@sm nginx_install]# vim initpkg.sls
init_pkg_install:
pkg.installed:
- names:
- gcc
- gcc-c++
- make
- autoconf
- openssl-devel
- pcre-devel
[root@sm nginx_install]# vim install.sls
nginx_src_install:
file.managed:
- name: /usr/local/src/nginx-1.9.12.tar.gz
- source: salt://nginx_install/files/nginx-1.9.12.tar.gz
- user: root
- group: root
- mode: 644
cmd.script:
- source: salt://nginx_install/files/build.sh
- cwd: /usr/local/src
- user: root
- unless: test -d /usr/local/nginx
- require:
- file: nginx_src_install
- pkg: init_pkg_install
[root@sm nginx_install]# vim nginx_init.sls
nginx_init:
file.managed:
- name: /usr/lib/systemd/system/nginx.service
- source: salt://nginx_install/files/nginx.service
- user: root
- group: root
- mode: 644
nginx_service:
service.running:
- name: nginx
- enable: true
- restart: true
[root@sm nginx_install]# mkdir files
[root@sm nginx_install]# cd files
[root@sm files ]# vim build.sh
#!/bin/bash
useradd -s /sbin/nologin nginx
tar xzf nginx-1.9.12.tar.gz
cd nginx-1.9.12
./configure --prefix=/usr/local/nginx --user=nginx --group=nginx
make
make install
[root@sm files ]# ls
build.sh // 源码安装脚本
nginx-1.9.12.tar.gz // nginx 源码包
nginx.service // nginx systemctl 系统启动文件
[root@sm files ]# vim nginx.service
[Unit]
Description=nginx - high performance web server
Documentation=http://nginx.org/en/docs/
After=network.target remote-fs.target nss-lookup.target
[Service]
Type=forking
PIDFile=/usr/local/nginx/logs/nginx.pid
ExecStartPre=/usr/local/nginx/sbin/nginx -t -c /usr/local/nginx/conf/nginx.conf
ExecStart=/usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf
ExecReload=/usr/local/nginx/sbin/nginx -s reload
ExecStop=/usr/local/nginx/sbin/nginx -s quit
PrivateTmp=true
[Install]
WantedBy=multi-user.target
# salt '*' state.highstate saltenv=dev test=True
# salt '*' state.highstate saltenv=dev