配环境永远是世界性难题之一。最近开始踩大数据的坑,为了实现HDFS完全集群分布实验,我克隆了三台虚拟机作为我的实验对象。在经历了连接校园网虚拟机分不到内网IP的漫长难题之后,本以为终于可以顺顺利利实验,结果还是遇到了不少bug
:sweat:
错误一
第一个坑是在初始格式化namenode
的时候,hdfs namenode format
命令报域名解析暂时失败,报错log
如下图所示。看了一遍林子雨老师的部署教程也没有相关的经历和解决办法。
因为报错之时忘了截图,所以我找了别人发生的类似错误图示来说明问题。错误日志上写的是Master.localdomain
域名解析暂时失败。但我主机名都是以$Master$标注的,怎么会出现localdomain
的后缀呢?查了一下/etc/hosts
主机映射文件
没有什么问题。再思考了一下,觉得可能是集群修改hadoop
配置文件的时候出现了错误,但一番排查之后也否决了这个想法。
再经历了Google各种错误排查失败之后,我终于发现了错误的根源地,即etc
中的hostname
文件。
hostname
文件表示的是当前主机的名称,所有主机初始名称一般都是localhost
,但在前期,我为了区分集群中Master和Slave虚拟机,把主节点虚拟机的主机名称、用户名、登录名都设置成了$Master$(同样地,从节点虚拟机也将相关参数设置为$Slave1$和$Slave2$等)
但我在修改hostname
文件的时候,没有默认文件的数据删除干净,所以主机名一直维持在Master.localname
的状态。而Master.localname
这个主机名在/etc/hosts
文件中找不到映射的$ip$地址,所以才造成了这次bug……说到底还是自己的原因
错误二
第二个坑是关于用ssh免密远程登录时报错Permission denied
。
这个问题困扰了将近一天的时间,照着林子雨老师的部署教程走,但无论怎么实验,最后总是无法实现免密登录功能,无脑听信网上的解决办法也花费了不少时间,最后还越改越乱。
无奈将这个问题暂且搁置了一天,在处理某次事项的过程中莫名找到了错误根源。
子雨老师所配置的三台虚拟机,用户名都是hadoop
。而我在一开始,就把三台虚拟机各自设置了不同的用户名,而在ssh免密登录的时候,默认是同名远程登录。即使主机B存储着主机$A$的公钥,但当$a$用户用主机$A$试着免密远程连接$B$主机的时候,仅仅ssh hostnameB
的话,默认的完整命令是ssh a@hostnameB
,对应不到主机$B$上的b@hostnameB
,所以才会出现Permission denied (publickey,gssapi-keyex,gssapi-with-mic)
的报错。
那对于普通用户不同用户名之间需要怎样ssh
远程连接呢?
根据网上定义,ssh
对这种情况也有相应的解决办法,即另外配置一个config
,映射好Hostname
和username
,我的配置如下图所示:
这样的话,当下次使用ssh Slave1
的时候,$Master$本机会首先根据config
中的配置需要对应的User
,再请求连接,这样的话就能顺利解决不同用户名下的ssh
远程连接任务了!
错误三
第三个坑是配置完毕之后,$ssh$免密登录仍旧需要密码的问题。
在解决了上述问题之后,$ssh$远程连接另一台服务器仍旧需要密码,我第一反应是可能依旧连接不上,但是ping
了一下远程主机之后发现可以ping
的通,这就说明连接没有问题,应该是目的主机设置的问题。那会是什么问题呢?初步断定可能是防火墙的锅,遂用sudo cat /var/log/secure
检查了系统安全日志,如下:
网上查了查,原来是某些文件的权限配置不当,导致信任错误,$SSH$不希望home目录和~/.ssh目录对组有写权限,于是:对于用户主目录,用命令chmod g-w /home/hadoop
修改权限;除此之外,对 .ssh 文件夹和 authorized_keys 文件同样也要限制,分别用以下两个命令:
chmod 700 /home/hadoop/.ssh
chmod 600 /home/hadoop/.ssh/authorized_keys
最后,用 service sshd restart
命令重启了$SSH$服务。
尾声
最后,大家着手集群分布之前,为了避免不必要的麻烦和花费过多的时间,切记事先关掉防火墙!!!别问我怎么知道的。:smile:
附上$centos$关于防火墙命令的操作
systemctl stop firewalld.service #停止firewall
systemctl start firewalld.service #开启firewall
systemctl disable firewalld.service #禁止firewall开机启动
firewall-cmd --state #查看默认防火墙状态(关闭后显示notrunning,开启后显示running)