Linux企业实战之自动化运维工具(六)——SaltStack(6)

本文详细介绍SaltStack的salt-ssh、salt-syndic和salt-api组件。salt-ssh实现无minion状态下的远程命令执行,salt-syndic构建多层级master架构,salt-api提供RESTful API接口,方便第三方系统集成。

salt-ssh

salt-ssh简介

  • salt-ssh可以独立运行的,不需要minion端。
  • salt-ssh 用的是sshpass进行密码交互的。
  • 以串行模式工作,性能下降。

部署salt-ssh

  • 实验环境
server1安装了salt-master
server2安装了minion,我们提前停止salt-minion
systemctl stop salt-minion			
yum install -y salt-ssh
vim /etc/salt/roster

在这里插入图片描述

salt-ssh server2 test.ping
salt-ssh server2 cmd.run df

在这里插入图片描述

有时候第一次访问,需要进行ssh的校验

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

salt-syndic

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的目录要保持一致。

  • 架构图

在这里插入图片描述

salt-syndic配置

  • 实验环境
server1作为master,安装salt-syndic
server2安装了salt-minion
server3安装了salt-minion
server4安装master,作为Topmaster
yum install -y salt-master       #在server4上安装salt-master
vim /etc/salt/master
systemctl enable --now salt-master

在这里插入图片描述

vim /etc/salt/master
systemctl restart salt-master
systemctl start salt-syndic

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

salt-api

salt-api简介

  • SaltStack 官方提供有REST API格式的 salt-api 项目,将使Salt与第三方系统集成变得尤为简单。

  • salt-api是外部系统与saltstack集成的接口,通过与外部系统的集成,我们将不再是单一的使用命令行来操作saltstack,而是可以通过代码、webUI等方式来操作saltstack。

  • 官方提供了三种api模块:

    • rest_cherrypy
    • rest_tornado
    • rest_wsgi

配置过程

  • 步骤一:在server1上安装salt-api,并且生成key和证书
yum install -y salt-api
cd /etc/pki/tls/private
openssl genrsa 2048 > localhost.key
cd /etc/pki/tls/certs/
make testcert

在这里插入图片描述
在这里插入图片描述

  • 步骤二:在/etc/salt/master.d目录下创建一个.conf文件,然后再创建一个认证文件
cd /etc/salt/master.d/
vim tls.conf
vim auth.conf
useradd -s /sbin/nologin saltapi
passwd saltapi
systemctl restart salt-master
systemctl start salt-api
netstat -antlp

在这里插入图片描述
上图中有一个小错误,应该是auth.conf
在这里插入图片描述

  • 步骤三:进行认证获取token,调用api接口
curl -sSk https://localhost:8000/login \
    -H 'Accept: application/x-yaml' \
    -d username=saltapi \
    -d password=redhat \
    -d eauth=pam

curl -sSk https://localhost:8000 \
    -H 'Accept: application/x-yaml' \
    -H 'X-Auth-Token: 497ba07244c4fb46a8446e8506b98682f5117aca'\
    -d client=local \
    -d tgt='*' \
    -d fun=test.ping

在这里插入图片描述
在这里插入图片描述

  • 做一个Github上关于salt-api的小项目

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

vim saltapi.py

import urllib2,urllib
import time

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://localhost:8000',username='saltapi',password='redhat')
    #sapi.token_id()
    print sapi.list_all_key()
    #sapi.delete_key('test-01')
    #sapi.accept_key('test-01')
    #sapi.deploy('test-01','nginx')
    #print sapi.remote_noarg_execution('test-01','grains.items')

if __name__ == '__main__':
    main()


python saltapi.py

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值