通过tcpdump采集主机间的流量情况

  • 2019 年 10 月 4 日
  • 筆記

由于公司计划要从idc迁移上云,前期准备工作之一就是要先梳理清楚当前主机间的调用关系链。 

关于这块,ODF大会上,古雷大师已经给我们指明了道路(感兴趣的可以找下 it大咖说的视频:运维数据可视化探索) , 他的比较精美但是也更复杂些。

作为一个苦逼dba,不会那些高大上的招式,怎么办?? 

当然不能放弃,借鉴了下他的思路,我整出了个比较lowbi的方法。

我的思路:

1、在每台机器上tcpdump采集500个包,格式化后写入到统一的数据库中

2、在数据库里 select distinct 查询语法, 即可找到某个主机的数据流的关系

## 在一个专用的mysql服务器 10.0.1.10 上创建账号及库:

create database tcpdump;    use tcpdump;  CREATE TABLE `graph` (    `id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT 'pk',    `src` varchar(100) NOT NULL DEFAULT '1.1.1.1' COMMENT '源地址',    `dest` varchar(100) NOT NULL DEFAULT '2.2.2.2' COMMENT '目的地址',    `cap_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,    PRIMARY KEY (`id`)  ) ENGINE=InnoDB AUTO_INCREMENT=5101 DEFAULT CHARSET=utf8 COMMENT='存放抓包采集的数据流向关系';    grant select,update,delete,insert on tcpdump.* to 'tcpdump'@'%' identified by 'tcpdump';

实际运行的脚本 

vim /root/cap/push.sh 

# 没错,下面你即将看到最 low bi的用法,直接获取数据调mysql客户端插入    # 查询语句:  # SELECT DISTINCT SUBSTRING_INDEX(src, '.', 1) AS src,SUBSTRING_INDEX(dest, '.', 1) AS dest FROM tcpdump.graph WHERE src LIKE 'sh1-%' AND dest LIKE 'sh1-%' AND src LIKE 'sh1-XXXXXX%';    source /etc/profile    port=$(ip a | egrep "10.0.*.*/16" | awk '{print $NF}')    FILE1=dump.log  FILE2=data.log  MYSQL_HOST='10.0.1.10'    tcpdump -i ${port} tcp -p -c 1000 -q > ${FILE1}    # 注意,我这环境的主机名都是 sh1-dbxxxx.demo.com ,因此使用下面的命令能提取出关键的主机信息  cat ${FILE1} | cut -d " " -f 3,5 > ${FILE2}    if `uname -r  | egrep  'el7'` ; then    mysql_version=/root/cap/mysql_el7  else    mysql_version=/root/cap/mysql_el6  fi    while read line; do    echo $line | awk '{print "insert into tcpdump.graph (src,dest) values(""$1"",""$2"");"}' | ${mysql_version} -h ${MYSQL_HOST} -utcpdump -ptcpdump  done < ${FILE2}

在 /root/cap/ 目录下,我还放了2个版本的mysql客户端(文件名 mysql_el6 和 mysql_el7),用来在不同版本的centos上执行写入操作。

部署到远程主机: 

ansible xxxx -m copy -a "src=/root/cap/ dest=/root/cap/ owner=root group=root mode=0755"

我们也可以再ansible推一个定时任务到全部主机去,当然个人建议是迁移到那个服务,我们就单独去对应服务的主机上多跑一段时间脚本采集数据然后做分析,而不是一下子搞个全网采集,那样数据量可能太大。

查询方法: 

select      distinct SUBSTRING_INDEX(src,'.',1) as src,     SUBSTRING_INDEX(dest,'.',1) as dest   from tcpdump.graph      where src like 'sh1-rabbitmq01%' ;       结果类似这样:  +----------------+----------------+  | src        | dest        |  +----------------+----------------+  | sh1-rabbitmq01 | sh1-web20    |  | sh1-rabbitmq01 | sh1-web25    |  | sh1-rabbitmq01 | sh1-web19    |  | sh1-rabbitmq01 | sh1-datax01   |  | sh1-rabbitmq01 | sh1-web10    |  | sh1-rabbitmq01 | sh1-k8s11    |  | sh1-rabbitmq01 | sh1-web10    |  | sh1-rabbitmq01 | sh1-web10    |  | sh1-rabbitmq01 | sh1-storm04   |  | sh1-rabbitmq01 | sh1-web10    |  +----------------+----------------+

有了数据后,我们还可以在 grafana 里面画图,配置大致是这样的:

1、添加mysql数据源

2、画图,使用table类型的图形展示界面,最终效果类似如下:

更进一步,我们还可以绘制动态的板子。这需要添加一个variables,如下:

这样,我们就可以下拉菜单找到对应的主机了,不需要一股脑的翻的手软眼花了。