saltstack(自动化运维工具)——JOB管理+salt-ssh与salt-syndic+salt-api配置

一、Job简介
master在下发指令任务时,会附带上产生的jid。
minion在接收到指令开始执行时,会在本地的/var/cache/salt/minion/proc目录下产生该jid命名的文件,用于在执行过程中master查看当前任务的执行情况。
指令执行完毕将结果传送给master后,删除该临时文件。
Job缓存默认保存24小时:

# vim /etc/salt/master
keep_jobs: 24

master端Job缓存目录:

/var/cache/salt/master/jobs

流程图:把Job存储到数据库
saltstack(自动化运维工具)——JOB管理+salt-ssh与salt-syndic+salt-api配置_第1张图片

二、把Job存储到数据库
2.1在server4上mariadb数据库

[root@server4 ~]# yum install mariadb-server.x86_64   安装数据库
[root@server4 ~]# systemctl start mariadb.service
[root@server4 ~]# mysql_secure_installation

2.2在server5(minion端)安装MySQL-python.x86_64

[root@server5 ~]# yum install  -y MySQL-python.x86_64

更改配置文件

[root@server5 ~]# vim /etc/salt/minion
[root@server5 ~]# systemctl restart salt-minion.service 

在这里插入图片描述
2.3在server4上

[root@server4 ~]# vim add.sql

```sql
# cat add.sql
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`
--
[root@server4 ~]# mysql -uroot -pwestos < add.sql  导入数据库
[root@server4 ~]# mysql -uroot -pwestos
MariaDB [(none)]> grant all on salt.* to salt@localhost identified by 'salt';
Query OK, 0 rows affected (0.01 sec)

MariaDB [(none)]> grant all on salt.* to salt@'%' identified by 'salt';
Query OK, 0 rows affected (0.00 sec)

[root@server4 ~]# salt server5 cmd.run hostname
server5:
    server5

saltstack(自动化运维工具)——JOB管理+salt-ssh与salt-syndic+salt-api配置_第2张图片
2.4在master端配置,复位刚才在minion端的配置,这样就不用再minion端去安装MySQL-python.x86_64

[root@server5 ~]# vim /etc/salt/minion
[root@server5 ~]# systemctl restart salt-minion.service 
[root@server5 ~]# yum install -y mysql

saltstack(自动化运维工具)——JOB管理+salt-ssh与salt-syndic+salt-api配置_第3张图片

[root@server4 ~]# yum install -y MySQL-python.x86_64
[root@server4 ~]# vim /etc/salt/master
master_job_cache: mysql
return: mysql
mysql.host: '172.25.254.4'
mysql.user: 'salt'
mysql.pass: 'salt'
mysql.db: 'salt'
mysql.port: 3306
[root@server4 ~]# systemctl restart salt-master.service 


saltstack(自动化运维工具)——JOB管理+salt-ssh与salt-syndic+salt-api配置_第4张图片
saltstack(自动化运维工具)——JOB管理+salt-ssh与salt-syndic+salt-api配置_第5张图片
三、salt-ssh简介
1】salt-ssh可以独立运行的,不需要minion端。
2】salt-ssh 用的是sshpass进行密码交互的。
3】以串行模式工作,性能下降。
3.1salt-ssh配置

停止minion端服务
[root@server5 ~]# systemctl stop salt-minion.service
[root@server6 ~]# systemctl stop salt-minion.service

安装salt-ssh:

[root@server4 ~]# yum install -y ssh-salt
[root@server4 ~]# cat /etc/salt/roster 
# Sample salt-ssh config file
#web1:
#  host: 192.168.42.1 # The IP addr or DNS hostname
#  user: fred         # Remote executions will be executed as user fred
#  passwd: foobarbaz  # The password to use for login, if omitted, keys are used
#  sudo: True         # Whether to sudo to root, not enabled by default
#web2:
#  host: 192.168.42.2
server5:
  host: 172.25.254.5
  user: root
  passwd: westos

server6:
  host: 172.25.254.6
  user: root
  passwd: westos


测试:

 salt-ssh '*' test.ping -i		//询问密码加 -i
 vim ~/.ssh/config    
StrictHostKeyChecking no   
加入此参数在当访问其他主机时不再校验key,直接显示密码登录不用回答yes或no

saltstack(自动化运维工具)——JOB管理+salt-ssh与salt-syndic+salt-api配置_第6张图片

[root@server4 ~]# salt-ssh server5 cmd.run df
server5:
    Filesystem            1K-blocks    Used Available Use% Mounted on
    /dev/mapper/rhel-root   8374272 1500000   6874272  18% /
    devtmpfs                 521648       0    521648   0% /dev
    tmpfs                    533788       0    533788   0% /dev/shm
    tmpfs                    533788    8328    525460   2% /run
    tmpfs                    533788       0    533788   0% /sys/fs/cgroup
    /dev/sda1               1038336  135308    903028  14% /boot
    tmpfs                    106760       0    106760   0% /run/user/0

四、salt-syndic简介
如果大家知道zabbix proxy的话那就很容易理解了,syndic其实就是个代理,隔离master与minion。
Syndic必须要运行在master上,再连接到另一个topmaster上。
Topmaster 下发的状态需要通过syndic来传递给下级master,minion传递给master的数据也是由syndic传递给topmaster。
topmaster并不知道有多少个minion。
syndic与topmaster的file_roots和pillar_roots的目录要保持一致

4.1salt-syndic配置
saltstack(自动化运维工具)——JOB管理+salt-ssh与salt-syndic+salt-api配置_第7张图片
4.2salt-syndic配置过程
实验环境

server4   172.25.254.4   salt-master
server5   172.25.254.5   salt-minion
server6   172.25.254.6   salt-minion
server7   172.25.254.7   salt-master(中心master)
server7作为server4与其他minion端的中间人。
server4制管理中间master
中间master去管理其他minion端
[root@server5 ~]# systemctl start salt-minion.service 
[root@server6 ~]# systemctl start salt-minion.service 
[root@server7 ~]# yum install -y salt-master
[root@server7 ~]# vim /etc/salt/master
1047行: order_masters: True
[root@server7 ~]# systemctl start salt-master.service 

在server1上

[root@server4 ~]# yum install -y salt-syndic
[root@server4 ~]# vim /etc/salt/master
1051行: syndic_master: 172.25.254.7  指定顶级master主机
[root@server4 ~]# systemctl restart salt-master.service 
[root@server4 ~]# systemctl restart salt-syndic.service 

saltstack(自动化运维工具)——JOB管理+salt-ssh与salt-syndic+salt-api配置_第8张图片
可以看到server7顶级的master只有一个下属server4,但是可以看到两个minion端,实际上只是server4取获取minion端的信息在交给server7.
五、salt-api配置
5.1salt-api简介
SaltStack 官方提供有REST API格式的 salt-api 项目,将使Salt与第三方系统集成变得尤为简单。
官方提供了三种api模块:

rest_cherrypy
rest_tornado
rest_wsgi

官方链接:https://docs.saltstack.com/en/latest/ref/netapi/all/index.html#all-netapi-modules
5.2salt-api配置过程
安装salt-api:

[root@server4 ~]# yum install -y salt-api  python-cherrypy

5.3生成证书
saltstack(自动化运维工具)——JOB管理+salt-ssh与salt-syndic+salt-api配置_第9张图片

[root@server4 certs]# cd /etc/salt/master.d/
[root@server4 master.d]# ll
total 0
[root@server4 master.d]# vim auth.conf  创建用户认证文件
[root@server4 master.d]# cat auth.conf
external_auth:
  pam:
    saltdev:
      - .*
      - '@wheel'
      - '@runner'
      - '@jobs'
[root@server4 master.d]# useradd saltdev  创建用户
[root@server4 master.d]# passwd saltdev   更改密码westos
Changing password for user saltdev.
New password: 
BAD PASSWORD: The password is shorter than 8 characters
Retype new password: 
passwd: all authentication tokens updated successfully.
[root@server4 master.d]# vim cert.conf  激活rest_cherrypy模块
[root@server4 master.d]# cat  cert.conf
rest_cherrypy:
  port: 8000
  ssl_crt: /etc/pki/tls/certs/localhost.crt
  ssl_key: /etc/pki/tls/private/localhost.key
[root@server4 master.d]# systemctl restart salt-master  重启
[root@server4 master.d]# systemctl start salt-api  启动
[root@server4 master.d]# netstat -tnpl | grep 8000  查看端口
tcp        0      0 0.0.0.0:8000            0.0.0.0:*               LISTEN      116430/python   

5.4获取认证token:

[root@server4 master.d]# curl -sSk https://localhost:8000/login \
> -H 'Accept: application/x-yaml' \  
> -d username=saltdev \
> -d password=westos \
> -d eauth=pam
return:
- eauth: pam
  expire: 1591767118.761024
  perms:
  - .*
  - '@wheel'
  - '@runner'
  - '@jobs'
  start: 1591723918.761023
  token: bc00b70cb788756454e0db7eddf7fd4b47a3bb30
  user: saltdev
  
推送任务
  [root@server4 master.d]# curl -sSk https://localhost:8000  \
  > -H 'Accept: application/x-yaml' \
  > -H 'X-Auth-Token:  bc00b70cb788756454e0db7eddf7fd4b47a3bb30' \ token值是上面命令获取的toekn值 
  > -d client=local  \
  > -d tgt='*'  \
  > -d fun=test.ping

在这里插入图片描述
编写一个python脚本安装软件

代码:https://github.com/binbin91/oms/blob/master/deploy/saltapi.py
[root@server4 ~]# vim saltapi.py
# -*- 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.254.4:8000',username='saltdev',password='westos')
    #sapi.token_id()
    #print sapi.list_all_key()  
    #sapi.delete_key('test-01')
    #sapi.accept_key('test-01')
    sapi.deploy('172.25.254.6','nginx')  给server6安nginx服务
    #print sapi.remote_noarg_execution('test-01','grains.items')

if __name__ == '__main__':
    main()

[root@server4 ~]# python saltapi.py 

你可能感兴趣的:(saltstack(自动化运维工具)——JOB管理+salt-ssh与salt-syndic+salt-api配置)