CMDB项目

运维愿景

  1. 自动装机
  2. 配置管理
  3. 监控
  4. 堡垒机
  5. 日志监控
  6. 资产管理【必备】

为什么开发CMDB?

  • 囧境:Excel维护资产信息,资产变更时难以保证Excel表正确性;信息交换不方便。
  • 目标:自动采集资产工具,自动汇报,保存变更记录。
  • 最终目标:实现运维自动化

了解CMDB架构

 a. cmdb架构大概分为三部分:

  • 资产采集
  • API(接受数据保存入库,对外提供数据接口)
  • 后台管理
1. Agent方式
    
    API:Django接收数据并入库
    
    程序:放置在每台服务器
    
    应用场景:针对服务器较多的公司
    
2. SSH方式
    
    API:Django接收数据并入库
    
    程序:放在中控机
    
    应用场景:针对服务器较少的公司
    
    SSH方式有三种工具,paramiko、Fabric、Ansible,其中Fabric、Ansible内部原理也是通过paramiko来实现得。
    paramiko安装:pip3 install paramiko
    
3. saltstack【python语言】 
    
    http://www.cnblogs.com/wupeiqi/articles/6415436.html
    
    API:Django接收数据并入库
    
    应用场景:针对服务器较多的公司【推荐】

    master:
        v = subprocess.getoutput('salt "*" cmd.run "ls"')
    
    saltstack内部原理是通过RPC来实现得消息队列

4. puppet【ruby语言】
    
    内部原理:puppet客户端每30秒钟自动汇报数据给puppet服务端。
    
    应用场景:主要是针对已经在使用puppet的公司。
四种架构模式

b. 主要负责内容: 资产采集

  • 三种方案方案:agent、paramiko、saltstack。
  • 为了提高扩展性,参考了Django的配置文件和中间件(反射)
  • 异常:错误堆栈信息

c. 开发期间遇到得难题(坑):

  • 唯一标识【标准化】

CMDB实现目标:实现兼容Agent、SSH、saltstack 以上三种方式。

简易实现方式:

# #################### Agent,每一台服务器一份 ####################
# import subprocess
# v1 = subprocess.getoutput('ipconfig')
# value1 = v1[20:30]
#
# v2 = subprocess.getoutput('dir')
# value2 = v2[0:5]
#
# # 连接数据库,写到数据库
#
# url = "http://127.0.0.1:8000/asset.html"
# import requests
#
# response = requests.post(url,data={'k1':value1,'k2':value2})
# print(response.text)


# ####################  saltstack ##########################
# v = subprocess.getoutput('salt "*" cmd.run "ls"')


# #################### Paramiko,中控机放一份 ####################
"""
- 远程连接服务器,执行命令,获取结果
- 将结果发送API
192.168.11.98
"""

import paramiko

# 创建SSH对象
ssh = paramiko.SSHClient()
# 允许连接不在know_hosts文件中的主机
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
# 连接服务器
ssh.connect(hostname='192.168.11.98', port=22, username='wupeiqi', password='123')

# 执行命令
stdin, stdout, stderr = ssh.exec_command('ls')
# 获取命令结果
result = stdout.read()

# 关闭连接
ssh.close()

value = result[0:10]
print(value)

url = "http://127.0.0.1:8000/asset.html"
import requests

response = requests.post(url,data={'k1':value,'k2':value})
print(response.text)
autoclient
from django.shortcuts import render,HttpResponse

def asset(request):
    if request.method == "POST":
        print(request.POST)
        # 写入到数据
        return HttpResponse('1002')
    else:
        return HttpResponse('姿势不对')
autoserver

补充Paramiko和SaltStack操作

 开发周期:

  两三个月

提高扩展性:

  参考Django:配置,中间件(反射)

有没有遇到难题:

难题,不应该是技术问题,技术问题都可以攻破。难题应该是业务问题。

  1. 错误堆栈信息
  2. Linux不太熟悉
  3. 唯一标识

唯一标识

  • 主机名是唯一标识,依赖本地文件

    注意:不建议使用主板SN,虚拟机中的SN号会重复,例如openstack等。

  • 流程:
    装机前,录入主机名、机房、机柜、机柜位置等信息。
    装机时,将服务信息录入CMDB,c1.com。
    资产采集:c1.com。
  • 步骤:
    a. 装系统,初始化软件(CMDB),运行CMDB:    
        - 通过命令获取主机名
        - 写入本地指定文件
    b.     - 将资产信息发送到API
    c. 获取资产信息:
        - 判断本地文件主机名和命令获取的主机名是否一致(如果不一致,按照文件中的主机名)
  • 最终流程:标准化:主机名不重复;流程标准化(装机同时,主机名在cmdb中设置)
  • 服务器资产采集(Agent):
    a. 第一次:文件不存在,或内容为空;
       采集资产:
            - 主机名写入文件
            - 发送API
                    
    b. 第N次:采集资产,主机名:文件中获取

    服务器资产采集(SSH或Salt):

    中控机:获取未采集主机名列表:【c1.com】
  • 代码:
    server_info = PluginManager().exec_plugin()
    hostname = server_info['basic']['data']['hostname']
    certname = open(settings.CERT_PATH,'r',encoding='utf-8').read().strip()
    if not certname:
        with open(settings.CERT_PATH,'w',encoding='utf-8') as f:
            f.write(hostname)
    else:
        server_info['basic']['data']['hostname'] = certname

     

 为什么要进行API验证:

  在数据传输过程中保证数据不被篡改,为了保证数据安全,数据只给通过验证的人看

API验证是如何设计的:

  这个设计我借鉴了Tornado中的加密Cookie来实现的,根据client_key+time 进行MD5创建动态的KEY,总共有三个限制:第一个,是时间,如果时间超过服务端两秒直接return;第二个,把客户端的ctime取出来,和把事先存到服务端的字符串和客户端一样的那个字符串进行md5加密,用这个加密的结果和客户端发来的加密结果进行对比,如果一样就通过,否则就return;第三个,我们在服务端维护了一个字典,字典中放的是最近2s内访问的client_md5_ctime_key和客户时间+2s组成的键值对,如果传过来的这个值在字典中有的话我们就return,在for循环查字典的时候顺便把超时的删掉,如果通过,就把他放到字典里面。

  还有一个问题就是如果黑客的网速比我们快的话(外网会发生),会比我们先到API这个时候我们需要对请求进行加密,这个是借鉴微信的加密方式,也就是AES加密方式。

 

 

 

 

 

 

 

 

 

subprocess参考文档:python基础之常用模块

参考博客:http://www.cnblogs.com/wupeiqi/articles/4786871.html

     http://www.cnblogs.com/wupeiqi/articles/4556300.html

     http://www.cnblogs.com/nulige/p/6703160.html

     http://www.hairuinet.com/python/201704111/index.html

 

    

posted @ 2017-07-26 15:54  luchuangao  阅读(587)  评论(0编辑  收藏  举报