zoukankan      html  css  js  c++  java
  • CMDB01 /paramiko模块、项目概述、项目架构、项目实现

    CMDB01 /paramiko模块、项目概述、项目架构、项目实现

    1. paramiko

    • 用于帮助开发者通过代码远程连接服务器,并对服务器进行操作。

      pip3 install paramiko 
      
    • 远程执行命令【用户名和密码】

         import paramiko
         
         # 创建SSH对象
         ssh = paramiko.SSHClient()
         
         # 允许连接不在know_hosts文件中的主机
         ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
         
         # 连接服务器
         ssh.connect(hostname='192.168.16.85', port=22, username='root', password='123456')
         
         # 执行命令
         stdin, stdout, stderr = ssh.exec_command('df')
         # 获取命令结果
         result = stdout.read()
         # 关闭连接
         ssh.close()
         
         print(result.decode('utf-8'))
         
      
    • 远程执行命令【公钥和私钥】(公钥必须提前上传到服务器)

         import paramiko
         
         private_key = paramiko.RSAKey.from_private_key_file(r'C:/Users/Administrator/.ssh/id_rsa')
         
         # 创建SSH对象
         ssh = paramiko.SSHClient()
         # 允许连接不在know_hosts文件中的主机
         ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
         # 连接服务器
         ssh.connect(hostname='192.168.16.85', port=22, username='root', pkey=private_key)
         
         # 执行命令
         stdin, stdout, stderr = ssh.exec_command('df')
         # 获取命令结果
         result = stdout.read()
         
         # 关闭连接
         ssh.close()
         
         print(result)
         
      
    • 远程上传和下载文件【用户名和密码】

         import paramiko
         
         transport = paramiko.Transport(('192.168.16.85', 22))
         transport.connect(username='root', password='123456')
         sftp = paramiko.SFTPClient.from_transport(transport)
         
         
         # 将location.py 上传至服务器 /tmp/test.py
         sftp.put('wy.txt', '/data/wy.txt')
         # 将location.py 下载到本地 /tmp/test.py
         sftp.get('/data/wy.txt', 'xx.txt')
         
         transport.close()
         
      
    • 远程上传和下载文件【公钥和私钥】

         import paramiko
         
         private_key = paramiko.RSAKey.from_private_key_file(r'C:/Users/Administrator/.ssh/id_rsa')
         
         transport = paramiko.Transport(('192.168.16.85', 22))
         transport.connect(username='root', pkey=private_key)
         
         sftp = paramiko.SFTPClient.from_transport(transport)
         # 将location.py 上传至服务器 /tmp/test.py
         # sftp.put('/tmp/location.py', '/tmp/test.py')
         
         # 将remove_path 下载到本地 local_path
         # sftp.get('remove_path', 'local_path')
         
         transport.close()
         
      
    • 通过私钥字符串也可以连接远程服务器

         key = """-----BEGIN RSA PRIVATE KEY-----
         MIIG5AIBAAKCAYEAu0fkMInsVRnIBSiZcVYhKuccWCh6hapYgB1eSOWZLz3+xFGy
         G5p2z8HgiHzfT838gAm+5OajuyAuE4+fHI77LXSg+pLbr1FhPVKAP+nbsnLgvHty
         ykZmt74CKKvZ08wdM7eUWJbkdpRNWmkwHBi99LeO0zYbHdXQ+m0P9EiWfdacJdAV
         RDVCghQo1/IpfSUECpfQK1Hc0126vI8nhtrvT3V9qF420U1fwW9GJrODl71WRqvJ
         BgSsKsjV16f0RKARESNmtA2vEdvMeutttZoO4FbvZ+iLKpcRM4LGm2+odryr8ijv
         dCPCLVvoDExOPuqP1dgt5MWcCWf6ZNhMwAs/yvRHAKetvo5gtz8YvzwlikopCLM7
         bS6C6woyppMHfIPjoGJ6JuKpeaWtAgugOw/oVvj1rRYoCv48R13NftqhkFD1KD8z
         km9CjDC8hv+2DmIedtjvVwUz2QF4PN/RC/i1jo3+3rbP1DLu9emTHiortBBrpQ5o
         K+y4Rzv+6NusD6DHAgMBAAECggGBAJ4hTaNOUaZpZmI0rZrsxoSbL2ugghNqid9i
         7MFQW89v4TWSZXi5K6iwYw3bohKYMqNJl01fENBnk4AgvJA4ig0PdP0eEzAs3pYQ
         mwlcRIygQvHiqkHwv7pVTS1aLUqQBfgtAazre2xEPCwitOSEX5/JfWcJQEwoxZMt
         k1MIF0mZc67Zy5sT/Vwn+XScnDt2jbsEBFkPfg1aDto3ZYCQS5Aj/D21j0OauUdy
         1SDIYkw1Kivx0IKsX1Kg0S6OOcnX/B6YrJvisrlQDeZnWlTsTyKSVTekIybJjUHE
         ZgLIIbifSbTW1Bv1iCkDAJBd4Cj4txjXPIgea9ylZ39wSDSV5Pxu0t/M3YbdA26j
         quVFCKqskNOC+cdYrdtVSij2Ypwov67HYsXC/w32oKO7tiRqy51LAs/WXMwQeS5a
         8oWDZLiYIntY4TCYTVOvFlLRtXb+1SbwWKjJdjKvdChv4eo/Ov5JEXD2FVbVC/5E
         Qo3jyjIrt1lrwXUdpJa0/iz4UV33wQKBwQDprCPZVCI7yK/BWTmUvCcupotNk6CC
         +QIKDcvVxz63YFD5nXto4uG7ywXR6pEwOwmycO0CBuouvlPdSioQ3RYi6k0EO3Ch
         9dybC5RZ3MENBHROHvU3mp01EWPUYnXAwNpvknujJqfXMxyURZvvox7hOnu/s3m4
         C3eCBrMMg+uqNZDbLqAymw3pMGhHVWjy5oO8eLuLeJv6er+XoSSPNb21Da7StdQS
         fBPQ1H0/+RXnhFJOzANc4mRZcXMCNGVZX6MCgcEAzSz3evuCRQ47AaSOrDd89jAw
         PgpT+PG4gWw1jFZqHTbQ8MUl3YnElOVoaWRdIdDeslg9THg1cs5Yc9RrbIibyQjV
         F9k/DlXGo0F//Mgtmr7JkLP3syRl+EedRbu2Gk67XDrV7XIvhdlsEuSnEK9xOiB6
         ngewM0e4TccqlLsb6u7RNMU9IjMu/iMcBXKsZ9Cr/DENmGQlTaRVt7G6UcAYGNgQ
         toMoCQWjR/HihlZHssLBj9U8uPyD38HKGy2OoXyNAoHBAKQzv9lHYusJ4l+G+IyJ
         DyucAsXX2HJQ0tsHyNYHtg2cVCqkPIV+8UtKpmNVZwMyaWUIL7Q98bA5NKuLIzZI
         dfbBGK/BqStWntgg8fWXx90C5UvEO2MAdjpFZxZmvgJeQuEmWVVTo5v4obubkrF5
         ughhVXZng0AOZsNrO8Suqxsnmww6nn4RMVxNFOoTnbUawTXezUN71HfWa+38Ybl0
         9UNWQyR0e3slz7LurrkWqwrOlBwlBrPtrsCflUbWVOXR6wKBwDFq+Dy14V2SnOG7
         aeXPA5kkaCo5QJqAVglOL+OaWLqqnk6vnXwrl56pVqmz0762WT0phbIqbe02CBX1
         /t3IVYVpTDIPUGG6hTqDJzmSWXGhLFlfD3Ulei3/ycCnAqh5eCUxwp8LVqjtgltW
         mWqqZyIx+nafsW/YgWqyYu4p1wKR/O+x5hSbsWDiwfgJ876ZgyMeCYE/9cAqqb6x
         3webtfId8ICVPIpXwkks2Hu0wlYrFIX5PUPtBjJZsb00DtuUbQKBwF5BfytRZ0Z/
         6ktTfHj1OJ93hJNF9iRGpRfbHNylriVRb+hjXR3LBk8tyMAqR4rZDzfBNfPip5en
         4TBMg8UATf43dVm7nv4PM2e24CRCWXMXYl7G3lFsQF/g7JNUoyr6bZQBf3pQcBw4
         IJ38IcKV+L475tP4rfDrqyJz7mcJ+90a+ai5cSr9XoZqviAqNdhvBq5LjGOLkcdN
         bS0NAVVoGqjqIY/tOd2NMTEF6kVoYfJ7ZJtjxk/R3sdbdtajV3YsAg==
         -----END RSA PRIVATE KEY-----"""
         
         
         import paramiko
         from io import StringIO
         
         private_key = paramiko.RSAKey(file_obj=StringIO(key))
         
         # 创建SSH对象
         ssh = paramiko.SSHClient()
         # 允许连接不在know_hosts文件中的主机
         ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
         # 连接服务器
         ssh.connect(hostname='192.168.16.85', port=22, username='root', pkey=private_key)
         
         # 执行命令
         stdin, stdout, stderr = ssh.exec_command('df')
         # 获取命令结果
         result = stdout.read()
         
         # 关闭连接
         ssh.close()
         
         print(result)
         
      

    2. 基于xshell连接服务器

    • 用户名和密码

    • 公钥和私钥(rsa)

      • 生成公钥和私钥

        ssh-keygen.exe -m pem
           
        在当前用户家目录会生成: .ssh/id_rsa.pub    .ssh/id_rsa
        
      • 把公钥放到服务器

        ssh-copy-id -i ~.ssh/id_rsa.pub root@192.168.16.85 
        
      • 以后再连接服务器时,不需要在输入密码

        ssh root@192.168.16.85 
        

    3. 项目概述

    • 背景

      • 大目标:运维自动化
      • 小目标:资产管理(以前用的excel)
      - 大公司:物理机1200 > 6000
      - 中:物理机70台
      - 小:阿里云(虚拟机)
      

      系统开发出来时候,可以自动化采集资产信息,并且给其他系统提供数据支持。

    • 运维:

      • 业务
      • IDC
      • 桌面
      • 监控
    • 物理机和虚拟机

      • 物理机:托管在兆维、世纪互联机房。
      • 虚拟机(云服务器):阿里云、腾讯云、aws

    4. 项目架构

    • 项目结构图

    • 项目有三部分组成:

      • 资产采集,用于远程连接服务器并获取服务器的资产信息,然后将资产信息汇报API
      • API,负责将资产信息写入数据库,并且要做资产变更记录,为了以后搭建运维自动化平台,可以为其他系统提供restful接口做数据支持。
      • 资产管控平台,为用户提供数据展示和报表。
    • 采集资产的方式:

      • 基于SSH(paramiko),70台物理机

      • ansible管理工具(saltstack、puppet)

      • 基于agent(客户端),1200台物理机

    5. 项目实现(资产采集、API)

    5.1 资产采集流程

    • 脚本

      import paramiko
      
      # 创建SSH对象
      ssh = paramiko.SSHClient()
      # 允许连接不在know_hosts文件中的主机
      ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
      # 连接服务器
      ssh.connect(hostname='192.168.16.85', port=22, username='root', password='123456')
      # 执行命令
      stdin, stdout, stderr = ssh.exec_command('df')
      # 获取命令结果
      result = stdout.read()
      # 关闭连接
      ssh.close()
      data = result.decode('utf-8')[0:10]
      
      
      # 将资产信息提交到api : POST http://127.0.0.1:8000/api/v1/server/
      """
      pip3 install requests
      """
      import requests
      
      """
      content-type:x-www-form-encode..
      数据格式:server=xxx&host=kkkk
      """
      # requests.post(
      #     url="http://127.0.0.1:8000/api/v1/server/",
      #     data={'server':data,'host':'192.168.16.88'}
      # )
      
      """
      content-type:application/json
      数据格式:{'server': 'Filesystem', 'host': '192.168.16.88'}
      """
      requests.post(
          url="http://127.0.0.1:8000/api/v1/server/",
          json={'server':data,'host':'192.168.16.88'}
      )
      
    • api

      from rest_framework.views import APIView
      from rest_framework.response import Response
      class ServerView(APIView):
          def post(self,request,*args,**kwargs):
              print(request.data)
              return Response('发送成功')
      

    5.2 采集多个资产信息(CPU、内存等)

    总结

    1. 为什么要开发CMDB?

      公司以后想要搭建自动化运维平台,CMDB是搭建平台的基石。
      目前而言,公司资产信息不够准确,因为都维护在excel中,维护主要人,通过cmdb可以自动采集资产信息以及做资产变更记录。
      
    2. 你们公司有多少台服务器?物理机?虚拟机?

      100台左右物理机。
      
    3. 你的CMDB是如何实现的?

      cmdb是由三部分组成,其中包含:资产采集的中控机、API、资产管控平台。
      对于资产采集部分,通过paramiko远程操作服务器(本质SSH)并采集资产信息,然后将资产信息汇报到API,在资产采集部分还继承了可扩展的功能,让我们定制插件时可以更加方便,实现起来也比较简单,参考django中间件的原理、开发封闭原则、工厂模式实现可插拔式的插件。 
      api,基于restful规范和drf组件来实现完成,主要做资产入库以及资产变更处理。 
      资产管控平台,对资产数据进行数据呈现和报表的处理。
      
    4. 你的程序有什么Bug?难以忘记的经历?

      对于bug没有太多印象,主要在资产采集可扩展性方面。。。。。
      
    5. 技术点

      • 类的约束

      • 通过字符串的形式导入一个模块

        import importlib
        module = importlib.import_module("xxx.xx.xx.csss")
        
      • 反射,通过字符串形式去操作对象中属性

        getattr
        setattr
        delattr
        hasattr
        
      • 线程池的应用

      • 导入包时,自动加载 __init__.py

      • requests模块的应用

        requests.get(url='...')
        
        requests.post(url="...",data={})
        
        requests.post(url="...",json={})
        
      • 项目中容易被修改的值,可以放在配置文件中。

      • 开放封闭原则

        • 配置开放
        • 源码封闭
      • 工厂模式:简单工厂

        mode = "email"
        
        class Email(object):
        	def send(self):
        		pass
        
        class Wechat(object):
        	def send(self):
        		pass
        		
        class Message(object):
        	def send(self):
        		pass
        
        def run():
        	instance = None 
        	if mode == 'email':
        		instance = Email()
        	elif mode == 'wechat':
        		instance = Wechat()
        	elif mode == 'message':
        		insance = Message()
        		
        	if not instance:
        		print('配置异常')
        	instance.send()
        	
        run()
        
      • 工厂模式:工厂方法/抽象工厂

        mode = "xxx.xx.Email"
        
        class Email(object):
        	def send(self):
        		pass
        
        class Wechat(object):
        	def send(self):
        		pass
        		
        class Message(object):
        	def send(self):
        		pass
        
        def run():
        	# 根据反射到类,并实例化。
        	instance.send()
        run()
        
  • 相关阅读:
    Atitit attilax要工作研究的要素 纪要 方案 趋势 方向 概念 理论
    Atitit 常见每日流程日程日常工作.docx v7 r8f
    Atitit it 互联网 软件牛人的博客列表
    Atitit 信息链(Information Chain)的概念理解 attilax总结
    Atitit 知识点的体系化 框架与方法 如何了解 看待xxx
    Atitit 聚合搜索多个微博 attilax总结
    Atitit 企业知识管理PKM与PIM
    Atitit 项目沟通管理 Atitit 沟通之道 attilax著.docx
    Atitit 项目管理软件 在线服务 attilax总结 1. 项目管理协作的历史 1 1.1. Worktile 406k 1 1.2. Teambition  584k in baidu
    Atitit.每周末总结 于每周一计划日程表 流程表 v8 import 上周遗漏日志补充 检查话费 检查流量情况 Crm问候 Crm表total and 问候
  • 原文地址:https://www.cnblogs.com/liubing8/p/11853664.html
Copyright © 2011-2022 走看看