zoukankan      html  css  js  c++  java
  • CMDB

    一:IT运维的分类

      IT运维,指的是对已经搭建好的网络、软件、硬件进行维护。运维领域也是细分的,有硬件运维和软件运维。

      硬件运维主要包括对基础设施的运维,例如机房的设备,主机的键盘,内存等物理设备的维护。

      软件运维主要包括系统运维和应用运维,系统运维主要包括对OS,数据库,中间件的监控和维护,这些系统介于设备和应用之间,应用运维主要是对线上业务系统的运维。

      这里主要讨论的是软件运维的自动化,包括系统运维和应用运维的自动化。

    二:传统运维的缺点

      1:日常工作繁琐

      日常运维工作繁琐,研发会经常需要到服务器上查看日志,重启应用,或者是上线某个产品需要部署环境等,都是运维的日常。

      2:应用运行环境不统一

      在部署某个应用后,应用不能访问,在开发环境运行的好,但是在测试环境后就不能继续用了,因为各类环境的类库不统一。还有一种情况是,由于运维人员的习惯不同,按照自己的习惯来安装部署环境,每种服务器上运行的软件目录不统一。

      3:运维及部署效率低下

      运维人员需要登录到服务器上执行命令,部署程序,不仅效率低,并且非常容易出现人为错误,人为出错之后也不容易找到问题所在。

      4:无用报警信息过多

      运维人员经常会收到很多的无用报警信息,常常会选择屏蔽这些报警信息,并且一旦应用的访问速度出了问题,就需要从系统、网络、应用、数据库等一步步查找信息。

      5:资产管理和应用系统混乱

      资产管理,服务管理经常记录在Excel或者文本里面,不便于管理。老员工由于熟悉不注重文档的维护,新员工入职时,资产才能更正一次。

    三:为什么需要自动化运维?

      1:项目上线

      流程:产品经理调研(画出原型图)-->定需求-->三方会谈(研发,产品经理,老大们)-->定日期-->测试项目-->最终上线-->应用运维

      目前:将代码打包给运维,运维解压上线

      问题:随着机器数量的线性增加,运维的工作量也是线性增加,重复而且是毫无意义的劳动

      解决:

        1:写一个shell脚本,进行部署

        2:搞一个自动化代码上线系统

          必要条件:服务器的各种信息(主机名,CPU,硬盘大小等)

      2:监控系统

      监测服务器的各种信息(硬盘是否满,CPU的使用率,内存使用率,网站服务运行是否正常)

      问题:之前简单的脚本,监测服务器的信息,比较麻烦

      解决:想将服务器的各种信息,以图表的形式展示在web界面上(可视化)

      必要条件:服务器的各种信息(主机名,CPU,硬盘大小等)

      3:自动装机系统

      问题:人工装机需要一台一台去装

      解决:搞一个装机系统,cobbler软件

      必要条件:服务器的各种信息(主机名,CPU等)

      4:Excel表格审计管理资产

    四:资产管理系统(CMDB)

    CMDB是所有运维工具的数据基础,CMDB全称Configuration Management Database

    1,CMDB包含的功能:

      1:用户管理,记录测试,开发,运维人员的用户表

      2:业务线管理,需要记录业务的详情

      3:项目管理,指定此项目需属于那条业务线,以及项目详情

      4:应用管理,指定此应用的开发人员,属于哪个项目,和代码地址,部署目录,部署集群,依赖的应用,软件等信息。

      5:主机管理,包括云主机,物理机,主机属于哪个集群,运行着哪些软件,主机管理员,连接着哪些网络设备,云主机的资源地,存储等相关信息。

      6:主机变更管理,主机的一些信息变更,例如管理员,所属集群等信息更改,连接的网络变更等。

      7:网络设备管理,主要记录网络设备的详细信息,及网络设备连接的上级设备

      8:IP管理,IP属于哪个主机,哪个网段,是否被占用等

    2,CMDB实现的四种方式:

      方式一:Agent方式

      可以将服务器上面的Agent程序作定时任务,定时将资产信息提交到指定API录入数据库

    本质就是在各个服务器上执行subprocess.getoutput("命令"),然后将每台机器上执行的结果返回给主句API,然后主机API收到这些数据之后,放到数据库中,最终通过web界面展现给用户。
    
    优点:速度快
    缺点:需要为每台服务器部署有关Agent程序
    使用场景:服务器比较多的时候

      方式二:ssh类实现方式(基于paramiko模块)

      中控机通过Paramiko(py模块)登录到各个服务器上,然后执行命令的方式去获取各个服务器上的信息。

    优点:没有Agent
    缺点:有一个中控机,速度慢
    使用场景:服务器比较少的时候

      方式三:salt-stack方式

    此方案本质上和第二种方案是差不多的流程,中控机发送命令给服务器执行。服务器将结果放入另一个队列中,中控机获取将服务信息发送到API进而录入到数据库。
    
    优点:速度快,开发成本低
    缺点:依赖于第三方工具
    使用场景:公司已经使用salt-stack软件

    saltstack的安装和配置

    1:安装和配置

    master端:
    """
    1. 安装salt-master
        yum install salt-master
    2. 修改配置文件:/etc/salt/master
        interface: 0.0.0.0    # 表示Master的IP 
    3. 启动
        service salt-master start
    """
    slave端:
    """
    1. 安装salt-minion
        yum install salt-minion
    2. 修改配置文件 /etc/salt/minion
        master: 10.211.55.4           # master的地址
        或
        master:
            - 10.211.55.4
            - 10.211.55.5
        random_master: True
        id: c2.salt.com                    # 客户端在salt-master中显示的唯一ID
    3. 启动
        service salt-minion start
    """
    View Code

    2:授权

    """
    salt-key -L                    # 查看已授权和未授权的slave
    salt-key -a  salve_id      # 接受指定id的salve
    salt-key -r  salve_id      # 拒绝指定id的salve
    salt-key -d  salve_id      # 删除指定id的salve
    """
    View Code

    3:执行命令

    在master服务器上对salve进行远程操作

    salt 'c2.salt.com' cmd.run  'ifconfig'

    基于API的方式

    import salt.client
    local = salt.client.LocalClient()
    result = local.cmd('c2.salt.com', 'cmd.run', ['ifconfig'])

    参考安装:

    http://www.cnblogs.com/tim1blog/p/9987313.html

    https://www.jianshu.com/p/84de3e012753

      方式四:puppet方式(Ruby写的,了解)

      每隔30分钟,通过RPC消息队列将执行的结果返回给用户

     AES介绍

    from Crypto.Cipher import AES 
    def encrypt(message):
        key = b'dfdsdfsasdfdsdfs'
        cipher = AES.new(key, AES.MODE_CBC, key)
        ba_data = bytearray(message,encoding='utf-8')
        v1 = len(ba_data)
        v2 = v1 % 16
        if v2 == 0:
            v3 = 16
        else:
            v3 = 16 - v2
        for i in range(v3):
            ba_data.append(v3)
        final_data = ba_data.decode('utf-8')
        msg = cipher.encrypt(final_data) # 要加密的字符串,必须是16个字节或16个字节的倍数
        return msg 
    # ############################## 解密 ##############################
    def decrypt(msg):
        from Crypto.Cipher import AES 
        key = b'dfdsdfsasdfdsdfs'
        cipher = AES.new(key, AES.MODE_CBC, key)
        result = cipher.decrypt(msg) # result = b'xe8xa6x81xe5x8axa0xe5xafx86xe5x8axa0xe5xafx86xe5x8axa0sdfsd									'
        data = result[0:-result[-1]]
        return str(data,encoding='utf-8')
    msg = encrypt('你好好爱好爱好sss')
    res = decrypt(msg)
    print(res)
    View Code

    字符串格式化字符

    String.prototype.format = function(args){
            return this.replace(/{(w+)}/g, function(s, i){
                return args[i];
            });
        };
    View Code

     CMDB表结构

    from django.db import models
    
    class UserProfile(models.Model):
        """
        用户信息
        """
        name = models.CharField(u'姓名', max_length=32)
        email = models.EmailField(u'邮箱')
        phone = models.CharField(u'座机', max_length=32)
        mobile = models.CharField(u'手机', max_length=32)
        password = models.CharField(u'密码', max_length=64)
        class Meta:
            verbose_name_plural = "用户表"
        def __str__(self):
            return self.name
    
    class UserGroup(models.Model):
        """
        用户组
        """
        name = models.CharField(max_length=32, unique=True)
        users = models.ManyToManyField('UserProfile')
        class Meta:
            verbose_name_plural = "用户组表"
        def __str__(self):
            return self.name
    
    class BusinessUnit(models.Model):
        """
        业务线
        """
        name = models.CharField('业务线', max_length=64, unique=True)
        contact = models.ForeignKey('UserGroup', verbose_name='业务联系人', related_name='c')
        manager = models.ForeignKey('UserGroup', verbose_name='系统管理员', related_name='m')
        class Meta:
            verbose_name_plural = "业务线表"
        def __str__(self):
            return self.name
    
    class IDC(models.Model):
        """
        机房信息
        """
        name = models.CharField('机房', max_length=32)
        floor = models.IntegerField('楼层', default=1)
        class Meta:
            verbose_name_plural = "机房表"
        def __str__(self):
            return self.name
    
    class Tag(models.Model):
        """
        资产标签
        """
        name = models.CharField('标签', max_length=32, unique=True)
        class Meta:
            verbose_name_plural = "标签表"
        def __str__(self):
            return self.name
    
    class Asset(models.Model):
        """
        资产信息表,所有资产公共信息(交换机,服务器,防火墙等)
        """
        device_type_choices = (
            (1, '服务器'),
            (2, '交换机'),
            (3, '防火墙'),
        )
        device_status_choices = (
            (1, '上架'),
            (2, '在线'),
            (3, '离线'),
            (4, '下架'),
        )
        device_type_id = models.IntegerField(choices=device_type_choices, default=1)
        device_status_id = models.IntegerField(choices=device_status_choices, default=1)
        cabinet_num = models.CharField('机柜号', max_length=30, null=True, blank=True)
        cabinet_order = models.CharField('机柜中序号', max_length=30, null=True, blank=True)
        idc = models.ForeignKey('IDC', verbose_name='IDC机房', null=True, blank=True)
        business_unit = models.ForeignKey('BusinessUnit', verbose_name='属于的业务线', null=True, blank=True)
        tag = models.ManyToManyField('Tag')
        latest_date = models.DateField(null=True)
        create_at = models.DateTimeField(auto_now_add=True)
        class Meta:
            verbose_name_plural = "资产表"
        def __str__(self):
            return "%s-%s-%s" % (self.idc.name, self.cabinet_num, self.cabinet_order)
    
    class NetworkDevice(models.Model):
        asset = models.OneToOneField('Asset')
        management_ip = models.CharField('管理IP', max_length=64, blank=True, null=True)
        vlan_ip = models.CharField('VlanIP', max_length=64, blank=True, null=True)
        intranet_ip = models.CharField('内网IP', max_length=128, blank=True, null=True)
        sn = models.CharField('SN号', max_length=64, unique=True)
        manufacture = models.CharField(verbose_name=u'制造商', max_length=128, null=True, blank=True)
        model = models.CharField('型号', max_length=128, null=True, blank=True)
        port_num = models.SmallIntegerField('端口个数', null=True, blank=True)
        device_detail = models.CharField('设置详细配置', max_length=255, null=True, blank=True)
        class Meta:
            verbose_name_plural = "网络设备"
    
    class Server(models.Model):
        """
        服务器信息
        """
        asset = models.OneToOneField('Asset')
        hostname = models.CharField(max_length=128, unique=True)
        sn = models.CharField('SN号', max_length=64, db_index=True)
        manufacturer = models.CharField(verbose_name='制造商', max_length=64, null=True, blank=True)
        model = models.CharField('型号', max_length=64, null=True, blank=True)
        manage_ip = models.GenericIPAddressField('管理IP', null=True, blank=True)
        os_platform = models.CharField('系统', max_length=16, null=True, blank=True)
        os_version = models.CharField('系统版本', max_length=16, null=True, blank=True)
        cpu_count = models.IntegerField('CPU个数', null=True, blank=True)
        cpu_physical_count = models.IntegerField('CPU物理个数', null=True, blank=True)
        cpu_model = models.CharField('CPU型号', max_length=128, null=True, blank=True)
        create_at = models.DateTimeField(auto_now_add=True, blank=True)
        class Meta:
            verbose_name_plural = "服务器表"
        def __str__(self):
            return self.hostname
    
    class Disk(models.Model):
        """
        硬盘信息
        """
        slot = models.CharField('插槽位', max_length=8)
        model = models.CharField('磁盘型号', max_length=32)
        capacity = models.FloatField('磁盘容量GB')
        pd_type = models.CharField('磁盘类型', max_length=32)
    
        server_obj = models.ForeignKey('Server',related_name='disk')
        class Meta:
            verbose_name_plural = "硬盘表"
        def __str__(self):
            return self.slot
    
    class NIC(models.Model):
        """
        网卡信息
        """
        name = models.CharField('网卡名称', max_length=128)
        hwaddr = models.CharField('网卡mac地址', max_length=64)
        netmask = models.CharField(max_length=64)
        ipaddrs = models.CharField('ip地址', max_length=256)
        up = models.BooleanField(default=False)
        server_obj = models.ForeignKey('Server',related_name='nic')
        class Meta:
            verbose_name_plural = "网卡表"
        def __str__(self):
            return self.name
    
    class Memory(models.Model):
        """
        内存信息
        """
        slot = models.CharField('插槽位', max_length=32)
        manufacturer = models.CharField('制造商', max_length=32, null=True, blank=True)
        model = models.CharField('型号', max_length=64)
        capacity = models.FloatField('容量', null=True, blank=True)
        sn = models.CharField('内存SN号', max_length=64, null=True, blank=True)
        speed = models.CharField('速度', max_length=16, null=True, blank=True)
        server_obj = models.ForeignKey('Server',related_name='memory')
        class Meta:
            verbose_name_plural = "内存表"
        def __str__(self):
            return self.slot
    
    
    
    
    
    
    class AssetRecord(models.Model):
        """
        资产变更记录,creator为空时,表示是资产汇报的数据。
        """
        asset_obj = models.ForeignKey('Asset', related_name='ar')
        content = models.TextField(null=True)# 新增硬盘
        creator = models.ForeignKey('UserProfile', null=True, blank=True) #
        create_at = models.DateTimeField(auto_now_add=True)
        class Meta:
            verbose_name_plural = "资产记录表"
        def __str__(self):
            return "%s-%s-%s" % (self.asset_obj.idc.name, self.asset_obj.cabinet_num, self.asset_obj.cabinet_order)
    
    
    class ErrorLog(models.Model):
        """
        错误日志,如:agent采集数据错误 或 运行错误
        """
        asset_obj = models.ForeignKey('Asset', null=True, blank=True)
        title = models.CharField(max_length=16)
        content = models.TextField()
        create_at = models.DateTimeField(auto_now_add=True)
        class Meta:
            verbose_name_plural = "错误日志表"
        def __str__(self):
            return self.title
    models
  • 相关阅读:
    048——VUE中使用animate.css动画库控制vue.js过渡效果
    047——VUE中css过渡动作实例
    046——VUE中组件之使用动态组件灵活设置页面布局
    045——VUE中组件之父组件使用scope定义子组件模板结构
    004PHP文件处理——目录操作:glob rewinddir opendir readdir
    003PHP文件处理——目录操作:rename scandir
    044——VUE中组件之使用内容分发slot构建bootstrap面板panel
    Linux输出信息并将信息记录到文件(tee命令)
    linux下使用SVN上传项目
    linux下将文件上传到svn服务器
  • 原文地址:https://www.cnblogs.com/liuxiaolu/p/10863219.html
Copyright © 2011-2022 走看看