• Saltstack是基于python开发的一套C/S架构配置管理工具
• 使用SSL证书签方的方式进行认证管理
• 底层使用ZeroMQ消息队列pub/sub方式通信
– 号称世界上最快的消息队列ZeroMQ能快速在成千上万台主机上进行各种操作
– 采用RSA Key方式确认身
主要功能
• Saltstack最主要的两个功能是:配置管理与远程执行
• Saltstack不只是一个配置管理工具,还是一个云计算与数据中心架构编排的利器
• Saltstack已经支持Docker相关模块
• 在友好地支持各大云平台之后,配合Saltstack的Mine实时发现功能可以实现各种云平台业务的自动扩展
Saltstack架构
• Saltstack基于C/S架构
– 服务器端称作Master
– 客户端称作Minion
• 可以实现传统处理方式,即:客户端发送请求给服务器,服务器收到请求后处理请求,再将结果返回
• 也可以使用消息队列中的发布与订阅(pub/sub)服务模式
Saltstack工作机制
• Master和Minion都以守护进程的方式运行
• Master监听配置文件里定义的ret_port(接收minion请求),和publish_port(发布消息)的端口
• 当Minion运行时,它会自动连接到配置文件里定义的Master地址ret_port端口进行连接认证
• 当Master和Minion可以正常通信后,就可以进行各种各样的配置管理工作了
server1 | 172.25.81.1 | salt-master |
---|---|---|
server2 | 172.25.81.2 | salt-minion |
server3 | 172.25.81.3 | salt-minion |
修改yum源安装:(所有主机都需要配置)
[root@server1 ~]# vim /etc/yum.repos.d/yum.repo
[dvd]
name=rhel7.3
baseurl=http://172.25.81.250/rhel7.3
gpgcheck=0[salt]
name=salt2018
baseurl=http://172.25.81.250/salt
gpgcheck=0
注意所挂载软件包文件夹的权限问题
master端:
[root@server1 ~]# yum install salt-master -y
[root@server1 ~]# yum install salt-minion -y
[root@server1 ~]# vim /etc/salt/minion
master: 172.25.81.1
[root@server1 ~]# systemctl start salt-master
[root@server1 ~]# systemctl start salt-minion
其余minion端同时安装salt-minion并修改配置文件开启服务:
[root@server2 ~]# vim /etc/salt/minion
master: 172.25.81.1
[root@server2 ~]# systemctl start salt-minion
[root@server3 ~]# vim /etc/salt/minion
master: 172.25.81.1
[root@server3 ~]# systemctl start salt-minion
Master与Minion互信:
• Minion上线后先与Master端联系,把自己的pubkey发过去
• Master接受Minion的公钥后,互信建立完成
[root@server1 ~]# salt-key -L ##查看密钥信息
[root@server1 ~]# salt-key -A ##接受密钥,完成互信
密钥管理:
说明:-a :accept ,-A:accept-all,-d:delete,-D:delete-all。可以使用 salt-key 命令查看到已经签名的客户端。此时我们在客户端的 /etc/salt/pki/minion 目录下面会多出一个minion_master.pub 文件。
测试所有主机连通性:
[root@server1 ~]# salt '*' test.ping
在主机上执行任意命令 测试
lsof命令查看可以看到master 端有长链接
注意:minion端与master端建立通信之后 在minion端的 /etc/salt/pki/minion 目录下面会多出一个minion_master.pub 文件
里面的内容与master端的 /etc/salt/pki/ 目录下的master.pub(公钥)一致
[root@server1 ~]# yum install -y python-setproctitle.x86_64
[root@server1 ~]# vim /etc/salt/master
file_roots:
base:
- /srv/salt ##master 的默认根目录[root@server1 ~]# systemctl restart salt-master
[root@server1 ~]# mkdir /srv/salt ##创建根目录
SLS(代表SaLt State文件)是Salt State系统的核心。SLS描述了系统的目标状态,由格式简单的数据构成。这经常被称作配置管理。
<1>安装httpd服务
首先查看server2没有安装该服务:
[root@server1 ~]# cd /srv/salt/
[root@server1 salt]# mkdir httpd
[root@server1 salt]# cd httpd/
[root@server1 httpd]# vim install.sls
httpd:
pkg.installed:
- pkgs:
- httpd
- php
- php-mysql[root@server1 httpd]# salt server2 state.sls httpd.install ##推送给minion主机server2端安装httpd服务
在server2查看,http和php是否下载成功
将minion端httpd的配置文件放到master的/srv/salt/httpd/files下
[root@server1 ~]# mkdir /srv/salt/httpd/files
<2>配置httpd服务
[root@server1 ~]# cd /srv/salt/httpd/
[root@server1 httpd]# vim service.sls
include:
- httpd.install/etc/httpd/conf/httpd.conf:
file.managed:
- source: salt://httpd/files/httpd.confhttp-service:
service.running:
- name: httpd
- enable: False
- reload: True
watch:
- file: /etc/httpd/conf/httpd.conf
[root@server1 httpd]# salt server2 state.sls httpd.service
minion端检测服务开启状态:
[root@server1 ~]# cd /srv/salt/
[root@server1 salt]# mkdir nginx
[root@server1 salt]# cd nginx/
[root@server1 nginx]# mkdir files
源码编译安装nginx
[root@server1 nginx]# vim /srv/salt/nginx/install.sls
{% set nginx_ver = '1.15.7' %}
nginx-install:
pkg.installed:
- pkgs:
- pcre-devel
- zlib-devel
- gcc
- makefile.managed:
- name: /mnt/nginx-{{ nginx_ver }}.tar.gz
- source: salt://nginx/files/nginx-{{ nginx_ver }}.tar.gzcmd.run:
- name: cd /mnt && tar zxf nginx-{{ nginx_ver }}.tar.gz && cd nginx-{{ nginx_ver }} && sed -i 's/CFLAGS="$CFLAGS -g"/#CFLAGS="$CFLAGS -g"/g' auto/cc/gcc && ./configure --prefix=/usr/local/nginx &> /dev/null && make &> /dev/null && make install &> /dev/null && cd .. && rm -fr nginx-{{ nginx_ver }}
- creates: /usr/local/nginx
创建nginx启动脚本
[root@server1 nginx]# vim /srv/salt/nginx/files/nginx.service
[Unit]
Description=The NGINX HTTP Server
After=syslog.target 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
ExecStart=/usr/local/nginx/sbin/nginx
ExecReload=/usr/local/nginx/sbin/nginx -s reload
ExecStop=/usr/bin/kill -s QUIT $MAINPID
PrivateTmp=true[Install]
WantedBy=multi-user.target
配置nginx服务
拷贝nginx的配置文件放到master的/srv/salt/nginx/files下
[root@server1 nginx]# vim /srv/salt/nginx/service.sls
include:
- nginx.install/usr/local/nginx/conf/nginx.conf:
file.managed:
- source: salt://nginx/files/nginx.conf
nginx-service:
file.managed:
- name: /etc/systemd/system/nginx.service
- source: salt://nginx/files/nginx.serviceservice.running:
- name: nginx
- reload: True
- watch:
- file: /usr/local/nginx/conf/nginx.conf
[root@server1 nginx]# salt server3 state.sls nginx.service
server3查看nginx是否开启
添加nginx用户
[root@server1 ~]# vim /srv/salt/nginx/files/nginx.conf
user nginx;
worker_processes auto;
[root@server1 ~]# vim /srv/salt/nginx/user.sls
nginx:
user.present:
- uid: 1000
- shell: /sbin/nologin
[root@server1 ~]# vim /srv/salt/nginx/service.sls
include:
- nginx.install
- nginx.user/usr/local/nginx/conf/nginx.conf:
file.managed:
- source: salt://nginx/files/nginx.conf
nginx-service:
file.managed:
- name: /etc/systemd/system/nginx.service
- source: salt://nginx/files/nginx.serviceservice.running:
- name: nginx
- reload: True
- watch:
- file: /usr/local/nginx/conf/nginx.conf
[root@server1 ~]# salt server3 state.sls nginx.service
在minion端查看用户:
top.sls
top.sls 是配置管理的入口文件,一切都是从这里开始,在master 主机上,默认存放在/srv/salt/目录.
top.sls 默认从 base 标签开始解析执行,下一级是操作的目标,可以通过正则,grain模块,或分组名,来进行匹配,再下一级是要执行的state文件,不包换扩展名。
[root@server1 ~]# vim /srv/salt/top.sls
base:
'server2':
- httpd.service'server3':
- nginx.service
主控端对目标主机(targeted minions)发出指令运行state.highstatem模块,目标主机首先会对top.sls下载,解析,然后按照top.sls内匹配规则内的定义的模块将被下载,解析,执行,然后结果反馈给 master.
最后可以在终端中执行命令来查看结果:
[root@server1 ~]# cd /srv/salt/
[root@server1 salt]# salt server[2,3] state.highstate
Grains
Grains是saltstack记录minion的一 些静态信息组件,可以简单的理解为grains里面记录着每台minion的一些常用的属性,比如cpu、内存、磁盘、网络信息等,可以通过 grains.items查看某台minion的grains所有信息,minion的grains信息是minion启动的时候采集汇报给master 的。
grains会在minion进程启动时进行加载,并缓存在内存中。这样salt-minion进程无需每次操作都要重新检索系统来获取grain,提升了minion性能。
grains的定义:
grains优先级(item名称相同的情况下): 1. 系统自带 2. grains文件写的 3. minion配置文件写的 4. 自己写的脚本
<1>通过minion配置文件定义grains:(minion端操作)
以minion主机server2为例
在配置文件中有默认的注释行,修改好配置文件 /etc/salt/minion重启minion服务
[root@server2 ~]# vim /etc/salt/minion
grains:
roles:
- httpd[root@server2 ~]# systemctl restart salt-minion
在master上通过salt 'server2' grains.item roles就可查看刚才定义的grains值。
<2>通过grains文件来设置并定义grains信息: (生产环境使用)(minion端操作)
以minion主机server3为例
将自定义的静态grain存在一个grain文件中(/etc/salt/grains),这样grains独立存储,易于在本地查找。能够通过执行模块进行修改。
[root@server3 ~]# vim /etc/salt/grains
roles:
nginx[root@server3 ~]# systemctl restart salt-minion ##重启minion服务
修改/etc/salt/grains不重启服务的方法,master端刷新命令如下(备注:方式一和方式二修改配置文件,通过此命令都可以不用重启服务)
salt '*' saltutil.sync_grains
<3>通过python脚本定义 (master端操作)
grains脚本目录,必须是base下创建_grains目录(如:/srv/salt/_grains)
[root@server1 ~]# mkdir /srv/salt/_grains
[root@server1 ~]# vim /srv/salt/_grains/my_grains.py ##在/srv/salt/_grains目录下创建一个python脚本
#!/usr/bin/env python
def my_grains():
grains = {}
grains['roles'] = 'httpd'
grains['hello'] = 'linux'
return grains
通过master同步脚本文件至minion端:
[root@server1 ~]# salt server3 saltutil.sync_grains
文件放在minion主机的/var/cache/salt/minion/extmods/grains目录下
在server1测试并查看:
可以看出虽然在脚本文件中定义了grains['roles'] = 'httpd',但是查看到的roles的结果仍然是nginx,这是因为之前的测试在server3上通过grains文件来设置roles是nginx. 所以grains文件写的信息优先级 高于自己写的脚本
将grains写入top FILE中:
[root@server1 ~]# vim /srv/salt/top.sls
base:
'roles:httpd':
- match: grain
- httpd.service'roles:nginx':
- match: grain
- nginx.service
然后在主节点进行推送
[root@server1 ~]# salt -G 'roles:httpd' test.ping ##对所有roles为httpd的主机进行连接检测
Grains很强大,但是其缺点是这些数据相对来说都是静态数据。pillar数据存储在master上。指定的minion只能看到自己pillar数据,其他的minion看不到任何pillar数据,这一点与状态文件正好相反。所有通过认证的minion都可以获取状态文件,但是每隔minion却都有自己的一套pillar数据,而且每台minion的pillar都进行了加密,所以很适用于敏感数据。
Pillar是数据管理中心,主要作用就是存储和定义配置管理中需要的一些数据,比如软件版本号、用户密码等信息,格式与grains类似,都是YAML格式。
Pillar也是Salt用来分发全局变量到所有minions的一个接口。安全起见,有些数据是不可以共享出来的,需要指定。比如高度敏感的数据:通过pillar传输的数据会保证只向选定的minions展现,这使得pillar可以作为Salt中管理安全信息的引擎,比如加密的key和密码。
通过master配置文件定义Pillar相关参数:
[root@server1 ~]# vim /etc/salt/master
pillar_roots:
base:
- /srv/pillar[root@server1 ~]# systemctl restart salt-master
[root@server1 ~]# mkdir /srv/pillar
[root@server1 ~]# vim /srv/pillar/web.sls
{% if grains['fqdn'] == 'server2' %}
webserver: httpd
{% elif grains['fqdn'] == 'server3' %}
webserver: nginx
{% endif %}
[root@server1 ~]# vim /srv/pillar/top.sls ##建立top file指定minion到pillar数据文件
base:
'*':
- web
[root@server1 ~]# salt '*' saltutil.refresh_pillar ##刷新minion的pillar数据
[root@server1 ~]# salt '*' pillar.items ##查看定义的item
[root@server1 ~]# salt -I 'webserver:nginx' test.ping 目标选择:选择pillar模块中webserver为nginx的主机进行连接测试
1、存放位置
Grains:Minion端
Pillar:Master端
2、数据类型
Grains:静态数据
Pillar:动态数据
3、数据采集更新方式
Grains:Minion启动时收集,也可以使用salt '*' saltutil.sync_grains进行刷新
Pillar:在Master端定义,指定给对应的Minion。可以使用salt '*' saltutil.refresh_pillar刷新
4、应用
Grains:存储Minion基本护具,比如用于匹配Minion,自身收据可以用来做资产管理等
Pillar:存储Master指定 数据,只有指定Minion可以看到,用于敏感数据保存
http://docs.saltstack.cn/ref/renderers/all/salt.renderers.jinja.html#module-salt.renderers.jinja
在state文件中Jinja最基本的用法是使用控制结构包装条件或冗余state元素:
修改监听端口和主机名
修改模板文件
[root@server1 ~]# vim /srv/salt/httpd/files/httpd.conf
Listen {{ host }}:{{ port }}
方法一:直接在service.sls文件中指定变量值
[root@server1 ~]# vim /srv/salt/httpd/service.sls
include:
- httpd.install/etc/httpd/conf/httpd.conf:
file.managed:
- source: salt://httpd/files/httpd.conf
- template: jinja
port: 8080
host: 172.25.81.2http-service:
service.running:
- name: httpd
- enable: False
- reload: True
watch:
- file: /etc/httpd/conf/httpd.conf
[root@server1 salt]# salt server2 state.sls httpd.service
server2查看推送是否成功
端口以及主机:
方法二:利用grains取变量值
[root@server1 salt]# vim /srv/salt/httpd/service.sls
include:
- httpd.install/etc/httpd/conf/httpd.conf:
file.managed:
- source: salt://httpd/files/httpd.conf
- template: jinja
port: 80
host: {{ grains['ipv4'][-1] }}http-service:
service.running:
- name: httpd
- enable: False
- reload: True
watch:
- file: /etc/httpd/conf/httpd.conf
[root@server1 salt]# salt server2 state.sls httpd.service
server2查看推送是否成功:
方法三:利用pillar取变量值
[root@server1 salt]# vim /srv/pillar/web.sls
{% if grains['fqdn'] == 'server2' %}
webserver: httpd
IP: 172.25.81.2
{% elif grains['fqdn'] == 'server3' %}
webserver: nginx
IP: 172.25.81.3
{% endif %}
[root@server1 salt]# vim /srv/salt/httpd/service.sls
include:
- httpd.install/etc/httpd/conf/httpd.conf:
file.managed:
- source: salt://httpd/files/httpd.conf
- template: jinja
port: 80
host: {{ pillar['IP'] }}http-service:
service.running:
- name: httpd
- enable: False
- reload: True
watch:
- file: /etc/httpd/conf/httpd.conf
[root@server1 salt]# salt server2 state.sls httpd.service
include和import模版
[root@server1 salt]# vim /srv/salt/httpd/lib.sls
{% set host = '127.0.0.1' %}
[root@server1 salt]# vim /srv/salt/httpd/files/httpd.conf
{% from 'httpd/lib.sls' import host %} ##模板文件第一行加入此语句
此时service.sls 文件里面定义的host变量是172.25.81.2
再次向server2推此服务:
查看server2的服务可以看出主机是127.0.0.1 所以lib.sls文件中定义的变量优先级高于service.sls文件中的变量
但是模板文件中添加的导入变量的语句并没有同步到minion主机的服务配置文件中.