1、saltsatck搭建
下载:
[root@foundation50 images]# cd /mnt/pub/docs/saltstack/
[root@foundation50 rhel7]# cp -r 3000/ /var/www/html/ 将下载好的3000版本saltsatck拷贝到server1上
[root@server1 ~]# cd /etc/yum.repos.d/
[root@server1 yum.repos.d]# vim saltstack.repo 编写 软件仓库
[saltsatck]
name=saltsatck
baseurl=http://172.25.50.250/3000
gpgcheck=0
[root@server1 yum.repos.d]# yum install salt-master.noarch -y 安装master端
[root@server1 yum.repos.d]# scp saltstack.repo server2:/etc/yum.repos.d/ 将软件仓库拷贝到server2上
[root@server1 yum.repos.d]# scp saltstack.repo server3/etc/yum.repos.d/ 将软件仓库拷贝到server3上
[root@server2 yum.repos.d]# yum install salt-minion.noarch -y server2上安装agent
[root@server3 yum.repos.d]# yum install salt-minion.noarch -y server3上安装agent
[root@server1 salt]# systemctl enable --now salt-master.service 开启salt-master
[root@server1 salt]# netstat -antlp 查看监听端口 ,两个监听端口
[root@server2 ~]# cd /etc/salt/
[root@server2 salt]# vim minion
[root@server2 salt]# systemctl enable --now salt-minion.service 启动
[root@server1 salt]# salt-key -L 查看授权认证列表
[root@server1 salt]# salt-key -help 查看帮助
[root@server1 salt]# salt-key -A server2 表示同意server2加入
The following keys are going to be accepted:
Unaccepted Keys:
server2
Proceed? [n/Y] y
[root@server1 salt]# salt-key -L
[root@server3 ~]# cd /etc/salt/
[root@server3 salt]# vim minion
[root@server3 salt]# systemctl enable --now salt-minion.service 设置开机自启
[root@server1 salt]# salt-key -L
[root@server1 salt]# salt-key -A -A表示 允许所有
The following keys are going to be accepted:
Unaccepted Keys:
server3
Proceed? [n/Y] y
Key for minion server3 accepted.
[root@server1 salt]# salt-key -L
测试:
[root@server1 salt]# salt server2 test.ping
server2:
True
[root@server1 salt]# salt server? test.ping
server2:
True
server3:
[root@server1 salt]# salt '*' test.ping
server3:
True
server2:
True
[root@server1 salt]# salt '*' cmd.run hostname
server3:
server3
server2:
server2
2、saltstack通信机制
4505端口是用来和所有minion相连的端口
4506端口是接收客户端返回报告信息
[root@server1 ~]# yum install python-setproctitle.x86_64 -y 安装,使查看进程信息更加详细
[root@server1 ~]# systemctl restart salt-master.service 重启master
[root@server1 ~]# ps ax
3、saltstack的远程执行
网站:salt内置执行模块用法
[root@server1 salt]# cd /srv/
[root@server1 srv]# mkdir salt 创建模块配置目录
[root@server1 salt]# mkdir /srv/salt/_modules 创建模块目录
[root@server1 salt]# cd _modules/ 模块编写位置必须是此位置
[root@server1 _modules]# vim mydisk.py 编写模块,都是以py结尾的
def df():
return _salt_['cmd.run']('df -h')
[root@server1 _modules]# salt server2 saltutil.sync_modules 将编写的模块同步到server2上
server2:
- modules.mydisk
查看server2上是否已经同步了:
[root@server2 salt]# cd /var/cache/
[root@server2 cache]# cd salt/
[root@server2 salt]# ls
minion
[root@server2 salt]# cd minion/
[root@server2 minion]# ls
extmods files module_refresh proc
[root@server2 minion]# cd files/
[root@server2 files]# ls
base
[root@server2 files]# cd base/
[root@server2 base]# ls
_modules
[root@server2 base]# cd _modules
[root@server2 _modules]# ls
mydisk.py
[root@server2 _modules]# cat mydisk.py 已经同步成功了
def df():
return __salt__['cmd.run']('df -h')
[root@server1 _modules]# salt server2 mydisk.df 执行
server2:
Filesystem Size Used Avail Use% Mounted on
/dev/mapper/rhel-root 17G 1.4G 16G 8% /
devtmpfs 988M 0 988M 0% /dev
tmpfs 1000M 100K 1000M 1% /dev/shm
tmpfs 1000M 17M 983M 2% /run
tmpfs 1000M 0 1000M 0% /sys/fs/cgroup
/dev/vda1 1014M 132M 883M 14% /boot
tmpfs 200M 0 200M 0% /run/user/0
安装apache:
[root@server1 ~]# cd /srv/salt/
[root@server1 salt]# vim apache.sls 编辑 文件,安装apache
httpd: 软件名
pkg.installed 方法:安装
[root@server1 salt]# salt server2 state.sls apache 执行 ,调用状态模块里的sls , apache指的是创建的apache.sls文件
server2:
----------
ID: httpd
Function: pkg.installed
Result: True 执行成功
Comment: All specified packages are already installed
Started: 14:59:49.563537
Duration: 1507.873 ms
Changes:
另一种写法:
[root@server1 salt]# vim apache.sls
apache-install: 声明
pkg.installed: 方法:安装
- name: httpd 安装软件名httpd
[root@server1 salt]# salt server2 state.sls apache 执行成功
server2:
----------
ID: apache-install
Function: pkg.installed
Name: httpd
Result: True
Comment: All specified packages are already installed
Started: 15:13:42.337287
Duration: 549.389 ms
Changes:
如何装多个包:
[root@server1 salt]# vim apache.sls
apache-install:
pkg.installed:
- pkgs: 多个包就是一个列表
- httpd
- php
[root@server1 salt]# salt server2 state.sls apache 执行
server2:
----------
ID: apache-install
Function: pkg.installed
Result: True 安装成功
Comment: All specified packages are already installed
Started: 15:24:11.784410
Duration: 555.747 ms
Changes:
安装后如何启动服务:
[root@server1 salt]# vim apache.sls
apache-install:
pkg.installed:
- pkgs:
- httpd
- php
service.running: 调用service模块,运行
- name: httpd 软件名
- enable: True 开机自启
[root@server1 salt]# salt server2 state.sls apache 执行
Comment: Service httpd has been enabled, and is running
Started: 15:39:01.231298
Duration: 355.03 ms
Changes:
----------
httpd:
True 执行成功
Summary for server2
------------
Succeeded: 2 (changed=1)
Failed: 0
源码安装nginx:
[root@server1 salt]# mkdir nginx
[root@server1 salt]# cd nginx/
[root@server1 nginx]# mkdir files
[root@server1 nginx]# mv nginx-1.8.1.tar.gz files/ 把nginx压缩文件放到files
[root@server1 nginx]# vim install.sls
nginx-install:
file.managed: 文件模块
- source: salt://nginx/files/nginx-1.18.0.tar.gz nginx源地址 nginx
- name: /mnt/nginx-1.18.0.tar.gz 目标地址
[root@foundation50 isos]# cd /mnt/pub/docs/lamp/
[root@foundation50 lamp]# scp nginx-1.8.1.tar.gz server1:/srv/salt/nginx 将nginx源码拷贝到server1上
[root@server1 salt]# mv install.sls nginx/
[root@server1 salt]# cd nginx/
[root@server1 nginx]# ls
files install.sls
[root@server1 nginx]# vim install.sls 编辑文件
nginx-install: 唯一声明
pkg.installed: 安装模块
- pkgs: 多个软件安装
- pcre-devel
- gcc
- openssl-devel
file.managed: 文件管理模块
- source: salt://nginx/files/nginx-1.18.0.tar.gz 源地址
- name: /mnt/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
[root@server1 nginx]# salt server3 state.sls nginx.install 执行 nginx.install 表示nginx目录底下的install.sls文件
server3:
----------
ID: nginx-install
Function: pkg.installed
Result: True 执行成功
Comment: All specified packages are already installed
Started: 11:59:18.231647
Duration: 599.433 ms
Changes:
----------
ID: nginx-install
Function: file.managed
Name: /mnt/nginx-1.18.0.tar.gz
Result: True
Comment: File /mnt/nginx-1.18.0.tar.gz is in the correct state
Started: 11:59:18.833858
Duration: 29.576 ms
Changes:
----------
问题:当再次salt server3 state.sls nginx.install 执行时 cmd还会继续运行nginx还会重新编译如何解决??
[root@server1 nginx]# vim install.sls 编辑文件
nginx-install:
pkg.installed:
- pkgs:
- pcre-devel
- gcc
- openssl-devel
file.managed:
- source: salt://nginx/files/nginx-1.18.0.tar.gz
- name: /mnt/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目录,如果有nginx目录就不会执行,不存在就会执行
[root@server1 nginx]# salt server3 state.sls nginx.install 执行
启动nginx
[root@server1 ~]# cd /srv/salt/nginx/
[root@server1 nginx]# vim service.sls
/usr/local/nginx/conf/nginx.conf: 声明,可以直接写目标路经
file.managed:
- source: salt://nginx/files/nginx.conf 源路经
nginx-service:
file.managed:
- source: salt://nginx/files/nginx.service 脚本源地址
- name: /etc/systemd/system/nginx.service 目标地址
service.runing:
- name: nginx
- enable: True
- reload: Ture
- watch:
- file: /usr/local/nginx/conf/nginx.conf 监控配置文件是否变化,如果变化reload
[root@foundation50 lamp]# scp nginx.service server1:/srv/salt/nginx/files/ 将nginx.service拷贝到server1的files目录里
[root@server3 minion]# cd /usr/local/nginx/conf/
[root@server3 conf]# scp nginx.conf server1:/srv/salt/nginx/files/ 将server3的nginx配置文件拷贝到server1的files目录里
问题:如何同时调用两个sls文件?
[root@server1 nginx]# ls
files install.sls service.sls 现在有两个sls文件如何同时运行
[root@server1 nginx]# vim service.sls 编辑service文件
include: include可以添加 install.sls文件,表示在执行service时,先执行nginx.install
- nginx.install
/usr/local/nginx/conf/nginx.conf:
file.managed:
- source: salt://nginx/files/nginx.conf
nginx-service:
file.managed:
- source: salt://nginx/files/nginx.service
- name: /etc/systemd/system/nginx.service
service.running:
- name: nginx
- enable: True
- reload: Ture
- watch:
- file: /usr/local/nginx/conf/nginx.conf
[root@server1 nginx]# salt server3 state.sls nginx.service 执行
注意salt所有路经都是基于/srv/salt/ 路经
对nginx配置文件进行更改:
[root@server1 nginx]# cd files/
[root@server1 files]# vim nginx.conf
[root@server3 conf]# ps ax 查看进程
[root@server1 files]# salt server3 state.sls nginx.service 执行
[root@server3 conf]# ps ax 查看进程
如何一次推送多个主机,而且每个主机部署的是不一样的?
[root@server1 nginx]# cd /srv/salt/
[root@server1 salt]# vim top.sls
base:
'server2':
- apache apache.sls 文件就在base下,没有新建文件,不需要指定目录
'server3':
- nginx.service
[root@server1 salt]# salt '*' state.highstate 调用高级状态
[root@server1 salt]# mkdir apache 创建apache目录
[root@server1 salt]# mv apache.sls apache 把编写的apache.sls文件拷贝到apache目录里面
[root@server1 salt]# cd apache/
[root@server1 apache]# mv apache.sls init.sls 将apache.sls该成init.sls文件
注:apache/init.sls 就是表示apache,他会自动找目录里面的init.sls文件
[root@server1 apache]# cd ..
[root@server1 salt]# vim top.sls
base:
'server2':
- apache 此处依旧写apache,不用写apache/init.sls
'server3':
- nginx.service
[root@server1 salt]# salt '*' state.highstate 执行高级推送
同样刚才安装的nginx也可以简化:
[root@server1 salt]# cd nginx/
[root@server1 nginx]# mv service.sls init.sls 将service.sls改成init.sls
[root@server1 nginx]# ls
files init.sls install.sls
[root@server1 salt]# vim top.sls
base:
'server2':
- apache
'server3':
- nginx 此处nginx.service该成nginx
[root@server1 salt]# salt '*' state.highstate 执行高级推送
6、grains与pillar详解
[root@server1 salt]# salt server2 grains.ls 列出所有item
[root@server1 salt]# salt server2 grains.items 列出所有key的直
[root@server1 salt]# salt server2 grains.item ipv4 指定某个key的直
server2:
----------
ipv4:
- 127.0.0.1
- 172.25.50.2
[root@server1 salt]# salt server2 grains.item fqdn 查看主机名
server2:
----------
fqdn:
server2
自定以grains项:
grains文档
[root@server2 minion]# cd /etc/salt/
[root@server2 salt]# vim minion
[root@server2 salt]# systemctl restart salt-minion.service 重启minion
[root@server1 salt]# salt server2 grains.item roles 查看角色
server2:
----------
roles:
- apache apache角色已经添加成功
另一种方法定义grains项:
root@server3 ~]# cd /etc/salt/
[root@server3 salt]# vim grains 创建grains文件
roles:
- nginx
[root@server1 salt]# salt server3 saltutil.sync_grains 在server1上刷新grains
server3:
[root@server1 salt]# salt server3 grains.item roles 查看角色,添加成功
server3:
----------
roles:
- nginx
第三种方法:(此方式只需要在master端操作)
[root@server1 salt]# mkdir _grains
[root@server1 salt]# cd _grains/
[root@server1 _grains]# vim mygrans.py 建立python文件
#!/usr/bin/env python
def mygrains():
# initialize a grains dictionary
grains = {}
# Some code for logic that sets grains like
grains['hello'] = 'world'
grains['salt'] = 'stack'
return grains
[root@server1 _grains]# salt server3 saltutil.sync_grains 刷新,同步
server3:
- grains.mygrans
[root@server1 _grains]# salt server3 grains.item salt 查看,角色添加成功
server3:
----------
salt:
stack
[root@server1 _grains]# salt server3 grains.item hello 角色添加成功
server3:
----------
hello:
world
grains匹配运用:
[root@server1 _grains]# salt -G roles:apache cmd.run hostname -G 表示匹配grains信息, roles:apache表示匹配对象为apache
server2:
server2 匹配为server2
[root@server1 _grains]# salt -G roles:nginx cmd.run hostname
server3:
server3 匹配为server2
[root@server1 _grains]# salt -G hello:world cmd.run hostname
server3:
server3
在top文件中匹配:
[root@server1 ~]# cd /srv/salt/
[root@server1 salt]# vim top.sls 编辑tops文件
base:
'roles:apache':
- match: grain
- apache
'roles:nginx':
- match: grain
- nginx
[root@server1 ~]# cd /srv/
[root@server1 srv]# mkdir pillar
[root@server1 pillar]# pwd
/srv/pillar pillar默认存放位置
[root@server1 pillar]# vim top.sls
base:
'*':
- packages 表示所有节点部署packages文件
[root@server1 pillar]# vim packages .sls 编写剧本
{% if grains['fqdn'] == 'server3' %}
package: nginx
{% elif grains['fqdn'] == 'server2' %}
package: httpd
{% endif %}
[root@server1 pillar]# salt '*' pillar.items 查询pillar数据,直接调用剧本不用刷新就可以生效
server3:
----------
package:
nginx
server2:
----------
package:
httpd
[root@server1 pillar]# salt -I "package:nginx" cmd.run hostname 用命令行匹配,匹配不到,需要刷新
[root@server1 pillar]# salt '*' saltutil.refresh_pillar 刷新pillar
server3:
True
server2:
True
[root@server1 pillar]# salt -I "package:nginx" cmd.run hostname ,再次匹配成功
server3:
server3
pillar 如何运用:
[root@server1 ~]# cd /srv/salt/apache
apache-install:
pkg.installed:
- pkgs:
- {{ pillar['package']}} 调用变量pillar中的package
- php
service.running:
- name: httpd
- enable: True
[root@server1 apache]# salt server2 state.sls apache 推送
更多的需要结合jinjia模板来用
jinja模板使用变量的方法:
[root@server1 salt]# vim test.sls
/mnt/testfile: 创建testfile文件
file.append: 用file模块里的追加 append表示追加
{% if grains['fqdn'] == 'server2' %} 如果是server2追加server2文本
- text: server2
{% elif grains['fqdn'] == 'server3' %} 如果是server3追加server3文本
- text: server3
{% endif %}
[root@server1 salt]# salt '*' state.sls test 推送
[root@server2 ~]# cat /mnt/testfile 创建成功
server2
[root@server3 ~]# cat /mnt/testfile 创建成功
server3
jinjia普通文件使用:
apache-install:
pkg.installed:
- pkgs:
- {{ pillar['package']}}
- php
file.managed:
- source: salt://apache/httpd.conf
- name: /etc/httpd/conf/httpd.conf
- template: jinja
- context: 定义变量内容
port: 8080
service.running:
- name: httpd
- enable: True
- watch:
- file: apache-install 此处不能直接写/etc/httpd/conf/httpd.conf 此文件隶属于apache-install,他会自动去找文件
[root@server1 apache]# scp server2:/etc/httpd/conf/httpd.conf . 从server2拷贝apache配置文件到/srv/salt/apache目录
[root@server1 apache]# vim httpd.conf
[root@server1 apache]# salt server2 state.sls apache 推送
如何监听ip,运用grains取直变量
[root@server1 apache]# salt server2 grains.item ipv4 只能取到ip列表
server2:
----------
ipv4:
- 127.0.0.1
- 172.25.50.2
[root@server1 apache]# vim httpd.conf
[root@server1 apache]# vim init.sls 编辑配置文件
apache-install:
pkg.installed:
- pkgs:
- {{ pillar['package'] }}
- php
file.managed:
- source: salt://apache/httpd.conf
- name: /etc/httpd/conf/httpd.conf
- template: jinja
- context:
port: 80 端口改为80
service.running:
- name: httpd
- enable: True
- watch:
- file: apache-install
[root@server1 apache]# salt server2 grains.item ipv4 执行推送,推送成功
第2种方式:
[root@server1 apache]# vim httpd.conf 编辑配置文件
[root@server1 apache]# vim init.sls
[root@server1 apache]# salt server2 state.sls apache 推送,成功
第3种方法:运用pillar取直
[root@server1 srv]# cd pillar/
[root@server1 pillar]# vim packages.sls 编写剧本
[root@server1 apache]# vim init.sls
[root@server1 apache]# salt server2 state.sls apache 推送
第4种方法:
[root@server1 apache]# vim init.sls
[root@server1 apache]# vim httpd.conf
[root@server1 apache]# salt server2 state.sls apache 推送,成功
第5种方法:定义变量文件
[root@server1 apache]# vim lib.sls 定义变量文件
{% set port = 80 %} 赋值给变量
[root@server1 apache]# vim httpd.conf 编辑配置文件
[root@server1 apache]# vim init.sls
示例:搭建高可用集群
[root@server1 ~]# cd /srv/salt/
[root@server1 salt]# mkdir keepalived
[root@server1 keepalived]# vim init.sls
kp-install:
pkg.installed:
- name: keepalived
file:managed:
- source: salt://keepalived/files/keepalived.conf
- name: /etc/keepalived/keepalived.conf
service.running:
- name: keepalived
- enabled: Ture
- reload: Ture
- watch:
-file: kp-install
[root@server1 keepalived]# mkdir files 创建files目录
[root@server1 keepalived]# cd files/ 进入目录
[root@server2 yum.repos.d]# yum install -y keepalived 在server2上安装keepalived
[root@server1 files]# scp server2:/etc/keepalived/keepalived.conf . 将server2上keepalived.conf配置文件拷贝到当前目录
[root@server1 files]# vim keepalived.conf 编辑keepalived配置文件
[root@server1 ~]# cd /srv/pillar/
[root@server1 pillar]# cp packages.sls keepalived.sls
[root@server1 pillar]# vim keepalived.sls 编写剧本
{% if grains['fqdn'] == 'server2' %}
kp-state: MASTER
kp-vrid: 51
kp-pri: 100 BACKUP优先级高
{% elif grains['fqdn'] == 'server3' %}
kp-state: BACKUP
kp-vird: 51
kp-pri: 50 BACKUP优先级低
{% endif %}
[root@server1 pillar]# vim top.sls
base:
'*':
- packages
- keepalived 将剧本添加到top.sls里面,这样才能加载
[root@server1 keepalived]# vim init.sls
kp-install:
pkg.installed:
- name: keepalived
file.managed:
- source: salt://keepalived/files/keepalived.conf
- name: /etc/keepalived/keepalived.conf
- template: jinja
- context:
STATE: {{ pillar['kp-state'] }} 调用pillar下的keepalived.sls文件
VRID: {{ pillar['kp-vird'] }} 调用pillar下的keepalived.sls文件
PRI: {{ pillar['kp-pri'] }} 调用pillar下的keepalived.sls文件
service.running:
- name: keepalived
- enable: Ture
- reload: Ture
- watch:
- file: kp-install
[root@server1 ~]# cd /srv/salt/
[root@server1 salt]# vim top.sls
base:
'server2':
- apache
- keepalived
'server3':
- nginx
- keepalived
[root@server1 keepalived]# cd /srv/pillar/
[root@server1 pillar]# vim packages.sls
[root@server1 ~]# cd /srv/salt/apache
[root@server1 apache]# vim httpd.conf 编辑apache配置文件
[root@server1 salt]# salt '*' state.highstate 执行成功
[root@server2 ~]# ip addr show 查看ip
测试:
[root@server2 ~]# systemctl stop keepalived.service 停掉server2上的keepalived
[root@foundation50 isos]# curl 172.25.50.100 访问
[root@server3 ~]# ip addr show vip从server2切换到server3上
7、job管理
[root@server1 ~]# cd /var/cache/salt master的缓存路径
[root@server1 salt]# ls
master
如何把缓存数据返回到数据库上?
[root@server1 ~]# yum install mariadb-server -y 安装数据库
[root@server1 ~]# systemctl start mariadb.service 启动数据库
[root@server2 ~]# yum install -y MySQL-python.x86_64 在server2上安装
[root@server2 ~]# cd /etc/salt/
[root@server2 salt]# vim minion 编辑minion端配置文件
[root@server1 ~]# vim salt.sql 在server1上建立文件,创建库和表结构
CREATE DATABASE `salt`
DEFAULT CHARACTER SET utf8
DEFAULT COLLATE utf8_general_ci;
USE `salt`;
--
-- Table structure for table `jids`
--
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;
# CREATE INDEX jid ON jids(jid) USING BTREE;
--
-- Table structure for table `salt_returns`
--
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;
--
-- Table structure for table `salt_events`
--
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;
[root@server1 ~]# mysql < salt.sql 将salt.sql 导入数据库
[root@server1 ~]# mysql
MariaDB [(none)]> grant all on salt.* to salt@'%' identified by 'salt'; 给salt用户授权
Query OK, 0 rows affected (0.00 sec)
[root@server2 salt]# mysql -h 172.25.50.1 -usalt -psalt 在server2上远程登陆
MariaDB [(none)]> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| salt | salt库存在
| test |
+--------------------+
3 rows in set (0.00 sec)
[root@server2 salt]# systemctl restart salt-minion.service 重启minion端
[root@server1 ~]# salt server2 cmd.run df --return mysql -return mysql 表示指定到数据库
server2:
Filesystem 1K-blocks Used Available Use% Mounted on
/dev/mapper/rhel-root 17811456 1446736 16364720 9% /
devtmpfs 1011448 0 1011448 0% /dev
tmpfs 1023468 40 1023428 1% /dev/shm 此时的结果是返回给master
tmpfs 1023468 16984 1006484 2% /run
tmpfs 1023468 0 1023468 0% /sys/fs/cgroup
/dev/vda1 1038336 135076 903260 14% /boot
tmpfs 204696 0 204696 0% /run/user/0
此方法需要配置所有的minion端,比较麻烦,所以可以使用第二种方法
第二种方法:
[root@server1 ~]# vim /etc/salt/master 编辑master配置文件
[root@server1 ~]# systemctl restart salt-master.service 重启服务
[root@server1 ~]# mysql -usalt -psalt salt salt用户不能登陆本机mysql
ERROR 1045 (28000): Access denied for user 'salt'@'localhost' (using password: YES)
MariaDB [(none)]> grant all on salt.* to salt@localhost identified by 'salt'; 授权本机登陆
Query OK, 0 rows affected (0.00 sec)
[root@server1 ~]# mysql -usalt -psalt salt
MariaDB [salt]> 可以登陆了
[root@server1 ~]# yum install -y MySQL-python.x86_64 安装MySQL-python模块,现在是由master端去存入数据到mysql,所以要在master端安装
[root@server1 ~]# salt '*' test.ping
server3:
True
server2:
True
[root@server1 ~]# salt '*' cmd.run hostname
server2:
server2
server3:
server3
[root@server1 ~]# mysql 登陆mysql
MariaDB [(none)]> use salt
MariaDB [salt]> show tables;
+----------------+
| Tables_in_salt |
+----------------+
| jids |
| salt_events |
| salt_returns |
+----------------+
3 rows in set (0.00 sec)
MariaDB [salt]> select * from salt_returns;
8、salt-ssh 与 salt-syndic
[root@server3 ~]# systemctl stop salt-minion.service 停掉minion端
[root@server1 ~]# yum install salt-ssh -y 安装
[root@server1 ~]# cd /etc/salt/
[root@server1 salt]# vim roster 编辑salt-ssh 配置文件
[root@server1 salt]# salt-ssh '*' test.ping 推送
server3:
True
user -> top master (顶级master) -> (syndic(相当于代理) -> master)这两个是共存的 -> minion
[root@server1 ~]# yum install salt-syndic -y 下载套件
再开启一台srver4,让server4做topmaster
[root@server1 yum.repos.d]# scp saltstack.repo server4:/etc/yum.repos.d/ 将server1上saltstack.repo yum源拷贝到server4上
[root@server4 ~]# yum install -y salt-master 在server4上安装master
[root@server1 ~]# cd /etc/salt/
[root@server1 salt]# vim master
[root@server4 ~]# cd /etc/salt
[root@server4 salt]# vim master 编辑配置文件
[root@server4 salt]# systemctl start salt-master.service 启动master
[root@server1 salt]# systemctl restart salt-master.service 重启服务
[root@server1 salt]# systemctl start salt-syndic.service 启动syndic
[root@server4 salt]# salt-key -L
Accepted Keys:
Denied Keys:
Unaccepted Keys:
server1
Rejected Keys:
[root@server4 salt]# salt-key -A
The following keys are going to be accepted:
Unaccepted Keys:
server1
Proceed? [n/Y] Y
Key for minion server1 accepted.
[root@server4 ~]# salt-key -L
Accepted Keys:
server1 server1相当于代理,topmaster通过salt-syndic传递到下级master,然后相当于在下级master做了salt '*' test.ping 动作
Denied Keys:
Unaccepted Keys:
Rejected Keys:
[root@server4 ~]# salt '*' test.ping
server2:
True
server3:
True
9、salt-api配置
REST_CHERRYPY
[root@server1 salt]# yum install salt-api -y 安装组件
[root@server1 ~]# cd /etc/salt/
[root@server1 salt]# cd master.d/
[root@server1 master.d]# vim auth.conf 建立文件 扩展认证,默认后面跟.conf
external_auth:
pam: pam认证
saltapi: 用户
- .* 表示调用所有内容
- '@wheel'
- '@runner' 表示允许的功能模块,此初没有添加
- '@jobs'
[root@server1 master.d]# cd /etc/pki/
[root@server1 pki]# cd tls/
[root@server1 tls]# cd private/
[root@server1 private]# openssl genrsa 1024 > localhost.key 生成key,私匙
Generating RSA private key, 1024 bit long modulus
.....++++++
....++++++
e is 65537 (0x10001)
[root@server1 private]# cd ..
[root@server1 tls]# cd certs/
[root@server1 certs]# ls
[root@server1 certs]# make testcert 生成证书
Country Name (2 letter code) [XX]:cn
State or Province Name (full name) []:shaanxi
Locality Name (eg, city) [Default City]:xi'an
Organization Name (eg, company) [Default Company Ltd]:westos
Organizational Unit Name (eg, section) []:linux
Common Name (eg, your name or your server's hostname) []:server1
Email Address []:root@westos.org
[root@server1 certs]# pwd
/etc/pki/tls/certs 证书路经
[root@server1 private]# pwd key的路经
/etc/pki/tls/private
[root@server1 tls]# cd /etc/salt/master.d/
[root@server1 master.d]# vim ssl.conf 建立文件,加密配置
rest_cherrypy:
port: 8000
ssl_crt: /etc/pki/tls/certs/localhost.crt
ssl_key: /etc/pki/tls/private/localhost.key
[root@server1 master.d]# systemctl start salt-api.service 启动salt-api
[root@server1 master.d]# useradd saltapi 建立刚才添加的认证用户
[root@server1 master.d]# passwd saltapi 添加密码
Changing password for user saltapi.
New password:
BAD PASSWORD: The password is shorter than 8 characters
Retype new password:
passwd: all authentication tokens updated successfully.
[root@server1 master.d]# systemctl restart salt-master.service
[root@server1 master.d]# systemctl restart salt-api.service
[root@server1 master.d]# curl -sSk https://172.25.50.1:8000/login -H 'Accept: application/x-yaml' -d username=saltapi -d password=westos -d eauth=pam 执行,得到token,认证方式pam
return:
- eauth: pam
expire: 1644592274.53811
perms:
- .*
- '@wheel'
- '@runner'
- '@jobs'
start: 1644549074.538108
token: 42e8d9dcb3932e77232084933f5b90537371ec6c
user: saltapi
[root@server1 master.d]# curl -sSk https://172.25.50.1:8000 -H 'Accept: application/x-yaml' -H 'X-Auth-Token: 42e8d9dcb3932e77232084933f5b90537371ec6c' -d client=local -d tgt='*' -d fun=test.ping
return:
- server2: true
server3: true
[root@foundation50 images]# cd /mnt/pub/docs/saltstack/
[root@foundation50 saltstack]# scp saltapi.py server1: 将老师改好的saltapi.py拷贝到server1上
[root@server1 ~]# vim saltapi.py 执行nginx
# -*- coding: utf-8 -*-
import urllib2,urllib
import time
import ssl
ssl._create_default_https_context = ssl._create_unverified_context
try:
import json
except ImportError:
import simplejson as json
class SaltAPI(object):
__token_id = ''
def __init__(self,url,username,password):
self.__url = url.rstrip('/')
self.__user = username
self.__password = password
def token_id(self):
''' user login and get token id '''
params = {'eauth': 'pam', 'username': self.__user, 'password': self.__password}
encode = urllib.urlencode(params)
obj = urllib.unquote(encode)
content = self.postRequest(obj,prefix='/login')
try:
self.__token_id = content['return'][0]['token']
except KeyError:
raise KeyError
def postRequest(self,obj,prefix='/'):
url = self.__url + prefix
headers = {'X-Auth-Token' : self.__token_id}
req = urllib2.Request(url, obj, headers)
opener = urllib2.urlopen(req)
content = json.loads(opener.read())
return content
def list_all_key(self):
params = {'client': 'wheel', 'fun': 'key.list_all'}
obj = urllib.urlencode(params)
self.token_id()
content = self.postRequest(obj)
minions = content['return'][0]['data']['return']['minions']
minions_pre = content['return'][0]['data']['return']['minions_pre']
return minions,minions_pre
def delete_key(self,node_name):
params = {'client': 'wheel', 'fun': 'key.delete', 'match': node_name}
obj = urllib.urlencode(params)
self.token_id()
content = self.postRequest(obj)
ret = content['return'][0]['data']['success']
return ret
def accept_key(self,node_name):
params = {'client': 'wheel', 'fun': 'key.accept', 'match': node_name}
obj = urllib.urlencode(params)
self.token_id()
content = self.postRequest(obj)
ret = content['return'][0]['data']['success']
return ret
def remote_noarg_execution(self,tgt,fun):
''' Execute commands without parameters '''
params = {'client': 'local', 'tgt': tgt, 'fun': fun}
obj = urllib.urlencode(params)
self.token_id()
content = self.postRequest(obj)
ret = content['return'][0][tgt]
return ret
def remote_execution(self,tgt,fun,arg):
''' Command execution with parameters '''
params = {'client': 'local', 'tgt': tgt, 'fun': fun, 'arg': arg}
obj = urllib.urlencode(params)
self.token_id()
content = self.postRequest(obj)
ret = content['return'][0][tgt]
return ret
def target_remote_execution(self,tgt,fun,arg):
''' Use targeting for remote execution '''
params = {'client': 'local', 'tgt': tgt, 'fun': fun, 'arg': arg, 'expr_form': 'nodegroup'}
obj = urllib.urlencode(params)
self.token_id()
content = self.postRequest(obj)
jid = content['return'][0]['jid']
return jid
def deploy(self,tgt,arg):
''' Module deployment '''
params = {'client': 'local', 'tgt': tgt, 'fun': 'state.sls', 'arg': arg}
obj = urllib.urlencode(params)
self.token_id()
content = self.postRequest(obj)
return content
def async_deploy(self,tgt,arg):
''' Asynchronously send a command to connected minions '''
params = {'client': 'local_async', 'tgt': tgt, 'fun': 'state.sls', 'arg': arg}
obj = urllib.urlencode(params)
self.token_id()
content = self.postRequest(obj)
jid = content['return'][0]['jid']
return jid
def target_deploy(self,tgt,arg):
''' Based on the node group forms deployment '''
params = {'client': 'local_async', 'tgt': tgt, 'fun': 'state.sls', 'arg': arg, 'expr_form': 'nodegroup'}
obj = urllib.urlencode(params)
self.token_id()
content = self.postRequest(obj)
jid = content['return'][0]['jid']
return jid
def main():
sapi = SaltAPI(url='https://172.25.50.1:8000',username='saltapi',password='westos')
sapi.token_id()
print sapi.list_all_key()
#sapi.delete_key('test-01')
#sapi.accept_key('test-01')
sapi.deploy('server3','nginx') 执行nginx
#print sapi.remote_noarg_execution('test-01','grains.items')
if __name__ == '__main__':
main()
[root@server3 minion]# systemctl stop nginx.service 停止server3上的nginx
[root@server1 ~]# python saltapi.py 运行
[root@server3 minion]# ps ax nginx已经运行