ARTICLE DETAIL

资讯详情

深耕商务建站与企业官网运营的一线实战洞察。

Hadoop集群SSH免密登录配置全攻略:从原理到踩坑排查

Hadoop集群SSH免密登录配置全攻略:从原理到踩坑排查 如果你正在搭Hadoop集群而且第一次执行start-dfs.sh就一路绿灯跑完那运气真的不错。大部分人的第一次都会卡在同一个地方——脚本走到某个节点时突然停住终端上冒出一行密码提示等你手动输入SSH密码。明明当时已经把公钥拷到所有机器上了为什么还要输密码这个问题我在不少集群环境里见过有的甚至卡了整整一天。Hadoop的启动脚本不会帮你输密码。无论是NameNode去连DataNode还是start-dfs.sh按slaves文件逐个访问节点底层都是通过SSH远程执行命令。只要有一台机器没有配好免密整个启动流程就卡在那里看起来像死机了一样。这篇内容就是针对“Hadoop用户配置SSH免密登录”这件事把这套配置的原理、步骤、踩坑点一次性说清楚。1. 为什么Hadoop集群要把SSH免密放在最前面1.1 集群启动脚本的真实连机逻辑很多人第一次接触Hadoop时习惯先把JDK装好、把Hadoop解压好、把配置文件改好最后才想起SSH这回事。这个顺序其实有点反了。Hadoop的启动流程是典型的“被动依赖SSH”start-dfs.sh执行后脚本会读取slaves文件或较新版本中的workers文件拿到所有DataNode的地址然后通过SSH逐个远程执行命令启动DataNode进程。NameNode所在机器也就是主节点必须能免密登录到每一个DataNode。SecondaryNameNode如果单独部署也需要考虑对应的免密链路。脚本在处理这些连接时完全是非交互的它不会弹出一个窗口让你输入密码而是直接在终端卡住等待标准输入。在单机伪分布式模式下节点只有localhost一个只需要本机免密即可。但一旦到了三台、五台、甚至更多节点的分布式环境连接关系就变成了多对多。有些初次搭建的人只在主节点上配置了到DataNode的免密忽略了DataNode之间可能存在的互连需求结果启动过程照样卡住。稳妥的做法是配置全互信每个节点都能免密登录其他所有节点。这样无论脚本从哪个节点发起连接都不会在密码输入这一步停下来。1.2 密钥认证是怎么做到“免密”的SSH免密的核心是非对称加密也就是密钥对。每个用户在自己的家目录下生成一对密钥私钥id_rsa和公钥id_rsa.pub。私钥留在本机绝对不对外传输公钥则分发到所有需要被免密登录的目标机器的~/.ssh/authorized_keys文件里。整个认证过程可以简单理解为主机A要登录主机B时A的SSH客户端用私钥对一段数据签名B收到后用A的公钥去验证签名。签名验证通过B就知道对面确实是持有私钥的A于是直接放行不再索要密码。这就像你把自己的“通行凭证”复印件预先留在门卫处下次进大门时报个名字、亮出对应标记门卫核对无误就开门不需要再出示身份证和密码。这里要注意一个常见误区authorized_keys文件里保存的是所有允许登录这台机器的用户的公钥。如果一台机器有三个用户都需要被免密登录那么这三个用户的公钥都会被追加到这个文件里。不同用户的公钥是可以共存的互不影响。这也是为什么手动操作时强调“追加”而不是“覆盖”一个不小心用重定向覆盖掉原有内容前面配好的免密就全失效了。2. 配置前必须先确认的三类基础项2.1 用户身份和目录权限边界Hadoop集群运行通常不会直接用root而是创建一个普通用户比如统一叫hadoop。这样做的好处是权限隔离清晰也符合Hadoop社区的主流操作习惯。SSH免密是“用户级”的配置每个用户有自己的~/.ssh目录A用户配置的免密只对A用户生效换一个用户登录根依然需要密码。在开始之前先确认所有节点上都是用同一个用户名、同一个家目录路径。如果一台机器上用户名是hadoop另一台是hduser哪怕你把公钥拷过去了SSH依然会去对应目标用户的家目录里找authorized_keys找不到自然要密码。我在实际环境中见过很多次这种“用户名不统一”导致免密失败的案例。排查时第一件事就是确认所有节点都执行了whoami echo $HOME另外还有个隐藏很深的坑目标机器上.ssh目录或authorized_keys文件的权限不对即使公钥内容完全正确SSH服务端也会拒绝读取。权限要求非常严格chmod 700 ~/.ssh chmod 600 ~/.ssh/authorized_keys chmod 600 ~/.ssh/id_rsa chmod 644 ~/.ssh/id_rsa.pub.ssh目录权限如果太宽松比如755SSH服务端出于安全考虑会直接忽略这个目录下的授权文件表现就是免密配置正确但始终要密码。2.2 主机名与映射规划集群环境下各节点通常通过主机名互相访问而不是每次都敲IP。这就涉及两层一是每台机器的主机名要设置好二是/etc/hosts里的映射关系要正确。主机名设置建议在配置SSH之前就完成因为后面分发公钥、验证免密时都会用到主机名。如果中途改主机名已生成的known_hosts里会残留旧主机名的指纹记录新主机名连接时会出现“Host key verification failed”的报错多一道处理工序。/etc/hosts里每一行对应一条映射192.168.1.10 hadoop-master 192.168.1.11 hadoop-node1 192.168.1.12 hadoop-node2所有节点上的这个文件要保持一致。如果只改了一台机器另一台机器解析不到主机名SSH连接就会直接失败报错类似“Could not resolve hostname xxx”。2.3 ssh-keygen的几个参数别弄错生成密钥对的命令看起来简单但有几个参数直接决定后续是否顺利ssh-keygen -t rsa -P -f ~/.ssh/id_rsa-t rsa指定密钥算法为RSAHadoop生态里最常见的用法是RSA兼容性最好。-P 表示passphrase为空也就是私钥本身不设密码短语。这一步很关键——如果给私钥设了密码短语那么每次SSH连接时依然会提示输入这个短语等于没有真正实现免密。-f指定生成文件的路径默认就是~/.ssh/id_rsa如果之前生成过执行时会询问是否覆盖。生成后检查一下家目录下是否出现了这两个文件ls -la ~/.ssh/正常情况下能看到id_rsa和id_rsa.pub。如果目录不存在可能是用户的home目录没有被正确创建或者ssh-keygen执行时被别的方式干扰了。先mkdir -p ~/.ssh再执行一次即可。3. 标准环境下的完整配置流程3.1 生成密钥对并完成本机免密我会以一个三节点集群为例来说明一台主节点hadoop-master和两台DataNodehadoop-node1、hadoop-node2三个节点都用hadoop用户。第一步在每台机器上都登录hadoop用户生成自己的密钥对ssh-keygen -t rsa -P -f ~/.ssh/id_rsa如果机器数量多可以考虑在控制机上统一生成一对密钥然后把公钥分发到每台机器私钥只保留在控制机。这样所有节点的免密都由控制机发起管理上更集中但要注意私钥的安全保护。第二步在每台机器上配置本机免密。本机免密虽然看起来简单但有实际用处Hadoop脚本有时会连localhost或本机主机名启动某些辅助进程没有本机免密同样会卡cat ~/.ssh/id_rsa.pub ~/.ssh/authorized_keys chmod 600 ~/.ssh/authorized_keys执行后验证一下ssh localhost ssh hadoop-master如果不报错、不要求输密码说明本机免密完成。3.2 从中心节点向DataNode分发公钥接下来在主节点上把hadoop-master的公钥分发到两台DataNode。这里有两种方式。第一种最省事用ssh-copy-id工具ssh-copy-id -i ~/.ssh/id_rsa.pub hadoophadoop-node1 ssh-copy-id -i ~/.ssh/id_rsa.pub hadoophadoop-node2命令执行过程中会要求输入一次目标机器的密码这是正常现象。ssh-copy-id会自动把公钥追加到目标机器的~/.ssh/authorized_keys还会顺带处理目录权限。整个过程只用一次密码之后就再也不用了。但有些最小化安装的系统没有ssh-copy-id这个命令那就用传统手动方式cat ~/.ssh/id_rsa.pub | ssh hadoophadoop-node1 mkdir -p ~/.ssh cat ~/.ssh/authorized_keys chmod 600 ~/.ssh/authorized_keys手动方式要注意管道命令里的地址写的是hadoop-userhadoop-node1这里用户名换成实际的即可。目标机器上如果~/.ssh目录不存在管道里的mkdir -p会先创建它。这种写法好处是不需要临时存储公钥文件一条命令把拷贝、追加、改权限全做了。执行完成后在DataNode上单独看一眼公钥是否真的追加成功tail -n 1 ~/.ssh/authorized_keys对比主节点上的id_rsa.pub内容应该一模一样。3.3 验证全链路免密是否真的通了配置完成后不要急着启动Hadoop先在主节点上把所有目标都测一遍ssh hadoop-node1 hostname ssh hadoop-node2 hostname ssh hadoop-node1 ls -la /opt/hadoop每一条命令如果都能直接返回结果而没有密码提示说明这条链路是通的。如果返回的是目标机器上一个普通命令的执行结果说明SSH已经成功连上了目标主机并执行了远程命令。这里提醒一个细节ssh hadoop-node1这种写法默认使用当前用户名连接目标机器。如果当前是hadoop用户连接过去的目标用户也是hadoop。如果当前是其他用户比如root要记得显式指定目标用户名ssh hadoophadoop-node1。Hadoop启动脚本是以运行start-dfs.sh的用户去连接各节点的所以最终所有节点上都必须有和主节点启动用户同名的用户且公钥要放在那个同名用户的authorized_keys里。全互信验证可以这样处理在每个节点上分别执行同样的SSH连接测试确保任意两个节点之间都能互相免密。这样做的好处是后续执行stop-dfs.sh、stop-yarn.sh或者在新版本脚本中涉及节点间跳转时不会卡住。4. 启动集群时的常见故障与排查实录4.1 启动卡在节点名处并提示输入密码这是最典型的故障。执行start-dfs.sh后屏幕上出现了类似这样的输出Starting namenodes on [hadoop-master] hadoop-master:然后光标停在那里等输入密码。出现这种情况先按CtrlC中断然后按顺序排查第一步确认公钥在目标机器上的存放位置。用主节点的hadoop用户执行ssh -v hadoop-node1-v是verbose模式输出里会显示尝试了哪些认证方法。如果看到Server accept key之后再没有下文说明服务端没有接受公钥基本就是authorized_keys的问题。如果看到公钥路径被尝试了但被拒绝优先检查权限。第二步在目标机器上看.ssh目录和文件的权限ls -la ~/.ssh/ stat -c %a %n ~/.ssh ~/.ssh/authorized_keys校验规则就是之前提到的.ssh必须是700authorized_keys必须是600私钥是600公钥可以是644。第三步如果权限没问题看SSH服务端日志。系统日志位置因发行版而异tail -n 100 /var/log/secure tail -n 100 /var/log/auth.log日志里如果出现Authentication refused或Permission denied会直接告诉你被拒绝的原因。大部分情况都指向授权文件路径或权限。4.2 报错Host key verification failed这个报错常见于以下几种场景系统重装后主机名没变但SSH主机密钥变了之前连接过某IP但后来该IP分配给另一台机器或者known_hosts里的旧记录与当前主机指纹不匹配。报错信息一般长这样WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! Host key verification failed.解决办法很简单在发起连接的本机上把对应主机的旧指纹记录删掉ssh-keygen -R hadoop-node1这条命令会从~/.ssh/known_hosts里移除指定主机的条目。删掉后重新连接会再次提示确认主机指纹输入yes即可重新记录。如果有多台机器都报这个错逐个执行ssh-keygen -R或者简单粗暴地处理整个文件rm -f ~/.ssh/known_hosts删掉后重连所有指纹都会重新建立。第一次连接时的yes确实必不可少Hadoop脚本不会帮你回答这个提示所以建议在正式启动前手动把所有目标都连一遍避免在脚本执行时遇到这个交互。4.3 权限报错和SELinux干扰有些Linux发行版默认开启了SELinux如果配置不当SSH免密会遇到额外阻碍。典型表现是公钥文件内容完全正确、权限也对但就是免密不成功。查看审计日志时可以看到SELinux的拦截记录。我不是建议一遇到问题就去关闭SELinux但如果在测试环境里为了快速推进搭建进度临时关闭确实能省很多排查时间setenforce 0不过这个命令只对当前会话有效重启后又会恢复。要想长期关闭需要修改配置文件/etc/selinux/config把SELINUXenforcing改成SELINUXdisabled。生产环境建议保留SELinux但要在安全策略里放行SSH免密相关操作或者验证一下问题确实由SELinux引起再做处理。还有一种权限相关问题容易被忽略目标机器上hadoop用户的home目录本身权限不对。如果home目录对其他用户没有执行权限SSH服务端在访问~/.ssh/authorized_keys时也会失败。常规情况下home目录权限是755或700问题不大但如果有历史原因改过检查一下也不会浪费多少时间。4.4 多节点互信不完整导致的后遗症在集群运行一段时间后有时会出现一种奇怪的现象单独执行ssh hadoop-node2完全正常但Hadoop脚本跑到某一步就卡住。排查了半天发现是脚本内部会从节点A跳到节点B而A到B的免密没有配置。这类问题最隐蔽因为表面上看“每个节点都能访问其他节点”似乎都配了但实际上可能是单向的或者某些节点之间的互信漏掉了。给一个简单的检查方法在每一个节点上写一个循环测试把集群内所有主机名都ping一遍SSH连接for host in hadoop-master hadoop-node1 hadoop-node2; do echo $host: $(ssh $host hostname 21) done如果某个节点返回的不是主机名而是密码提示或错误说明该节点到目标的链路有问题。逐节点跑一遍很快就能把缺漏的地方找出来。这个循环在后期扩容节点时特别有用新加一台DataNode后保证新节点和所有旧节点之间都做好互信是整个集群稳定启动的基础保障。5. 几个让集群维护更顺手的个人习惯5.1 先规划主机名再配置免密我实际踩过几次坑之后现在固定的顺序是先规划好所有节点的主机名更新全部/etc/hosts重启或重新登录让主机名生效然后创建统一的Hadoop运行用户最后才去生成密钥、分发公钥。这个顺序一旦固定下来后续每次扩容都按照同样流程走一遍很少再出现“重启后免密失效”或“主机名变更后known_hosts报错”这类问题。5.2 用脚本批量完成公钥分发节点数量超过五台时手动一条条执行ssh-copy-id太容易出错。可以写一个简单的Shell脚本在控制节点上批量执行for node in hadoop-node1 hadoop-node2 hadoop-node3; do ssh-copy-id -i ~/.ssh/id_rsa.pub hadoop$node done脚本本身没什么技术含量但胜在可以重复执行、不会遗漏节点。如果某些机器迁移了IP重新跑一遍脚本就把公钥刷过去了。5.3 新节点加入集群时的两件套每次给Hadoop集群新增DataNode时只靠复制旧机器的authorized_keys是不够的。新节点自己也需要生成一套密钥对然后把新节点的公钥加入旧节点的authorized_keys把旧节点的公钥加入新节点的authorized_keys。我通常会在新节点上先完成本地密钥生成再把新节点的公钥复制到控制机在控制机上批量分发到所有旧节点同时从任何一个旧节点把它的公钥复制到新节点追加到新节点的authorized_keys里。最后在新节点上执行一次全节点免密验证循环。整个过程大概多花五分钟但换来的是后续启动集群时零卡顿很值得。5.4 把免密测试写入集群交接清单如果你负责维护一个别人搭建好的集群接手时不要只看配置文件先把免密链路全盘验证一遍。这个动作花费的时间很少却是最快发现遗留隐患的方式。我在接手某些环境时遇到过这样的情况表面上看集群运行正常但某台机器重启后因为SSH服务启动顺序的问题免密暂时失效导致后续操作各种诡异报错。提前验一遍心里就有底了。SSH免密本身是个入门级配置但它却是整个Hadoop集群最容易出问题的前置环节之一。很多集群启动异常、脚本挂起、进程起不了根因追到最后都是免密链路有缺口。把这件事做得扎实一点后面跑任务、调参数、扩节点才会顺。
返回列表
PREV
查看更多资讯
NEXT
返回资讯列表