资讯专栏INFORMATION COLUMN

saltstack-api使用详解

A Loity / 2467人阅读

摘要:本文介绍下的简单使用。介绍本身就提供了一套算完整的,使用来实现的,供外部的程序调用。安装需要安装,然后进行一些配置才可以正常使用,安装方法有两种。命令在中使用方式是客户端方法参数例子。重启再次测试,。

简述
接触了saltstack感觉十分强大,非常适合做自动化运维。本文介绍下salt-api的简单使用。后续打算用django + saltsatck做一个web界面的自动化运维平台。
salt-api介绍

saltsatck本身就提供了一套算完整的api,使用 CherryPy 来实现 restful 的 api,供外部的程序调用。

salt-api安装

salt-api需要安装,然后进行一些配置才可以正常使用,安装方法有两种。
方法一:
yum安装,需要的依赖包cherry也会被补全装上。
安装salt-api,并设置开机启动

yum -y install salt-api pyOpenSSL 
systemctl enable salt-api

方法二:
pip安装,首先要确认机器上有没有安装pip模块。

rpm -ivh https://mirrors.aliyun.com/epel/7/x86_64/s/salt-api-2015.5.10-2.el7.noarch.rpm
pip install cherrypy==3.2.3
pip install cherrypy
pip install salt-api
配置自签名证书
cd /etc/pki/tls/certs/
make testcert



Enter pass phrase:    ===>  输入加密短语,这里我使用salt2017
Verifying - Enter pass phrase:    ===>  确认加密短语
umask 77 ; 
/usr/bin/openssl req -utf8 -new -key /etc/pki/tls/private/localhost.key -x509 -days 365 -out /etc/pki/tls/certs/localhost.crt -set_serial 0
Enter pass phrase for /etc/pki/tls/private/localhost.key:    ===>  再次输入相同的加密短语
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter ".", the field will be left blank.
-----
Country Name (2 letter code) [XX]:CN
State or Province Name (full name) []:BeiJing
Locality Name (eg, city) [Default City]:BeiJing
Organization Name (eg, company) [Default Company Ltd]:
Organizational Unit Name (eg, section) []:
Common Name (eg, your name or your server"s hostname) []:
Email Address []:

解密key文件,生成无密码的key文件, 过程中需要输入key密码,该密码为之前生成证书时设置的密码

cd /etc/pki/tls/private/
openssl rsa -in localhost.key -out localhost_nopass.key

修改文件权限

chmod 755 /etc/pki/tls/certs/localhost.crt 
chmod 755 /etc/pki/tls/private/localhost.key 
chmod 755 /etc/pki/tls/private/localhost_nopass.key
添加用户

生产环境请使用密码复杂度高的密码,这里我使用salt2017

useradd -M -s /sbin/nologin saltapi
passwd saltapi        
配置salt-api

修改/etc/salt/master文件

sed -i "/#default_include/s/#default/default/g" /etc/salt/master

创建/etc/salt/master.d/目录

mkdir -p /etc/salt/master.d/
cd /etc/salt/master.d/
touch eauth.conf
touch api.conf

编辑eauth.conf,添加下面内容

external_auth:
  pam:
    saltapi:   # 用户
      - .*     # 该配置文件给予saltapi用户所有模块使用权限,出于安全考虑一般只给予特定模块使用权限

编辑api.conf,添加下面内容

rest_cherrypy:
  port: 8001
  ssl_crt: /etc/pki/tls/certs/localhost.crt
  ssl_key: /etc/pki/tls/private/localhost_nopass.key
启动salt-api
systemctl restart salt-master
systemctl start salt-api
ps -ef|grep salt-api
netstat -lnput|grep 8001
验证服务

获得token

curl -k https://172.16.0.19:8001/login -H "Accept: application/x-yaml"  -d username="saltapi"  -d password="salt2017"  -d eauth="pam"
return:
- eauth: pam
  expire: 1494365711.173652
  perms:
  - .*
  start: 1494322511.173652
  token: f40623825ea02606bfc558c982dbbfbb923c7570
  user: saltapi

调用test.ping

curl -k https://172.16.0.19:8001/ -H "Accept: application/x-yaml" -H "X-Auth-Token: f40623825ea02606bfc558c982dbbfbb923c7570" -d client="local" -d tgt="*" -d fun="test.ping"
return:
- client1: true
  saltstack: true
编写python脚本请求salt api接口

自定义一个类,首先初始化时候获得token,然后使用token认证去请求相应的json文件。
salt命令在shell中使用方式是salt 客户端 方法 参数(例子:salt "client1" cmd.run "free -m")
这里salt命令方法我们已经封装好了,想使用salt的什么方法就传入对应的客户端、方法、参数即可。
代码如下:

#!/usr/bin/env python
# _*_ coding:utf-8 _*_
__author__ = "junxi"


import requests
import json
try:
    import cookielib
except:
    import http.cookiejar as cookielib

# 使用urllib2请求https出错,做的设置
import ssl
context = ssl._create_unverified_context()

# 使用requests请求https出现警告,做的设置
from requests.packages.urllib3.exceptions import InsecureRequestWarning
requests.packages.urllib3.disable_warnings(InsecureRequestWarning)


salt_api = "https://172.16.0.19:8001/"


class SaltApi:
    """
    定义salt api接口的类
    初始化获得token
    """
    def __init__(self, url):
        self.url = url
        self.username = "saltapi"
        self.password = "salt2017"
        self.headers = {
            "User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 Safari/537.36",
            "Content-type": "application/json"
            # "Content-type": "application/x-yaml"
        }
        self.params = {"client": "local", "fun": "", "tgt": ""}
        # self.params = {"client": "local", "fun": "", "tgt": "", "arg": ""}
        self.login_url = salt_api + "login"
        self.login_params = {"username": self.username, "password": self.password, "eauth": "pam"}
        self.token = self.get_data(self.login_url, self.login_params)["token"]
        self.headers["X-Auth-Token"] = self.token

    def get_data(self, url, params):
        send_data = json.dumps(params)
        request = requests.post(url, data=send_data, headers=self.headers, verify=False)
        # response = request.text
        # response = eval(response)     使用x-yaml格式时使用这个命令把回应的内容转换成字典
        # print response
        # print request
        # print type(request)
        response = request.json()
        result = dict(response)
        # print result
        return result["return"][0]

    def salt_command(self, tgt, method, arg=None):
        """远程执行命令,相当于salt "client1" cmd.run "free -m""""
        if arg:
            params = {"client": "local", "fun": method, "tgt": tgt, "arg": arg}
        else:
            params = {"client": "local", "fun": method, "tgt": tgt}
        print "命令参数: ", params
        result = self.get_data(self.url, params)
        return result

def main():
    print "=================="
    print "同步执行命令"
    salt = SaltApi(salt_api)
    print salt.token
    salt_client = "*"
    salt_test = "test.ping"
    salt_method = "cmd.run"
    salt_params = "free -m"
    # print salt.salt_command(salt_client, salt_method, salt_params)
    # 下面只是为了打印结果好看点
    result1 = salt.salt_command(salt_client, salt_test)
    for i in result1.keys():
        print i, ": ", result1[i]
    result2 = salt.salt_command(salt_client, salt_method, salt_params)
    for i in result2.keys():
        print i
        print result2[i]
        print

if __name__ == "__main__":
    main()

查看运行结果
第一行请求认证的token。
从结果可以看出来我们请求了两条命令,test.ping和free -m

==================
同步执行命令
83ad5789cf8046ff06972e1f92bb31f012609a78
命令参数:  {"fun": "test.ping", "client": "local", "tgt": "*"}
client1 :  True
saltstack :  True
命令参数:  {"fun": "cmd.run", "client": "local", "tgt": "*", "arg": "free -m"}
client1
              total        used        free      shared  buff/cache   available
Mem:            220         153           7           2          59          31
Swap:          2046         129        1917

saltstack
              total        used        free      shared  buff/cache   available
Mem:            976         516          83          24         376         260
Swap:          2046           0        2046

请求异步执行salt命令后的jid结果,首先要修改/etc/salt/master.d/eauth.conf 配置文件,增加权限,然后重启salt-master和salt-api。

cd /etc/salt/master.d/
vi eauth.conf
# 修改内容如下:
external_auth:
  pam:
    saltapi:
      - .*
      - "@runner"
      - "@wheel"

python编写异步请求模块

def salt_async_command(self, tgt, method, arg=None):  # 异步执行salt命令,根据jid查看执行结果
    """远程异步执行命令"""
    if arg:
        params = {"client": "local_async", "fun": method, "tgt": tgt, "arg": arg}
    else:
        params = {"client": "local_async", "fun": method, "tgt": tgt}
    jid = self.get_data(self.url, params)["jid"]
    return jid

def look_jid(self, jid):  # 根据异步执行命令返回的jid查看事件结果
    params = {"client": "runner", "fun": "jobs.lookup_jid", "jid": jid}
    print params
    result = self.get_data(self.url, params)
    return result

查看执行结果

def main():
    print
    print "=================="
    print "异步执行命令"
    salt1 = SaltApi(salt_api)
    salt_client = "*"
    salt_method = "cmd.run"
    salt_params = "df -hT"
    # 下面只是为了打印结果好看点
    jid1 = salt1.salt_async_command(salt_client, salt_test)
    result1 = salt1.look_jid(jid1)
    for i in result1.keys():
        print i, ": ", result1[i]

    jid2 = salt1.salt_async_command(salt_client, salt_method, salt_params)
    result2 = salt1.look_jid(jid2)
    for i in result2.keys():
        print i
        print result2[i]
        print


if __name__ == "__main__":
    main()
==================
异步执行命令
{"fun": "jobs.lookup_jid", "jid": u"20170525095342243770", "client": "runner"}
saltstack :  True
client1 :  True
{"fun": "jobs.lookup_jid", "jid": u"20170525095342994269", "client": "runner"}
client1
Filesystem     Type      Size  Used Avail Use% Mounted on
/dev/sda2      xfs        17G   13G  4.1G  77% /
devtmpfs       devtmpfs   97M     0   97M   0% /dev
tmpfs          tmpfs     111M   12K  111M   1% /dev/shm
tmpfs          tmpfs     111M  4.7M  106M   5% /run
tmpfs          tmpfs     111M     0  111M   0% /sys/fs/cgroup
/dev/sda1      xfs       297M  202M   96M  68% /boot

saltstack
Filesystem     Type      Size  Used Avail Use% Mounted on
/dev/sda2      xfs        17G  7.2G  9.9G  43% /
devtmpfs       devtmpfs  475M     0  475M   0% /dev
tmpfs          tmpfs     489M   16K  489M   1% /dev/shm
tmpfs          tmpfs     489M  6.9M  482M   2% /run
tmpfs          tmpfs     489M     0  489M   0% /sys/fs/cgroup
/dev/sda1      xfs       297M  202M   96M  68% /boot
salt-api二次开发遇到的问题

对salt-api进行了二次开发,通过api控制minion,可能会遇到发送命令线程就进入了等待,然后就是超时。
解决方法:salt.netapi.rest_cherrypy包里面有一个app.py方法,修改"server.thread_pool": self.apiopts.get("thread_pool", 100)为200,修改"server.socket_queue_size": self.apiopts.get("queue_size", 30)为300 。重启salt-api 再次测试,OK。

vi /usr/lib/python2.7/site-packages/salt/netapi/rest_cherrypy/app.py
修改下面两行内容
"server.thread_pool": self.apiopts.get("thread_pool", 100),
"server.socket_queue_size": self.apiopts.get("queue_size", 30),
为
"server.thread_pool": self.apiopts.get("thread_pool", 200),
"server.socket_queue_size": self.apiopts.get("queue_size", 300),

重启salt-api

systemctl restart salt-api

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/41604.html

相关文章

  • 计算机网络(HCIP、HCIE)系列文章大合集

    摘要:近期,我写了很多计算机网络系列文章,适合备考人员查阅,先将各文章整理如下衷心建议您收藏,慢慢查阅一基础入门知识计算机网络基础计算机网络误区源目和源目变化问题计算机网络误区中和原理详解计算机网络误区为什么我的包发不出去计 ...

    gitmilk 评论0 收藏0
  • 八问WebSocket协议:为你快速解答WebSocket热门疑问

    一、引言 WebSocket是一种比较新的协议,它是伴随着html5规范而生的,虽然还比较年轻,但大多主流浏览器都已经支持。它使用方面、应用广泛,已经渗透到前后端开发的各种场景中。 对http一问一答中二式流程(就是从所周之的长轮询技要啦)的不满,催生了支持双向通信的WebSocket诞生。WebSocket是个不太干净协议。 本文将从8个常见的疑问入手,为还不了解WebSocket协议的开发者快...

    Zoom 评论0 收藏0
  • 工具使用-积累与发现

    摘要:一积累中如何快速查看包中的源码最常用的大开发快捷键技巧将对象保存到文件中从文件中读取对象中的用法的配置详解和代码的格式详解格式化内容设置生成详解注释规范中设置内存调试的小知识单步执行命令的区别的动态代理机制详解内容有瑕疵,楼指正泛型继承的几 一、积累 1.JAVA Eclipse中如何快速查看jar包中 的class源码 最常用的15大Eclipse开发快捷键技巧 Java将对象保存到...

    wangjuntytl 评论0 收藏0
  • 工具使用-积累与发现

    摘要:一积累中如何快速查看包中的源码最常用的大开发快捷键技巧将对象保存到文件中从文件中读取对象中的用法的配置详解和代码的格式详解格式化内容设置生成详解注释规范中设置内存调试的小知识单步执行命令的区别的动态代理机制详解内容有瑕疵,楼指正泛型继承的几 一、积累 1.JAVA Eclipse中如何快速查看jar包中 的class源码 最常用的15大Eclipse开发快捷键技巧 Java将对象保存到...

    Lyux 评论0 收藏0
  • 工具使用-积累与发现

    摘要:一积累中如何快速查看包中的源码最常用的大开发快捷键技巧将对象保存到文件中从文件中读取对象中的用法的配置详解和代码的格式详解格式化内容设置生成详解注释规范中设置内存调试的小知识单步执行命令的区别的动态代理机制详解内容有瑕疵,楼指正泛型继承的几 一、积累 1.JAVA Eclipse中如何快速查看jar包中 的class源码 最常用的15大Eclipse开发快捷键技巧 Java将对象保存到...

    tomener 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<