CMDB资产采集

Paramiko

import paramiko
 
private_key = paramiko.RSAKey.from_private_key_file('/home/auto/.ssh/id_rsa')
 
# 创建SSH对象
ssh = paramiko.SSHClient()
# 允许连接不在know_hosts文件中的主机
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
# 连接服务器
ssh.connect(hostname='c1.salt.com', port=22, username='wupeiqi', key=private_key)
 
# 执行命令
stdin, stdout, stderr = ssh.exec_command('df')
# 获取命令结果
result = stdout.read()
 
# 关闭连接
ssh.close()

SaltStack

1. 安装和配置

"""
1. 安装salt-master
    yum install salt-master
2. 修改配置文件:/etc/salt/master
    interface: 0.0.0.0    # 表示Master的IP 
3. 启动
    service salt-master start
"""
Master
"""
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
"""
Slave

2. 授权   salt-key -A 给所有的minion机授权

"""
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
"""
Master

3. 执行命令

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

salt 'c2.salt.com' cmd.run  'ifconfig'
基于shell命令
import salt.client
local = salt.client.LocalClient()
result = local.cmd('c2.salt.com', 'cmd.run', ['ifconfig'])
基于Salt的API
 

运维愿景

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

目前状况

  • 目前很多公司还是:手动维护Excel表格
  • 急需:资产自动采集并汇报入库
  • 解决办法:CMDB - 配置管理数据库(资产管理)

如果实现自动采集?

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的公司。

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

三层架构

  数据访问层
  业务处理层
  UI展示层

原理草图:

 

CMDB源码使用须知

 
一、CMDB项目大体攻略:
  1.先建目录
    bin #可执行文件
    config #配置文件
    lib #公共的模块
    src #业务逻辑

  2.配置文件
    settings 一般都是大写,放自定制配值文件
    自定义配置文件
    默认配置文件
    在lib里面写个目录conf在目录中建立一个config.py和global_settings.py第一个文件是放逻辑的,让自定义配置文件和默认配置文件结合起来,
  ****整合技巧
  PS: 
    import os
    os.environ['USER_SETTINGS']="config.settings"
  3.开发插件(可插拔)
    公司采集资产有差别
    默认采集:
      basic #主机名,系统版本,系统类型
      board #主板
      cpu
      disk
      memory #内存
      nic #网卡
    定义插件:
      class xxxx(object):
      def process(self):
      return '1331321321321'
    把这些插件都放到settings里面

  4.向API获取发送数据
    AGENT:
      向API发送资产信息
    SSH、SALT:
      整个流程的开始应该是从API接口开始,先从这里拿到没有采集的主机列表获取未采集的主机列表:[c1.com,c2.com]
    for host in 主机列表:
      host采集资产,发送到API
二、为什么要开发CMDB
  Excel维护资产信息,资产变更时难以保证Excel表正确性;信息交换不方便
  自动采集资产工具,目标:自动汇报,保存变更记录
  最终目标:实现运维自动化
三、CMDB架构:
  资产采集
  API(两个功能:接收数据保存入库,对外提供数据接口比如有人访问指定的url就能拿到指定主机的详细信息都展示出来)
  后台管理(对资产进行增删改查)
四、开发程序时你负责做什么
  周期:将近三个月
  三个人负责,我负责资产采集(那个简单说那个)
  调研提出三种方案:agent paramiko saltstack 三种方案,三种都兼容,为了提高
  扩展性,配置文件(自定义和默认)和中间件(反射)参考Django:
五、有没有遇到难题(技术的难题不是难题,业务的难题才是难题)
  Linux不太熟,命令都不知道该用啥
  唯一标识:大问题,一开始用的是主板的SN号,当初我们认为他就是唯一标识,
  物理机的话SN号是唯一的,openstack虚拟机和物理机的SN号是一样的
  所以在实现运维自动化之前就要先做标准话,后来改为主机名,主机名不能重复,用主机名作唯一标识
  主机名是唯一标识,依赖本地文件
六、最终流程:
  标准化:主机名不重复,流程的标准化,装机的时候CMDB中主机名已经设定好了
  服务器上的资产采集(AGENT):
  a.第一次采集,文件不存在或者内容为空,采集资产要把主机名写入文件,将采集信息发送到API
  b.第N次,采集资产,主机名从文件中获取,
SSH和Salt不存在这种情况:
  这个架构开始是从中控机获取没有采集过的主机名(主机名跟IP是绑定的),而流程一开始主机名已经被录入cmdb了
开发须知

一、CMDB项目大体攻略:
  1.先建目录
    bin #可执行文件
    config #配置文件
    lib #公共的模块
    src #业务逻辑

  2.配置文件
    settings 一般都是大写,放自定制配值文件
    自定义配置文件
    默认配置文件
    在lib里面写个目录conf在目录中建立一个config.py和global_settings.py第一个文件是放逻辑的,让二、自定义配置文件和默认配置文件结合起来,
  ****整合技巧
  PS:
    import os
    os.environ['USER_SETTINGS']="config.settings"
  3.开发插件(可插拔)
    公司采集资产有差别
    默认采集:
      basic #主机名,系统版本,系统类型
      board #主板
      cpu
      disk
      memory #内存
      nic #网卡
    定义插件:
      class xxxx(object):
      def process(self):
      return '1331321321321'
    把这些插件都放到settings里面

  4.向API获取发送数据
    AGENT:
      向API发送资产信息
    SSH、SALT:
      整个流程的开始应该是从API接口开始,先从这里拿到没有采集的主机列表获取未采集的主机列表:[c1.com,c2.com]
    for host in 主机列表:
      host采集资产,发送到API

三、为什么要开发CMDB
  Excel维护资产信息,资产变更时难以保证Excel表正确性;信息交换不方便
  自动采集资产工具,目标:自动汇报,保存变更记录
  最终目标:实现运维自动化
四、CMDB架构:
  资产采集
  API(两个功能:接收数据保存入库,对外提供数据接口比如有人访问指定的url就能拿到指定主机的详细信息都展示出来)
  后台管理(对资产进行增删改查)
五、开发程序时你负责做什么
  周期:将近三个月
  三个人负责,我负责资产采集(那个简单说那个)
  调研提出三种方案:agent paramiko saltstack 三种方案,三种都兼容,为了提高
  扩展性,配置文件(自定义和默认)和中间件(反射)参考Django:
六、有没有遇到难题(技术的难题不是难题,业务的难题才是难题)
  Linux不太熟,命令都不知道该用啥
  唯一标识:大问题,一开始用的是主板的SN号,当初我们认为他就是唯一标识,
  物理机的话SN号是唯一的,openstack虚拟机和物理机的SN号是一样的
  所以在实现运维自动化之前就要先做标准话,后来改为主机名,主机名不能重复,用主机名作唯一标识
  主机名是唯一标识,依赖本地文件
七、最终流程:
  标准化:主机名不重复,流程的标准化,装机的时候CMDB中主机名已经设定好了
  服务器上的资产采集(AGENT):
  a.第一次采集,文件不存在或者内容为空,采集资产要把主机名写入文件,将采集信息发送到API
  b.第N次,采集资产,主机名从文件中获取,
八、SSH和Salt不存在这种情况:
  这个架构开始是从中控机获取没有采集过的主机名(主机名跟IP是绑定的),而流程一开始主机名已经被录入cmdb了

九、为什么要进行API验证:

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

十、API验证是如何设计的:

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

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

 saltstack 安装

CentOS7  安装
yum install https://repo.saltstack.com/yum/redhat/salt-repo-latest-2.el7.noarch.rpm  -y

yum install salt-master -y

yum install salt-minion -y

CentOS6 安装
yum install https://repo.saltstack.com/yum/redhat/salt-repo-latest-2.el6.noarch.rpm  

yum install salt-master -y

yum install salt-minion -y
### saltstack技术入门与实践

#### 基本原理
SaltStack 采用`C/S`模式,server端就是salt的master,client端就是minion,minion与master之间通过`ZeroMQ`消息队列通信。

minion上线后先与master端联系,把自己的`pub key`发过去,这时master端通过`salt-key -L`命令就会看到minion的key,接受该minion-key后,也就是master与minion已经互信。

master可以发送任何指令让minion执行了,salt有很多可执行模块,比如说cmd模块,在安装minion的时候已经自带了,它们通常位于你的python库中,`locate salt | grep /usr/`可以看到salt自带的所有东西。

这些模块是python写成的文件,里面会有好多函数,如cmd.run,当我们执行`salt '*' cmd.run 'uptime'`的时候,master下发任务匹配到的minion上去,minion执行模块函数,并返回结果。

master监听4505和4506端口,4505对应的是ZMQ的PUB system,用来发送消息,4506对应的是REP system是来接受消息的。
具体步骤如下

```
1、Salt stack的Master与Minion之间通过ZeroMq进行消息传递,使用了ZeroMq的发布-订阅模式,连接方式包括tcp,ipc
2、salt命令,将cmd.run ls命令从salt.client.LocalClient.cmd_cli发布到master,获取一个Jodid,根据jobid获取命令执行结果。
3、master接收到命令后,将要执行的命令发送给客户端minion。
4、minion从消息总线上接收到要处理的命令,交给minion._handle_aes处理
5、minion._handle_aes发起一个本地线程调用cmdmod执行ls命令。线程执行完ls后,调用minion._return_pub方法,将执行结果通过消息总线返回给master
6、master接收到客户端返回的结果,调用master._handle_aes方法,将结果写的文件中
7、salt.client.LocalClient.cmd_cli通过轮询获取Job执行结果,将结果输出到终端。
```

#### saltstack 安装

[saltstack install](http://repo.saltstack.com/#rhel)

#### 修改minion配置文件
```
[root@linux-node2 ~]# vim /etc/salt/minion
master: 192.168.56.11
[root@linux-node2 ~]# vim /etc/salt/minion
master: 192.168.56.11
[root@linux-node1 pki]# pwd
/etc/salt/pki
[root@linux-node1 pki]# tree
.
├── master
│   ├── master.pem
│   ├── master.pub
│   ├── minions
│   ├── minions_autosign
│   ├── minions_denied
│   ├── minions_pre
│   │   ├── linux-node1.example.com
│   │   └── linux-node2.example.com
│   └── minions_rejected
└── minion
    ├── minion_master.pub
    ├── minion.pem
    └── minion.pub
[root@linux-node1 pki]# salt-key -A
[root@linux-node1 pki]# tree
.
├── master
│   ├── master.pem
│   ├── master.pub
│   ├── minions
│   │   ├── linux-node1.example.com
│   │   └── linux-node2.example.com
│   ├── minions_autosign
│   ├── minions_denied
│   ├── minions_pre
│   └── minions_rejected
└── minion
    ├── minion_master.pub
    ├── minion.pem
    └── minion.pub
```

#### 远程执行
```
[root@linux-node1 pki]# salt "*" test.ping
linux-node2.example.com:
    True
linux-node1.example.com:
    True
[root@linux-node1 pki]# salt "*" cmd.run 'w'
linux-node1.example.com:
     07:20:24 up 17:10,  1 user,  load average: 0.00, 0.01, 0.05
    USER     TTY      FROM             LOGIN@   IDLE   JCPU   PCPU WHAT
    root     pts/0    192.168.56.1     07:04    0.00s  0.30s  0.26s /usr/bin/python /usr/bin/salt * cmd.run w
linux-node2.example.com:
     08:26:25 up 22:40,  2 users,  load average: 0.15, 0.05, 0.06
    USER     TTY      FROM             LOGIN@   IDLE   JCPU   PCPU WHAT
    root     tty1                      Sat09   13:12m  0.02s  0.02s -bash
    root     pts/0    192.168.56.1     08:09   13:53   0.04s  0.04s -bash
```

#### 配置管理
##### YAML

- 缩进:
  - 两个空格
  - 不能使用tab键
  - 缩进代表层级关系

- 冒号:
  - key: value

- 短横线代表list

#### satate模块
```
# vim /etc/salt/master
file_roots:
  base:
    - /srv/salt
# mkdir /srv/salt
# mkdir /srv/salt
# cd /srv/salt
# mkdir web
# cd web
# pwd
/srv/salt/web
# vim apache.sls
apache-install:
  pkg.installed:
    - names:
      - httpd
      - httpd-devel

apache-service:
  service.running:
    - name: httpd
    - enable: True

# salt '*' state.sls web.apache
 [root@linux-node2 salt]# cd /var/cache/salt/
[root@linux-node2 salt]# tree               
.
`-- minion
    |-- extmods
    |-- files
    |   `-- base
    |       `-- web
    |           `-- apache.sls
    |-- pkg_refresh
    `-- proc
        `-- 20160605081351939477 
# cat /var/cache/salt/minion/files/base/web/apache.sls 
apache-install:
  pkg.installed:
    - names:
      - httpd
      - httpd-devel

apache-service:
  service.running:
    - name: httpd
    - enable: True   
# ps -ef|grep yum
root      34129  34103  1 08:13 ?        00:00:00 /usr/bin/python /usr/bin/yum --quiet check-update
root      34204  34149  0 08:14 pts/1    00:00:00 grep --color=auto yum

# cd /srv/salt/
# vim top.sls
base:
  'linux-node1.example.com':
    - web.apache
  'linux-node2.example.com':
    - web.apache
# salt '*' state.highstate test=True
# salt '*' state.highstate

# lsof -i:4505 -n
COMMAND     PID USER   FD   TYPE  DEVICE SIZE/OFF NODE NAME
salt-mast 24739 root   13u  IPv4 4637762      0t0  TCP *:4505 (LISTEN)
salt-mast 24739 root   15u  IPv4 4640421      0t0  TCP 192.168.56.11:4505->192.168.56.11:48344 (ESTABLISHED)
salt-mast 24739 root   16u  IPv4 4640542      0t0  TCP 192.168.56.11:4505->192.168.56.12:53039 (ESTABLISHED)
salt-mini 25378 root   25u  IPv4 4640888      0t0  TCP 192.168.56.11:48344->192.168.56.11:4505 (ESTABLISHED)
```

#### 数据系统

##### Grains
静态数据 当minion启动时收集的minion本地相关信息
##### Pillar
saltstack技术入门与实践

 

posted @ 2017-07-26 22:14  黄土地上的黑石头  阅读(621)  评论(0编辑  收藏  举报