介绍
有时你会发现,hadoop namenode的50070页面显示的datanode节点信息中,有些并非是我们同意加入的,或者你使用了iptables,但是防得住IP,防不住hostname变化,而且过去发现,服务器修改hostname直接在/etc/profile里面采用hostname XXX的形式,据我了解,/etc/profile只有在shell登录的时候才会被调用, 而正确的修改方式是 修改/etc/sysconfig/network文件。
如果集群再次被这种非法节点入侵,我们该怎么办?
监控,没错,就是监控,亡羊补牢,为时不晚。
关键算法
<a title="XX.XX.XX.XX:50010" href="http://XX-XX-XX-XX:50075/browseDirectory.jsp?namenodeInfoPort=50070&dir=%2F&nnaddr=XX.XX.XX.XX:9000">XX-XX-XX-XX</a>
如何取出最后一个XX-XX-XX-XX
<a title=.* href=.*>(.*))</a>
走过的坑
# 一开始打算使用\d+\d+\d+\d+的形式,可是后来想想,如果里面不是这种,比如是ec+amazon+computer+haha这种hostname该如何办呢?
result = re.findall("(\d+\-\d+\-\d+\-\d+)",response.read())
# 所以这种办法是不可以的,适用范围特别窄
上代码
#!/usr/bin/env python
# -*- coding:utf-8 -*-
import urllib2,MySQLdb
import os,sys,re
# 获取http页面
response = urllib2.urlopen('http://%s:50070/dfsnodelist.jsp?whatNodes=LIVE'%(sys.argv[1]), timeout=10)
# 分写返回结果,将10-XX-XX-XX的形式去重后转成10.X.X.X
# result = re.findall("(\d+\-\d+\-\d+\-\d+)",response.read())
result = re.findall("<a title=.* href=.*>(.*)</a>",response.read())
if len(result) > 0:
result2 = set(result)
print len(result2)
result3 = []
for value in result2:
value2 = value.replace("-",".")
result3.append(value2)
# 定义一个小函数,去获取所有datanode的IP信息
def getIPs():
returnResult = []
conn = MySQLdb.connect(host="XX",user = "XX", passwd = "XX",db = "XX",charset="utf8")
cur = conn.cursor()
command = '''select lanip from XX where groupName = "datanode";'''
print command
cur.execute(command)
results = cur.fetchall()
for result in results:
#print result[0]
returnResult.append(result[0])
conn.close()
return returnResult
# 调用函数,获取所有IP地址
realIPs = getIPs()
# 定义非法IP列表,
notInRealIPs = []
for ip in result3:
# 非常重要,对从http获取的资料与数据中记录的进行对比
if not ip in realIPs:
notInRealIPs.append(ip)
# 如果有非法,那么就进行 print,并且exit 1, 使用jenkins的时候会发出邮件通知
if len(notInRealIPs) > 0:
print "Find Error."
print notInRealIPs
sys.exit(1)