通過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,如下:

這樣,我們就可以下拉菜單找到對應的主機了,不需要一股腦的翻的手軟眼花了。