Saltstack之saltssh及其API的应用

ssh

saltssh简介

基本定义
  • salt-ssh是通过ssh协议执行命令进行管理服务器,不需要在服务器端安装minion客户端,如果有安装minion也可以调用minion模块,salt-ssh有点类似ansible无客户端基与ssh协议进行管理服务器,通过roser(/etc/salt/roser)配置文件
应用场景
  • 主要作用是不需要安装minion,只要ssh协议开放,即可远程执行命令,可用作拿到一批新机器,批量配置时使用,也可以直接通过salt-ssh不安装minion进行管理。
  • salt ssh系统并不完全取代salt的通信系统。它只是简单的基于ssh协议不在依赖于ZeroMQ和salt-minion,但是由于salt ssh完全是基于ssh协议的,所以在进行远程行,ssh的执行效率要远远低于ZeroMQ
  • 创建roster系统是因为salt-ssh需要依赖这个名单来确定哪些系统如何连接并且执行。
  • 因为这个roster系统属于“热插拔”类型,它可以增强附着在任何现有的系统中来收集关于哪些服务器目前可用以及可以使用salt-ssh来连接的信息

注意:此实验环境中不用装minion,不需要开启master和minion。

server2(minion)
  • 关闭minion服务,方便我们观察实验现象。
[root@server2 ~]# systemctl stop salt-minion   #停止 查看实验现象
server1(master)
  • 安装salt-ssh。
[root@server1 2019]# yum install salt-ssh -y
  • 编辑配置文件,添加要ssh连接的主机:
[root@server1 2019]# cd /etc/salt/
[root@server1 salt]# vim roster
server2:
  host: 172.25.11.2
  user: root    #要ssh连接的用户和密码
  passwd: redhat

在这里插入图片描述

测试
  • 配置成功后直接测试,可以看到ping的结果为true。
[root@server1 salt]# salt-ssh '*' test.ping

在这里插入图片描述

  • 查看server2的分区
[root@server1 salt]# salt-ssh server2 -r 'df'   #查看server2的分区

在这里插入图片描述

  • 查看server2的主机名。
[root@server1 salt]# salt-ssh server2 -r 'hostname'

在这里插入图片描述

API

server2(minion)
  • 在server2上将刚才关闭的服务再次打开。
[root@server2 ~]# systemctl start salt-minion   #将关闭的服务再次打开
server1(master)
  • 在server1安装salt-api。
[root@server1 salt]# yum install salt-api -y

在这里插入图片描述

  • /etc/pki/tls/private/目录下生成key。
[root@server1 salt]# cd /etc/pki/tls/
[root@server1 tls]# cd private/
[root@server1 private]# openssl genrsa 2048 > localhost.key    #生成key
[root@server1 private]# cat localhost.key   #查看已经生成

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

  • /etc/pki/tls/certs目录下生成证书,因为在这个目录下面有makefile文件,该文件里面有生成证书的相应方式,使用钥匙生成证书
[root@server1 private]# cd ..
[root@server1 tls]# cd certs/
[root@server1 certs]# make testcert    #生成证书

在这里插入图片描述

  • 在server1上/etc/salt下查看master文件里面有相应的api模块文件的目录及其文件命名格式,api模版文件要在master.d目录下且以.conf结尾。
[root@server1 ~]# vim /etc/salt/master    #里写了命名格式以及文件路径
12 #default_include: master.d/*.conf

在这里插入图片描述

  • 按照官网的格式,在/etc/salt/master.d目录下编辑api的配置文件添加证书及其钥匙。
  • 官网:https://docs.saltstack.com/en/latest/topics/eauth/index.html#acl-eauth
[root@server1 certs]# vim /etc/salt/master.d/api.conf    #所以按要求新建这个文件
rest_cherrypy:
  port: 8000    #开启端口
  ssl_crt: /etc/pki/tls/certs/localhost.crt
  ssl_key: /etc/pki/tls/private/localhost.key
  • 要保证api文件里的证书和私钥的路径是正确的。
[root@server1 certs]# ll /etc/pki/tls/certs/localhost.crt   #上面的证书和钥匙可以在系统中查到
[root@server1 certs]# ll /etc/pki/tls/private/localhost.key

在这里插入图片描述

  • 同样的,在/etc/salt/master.d目录下新建认证文件,按照官网的格式写。
[root@server1 master.d]# vim /etc/salt/master.d/auth.conf   #认证文件

external_auth:
  pam:
    saltdev:    #用户名
      - '.*'
      - '@wheel'   #允许所有的wheel模块
      - '@runner'
      - '@jobs'

在这里插入图片描述

  • 添加用户saltdev,修改密码为saltdev。
[root@server1 master.d]# useradd saltdev   #添加上面文件里写的saltdev用户,修改他的密码为saltdev,跟官网保持一致
[root@server1 master.d]# passwd saltdev
  • 开启salt-api服务,重启salt-master服务,并查看端口8000有没有成功开启。
[root@server1 ~]# systemctl restart salt-master
[root@server1 ~]# systemctl start salt-api
[root@server1 ~]# netstat -antlp   #查看8000端口已开启

在这里插入图片描述

  • 登陆,获取token。
[root@server1 ~]# curl -sSk https://localhost:8000/login \    #登陆,获取token
>     -H 'Accept: application/x-yaml' \
>     -d username=saltdev \
>     -d password=saltdev \
>     -d eauth=pam

在这里插入图片描述

  • 利用刚才的token,执行test.ping命令,检测所有的minion端。
#利用刚才的token,执行test.ping命令,检测所有的minion端。
[root@server1 ~]# curl -sSk https://localhost:8000     -H 'Accept: application/x-yaml'     -H 'X-Auth-Token:b4d2689c7630149c88c29408d174022dd92765bb' \      
>     -d client=local \
>     -d tgt='*' \     #目标是*
>     -d fun=test.ping

在这里插入图片描述

Python OMT

  • github官网可以找到别人写好的文件学习学习。
打印该master节点下的所有获得key的minion
[root@server1 ~]# vim saltapi.py   #写一个python脚本

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='saltdev',password='saltdev')      #修改这一行的3个参数 注意是https
    #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()
  • 修改了2处。
    在这里插入图片描述
  • 执行此脚本,可以看到执行结果。
[root@server1 ~]# python saltapi.py
打印出server2和server3

在这里插入图片描述

  • 列出所有的允许的key。
[root@server1 ~]# salt-key -L

在这里插入图片描述

开启server2的httpd服务
  • 再次修改.py文件 开启server2的apache服务。
  • 注意:必须确保在base目录下(/srv/salt)有相应的sls安装及其启动服务install.slsservice.sls的文件
  • 修改前 先查看进程:ps ax,可以看到此时httpd服务未开启。
    在这里插入图片描述
  • 修改文件并执行。
[root@server1 ~]# vim saltapi.py 
[root@server1 ~]# python saltapi.py 

在这里插入图片描述

  • server2再查看进程,开启httpd服务了 ps ax
    在这里插入图片描述
开启server3的nginx服务
  • 注意:必须确保在base目录下(/srv/salt)有相应的sls安装及其启动服务install.slsservice.sls的文件
  • 开启server3的nginx,编辑py文件并执行。
[root@server1 ~]# vim saltapi.py 
[root@server1 ~]# python saltapi.py

在这里插入图片描述

  • 在server3查看进程 ps ax,nginx成功开启。
    在这里插入图片描述
    注意:有可能server3开启了httpd,关闭apache,再执行一次python脚本然后再查看nginx的进程。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值