
搞過Hadoop集群的人都清楚第一次啟動分布式節(jié)點時最煩的就是每臺機器都要輸密碼。不管你是用sbin/start-dfs.sh啟動HDFS還是跑一條MapReduce任務(wù)只要腳本涉及跨節(jié)點遠程執(zhí)行命令就會卡在“Password”的提示上。尤其是三層結(jié)構(gòu)跑起來之后NameNode要跟每臺DataNode通信一次啟動輸十幾次密碼手都酸而且腳本后臺執(zhí)行根本沒法交互輸入。這時候給Hadoop用戶配好SSH免密登錄就是正兒八經(jīng)的剛需。這篇文章主要圍繞“為hadoop用戶配置SSH免密登錄”這件事把原理、實操步驟、權(quán)限細節(jié)、常見坑全部拆開講。適合剛剛搭好Hadoop集群的小白也適合在運維過程中想重新梳理SSH配置的人。看完你不僅能照著敲命令配好還能明白為什么目錄權(quán)限差一點都不行以及遇到“免密失效”“連接被拒絕”時該從哪里下手排查。1. 理解需求為什么Hadoop一定要配免密登錄1.1 從NameNode到DataNode的巡檢式通信先說一個最核心的場景。Hadoop集群啟動之后主節(jié)點NameNode、ResourceManager需要主動連接到從節(jié)點DataNode、NodeManager去執(zhí)行一些遠端命令比如啟動DataNode進程、刷新節(jié)點狀態(tài)、做元數(shù)據(jù)檢查。這個連接不是用戶手動敲的而是腳本里通過ssh hostname去觸發(fā)的。如果每臺機器都需要密碼那腳本在執(zhí)行到遠程部分時就僵住了。尤其是start-dfs.sh它會遍歷slaves文件里列出的每一個節(jié)點逐個嘗試SSH連接。以前我見過有人在非交互環(huán)境下配錯了密鑰結(jié)果啟動腳本卡在某個節(jié)點上半個小時最后超時失敗日志里全是“Permission denied, please try again.”。所以免密登錄是Hadoop偽分布式和全分布式集群能夠正常啟動、管理的前提不是可選項。1.2 公鑰認證原理簡單回顧SSH免密登錄本質(zhì)上是基于公鑰加密的身份認證??蛻舳松梢粚γ荑€公鑰放到服務(wù)端的~/.ssh/authorized_keys文件里私鑰留在客戶端。當客戶端發(fā)起SSH連接時服務(wù)端會拿著公鑰去驗證客戶端的身份如果匹配通過就不再要求輸密碼了。這個過程中權(quán)限是個極其敏感的校驗條件。OpenSSH對密鑰文件和.ssh目錄的權(quán)限有嚴格檢查如果權(quán)限過寬比如authorized_keys被設(shè)為644以外的“其他人可寫”狀態(tài)服務(wù)端會直接忽略這個文件哪怕你的公鑰內(nèi)容完全正確也會退回密碼登錄。這個問題我在后面詳細講。提示這里說的都是Hadoop用戶自己的配置不要動系統(tǒng)里root的SSH配置。Hadoop的守護進程如果以hadoop用戶運行那么免密登錄就是hadoop用戶的事配錯賬號會引發(fā)權(quán)限混亂。2. 準備工作與約定2.1 集群角色與網(wǎng)絡(luò)規(guī)劃在動手前先把角色理清。你需要確認誰是客戶端誰是服務(wù)端。在Hadoop集群里通常有三類節(jié)點NameNode / ResourceManager作為主節(jié)點需要免密SSH到所有從節(jié)點執(zhí)行遠程命令。DataNode / NodeManager作為從節(jié)點一般不需要反向免密??蛻舳斯?jié)點提交作業(yè)的機器如果你經(jīng)常手動ssh到集群其他節(jié)點也可以一并配置。但為了省事我建議在一個集群里把所有機器的hadoop用戶都互相配好免密至少從各主節(jié)點到各從節(jié)點要通。假設(shè)集群有三臺機器master01、worker01、worker02操作系統(tǒng)為Linux使用同一個hadoop用戶名并且已用相同的hadoop用戶登錄所有機器。網(wǎng)絡(luò)層先確認機器之間可以互ping/etc/hosts里也寫好了主機名映射。2.2 確認基礎(chǔ)環(huán)境確認以下兩點再開始所有機器都裝了openssh-server并且SSH服務(wù)已啟動。用systemctl status sshd查看如果沒有安裝就先用yum install -y openssh-serverDebian系是apt install openssh-server裝好。每臺機器上hadoop用戶的home目錄/home/hadoop存在且hadoop用戶可以正常登錄。如果還沒有創(chuàng)建用戶先執(zhí)行useradd hadoop passwd hadoop。另外建議先手動用密碼登錄一遍所有機器把known_hosts文件生成出來這樣后續(xù)配置過程中能少遇到host key確認的干擾。我這套流程是在常見的Linux發(fā)行版上跑的Mac系統(tǒng)略有差異但核心邏輯一樣。3. 核心實操一步步配置免密登錄3.1 生成密鑰對登錄到master01機器并切換到hadoop用戶或者直接用hadoop用戶登錄審計。然后執(zhí)行su - hadoop ssh-keygen -t rsa -b 4096 -P -f ~/.ssh/id_rsa參數(shù)里-P 表示私鑰文件不設(shè)置密碼這樣后續(xù)腳本自動連接時不需要再手動輸入私鑰口令。如果這里你設(shè)置了密碼那免密就會變成“免輸賬號密碼但要輸私鑰密碼”等于沒免。-f指定生成路徑放在hadoop用戶的.ssh目錄下。執(zhí)行完成后確認ls -l ~/.ssh/你會看到id_rsa私鑰和id_rsa.pub公鑰兩個文件。注意集群規(guī)模大或者安全意識強的環(huán)境里有人會傾向給私鑰加口令并配合ssh-agent。但在Hadoop自動化場景里腳本執(zhí)行是非交互式的加密私鑰會導(dǎo)致agent被發(fā)布后無法自動解鎖非常麻煩。生產(chǎn)環(huán)境如果一定要加需要配上ssh-agent和ssh-add并把密碼預(yù)置到keychain里這個復(fù)雜度不建議新手碰。3.2 分發(fā)公鑰并配置authorized_keys現(xiàn)在你的master01上有公鑰需要把公鑰內(nèi)容追加到所有目標機器hadoop用戶的~/.ssh/authorized_keys中。包括它自己也要配一份因為有些腳本也會往本機做SSH循環(huán)。最簡單的辦法是使用ssh-copy-id它在Linux下默認自帶很好用ssh-copy-id hadoopmaster01 ssh-copy-id hadoopworker01 ssh-copy-id hadoopworker02執(zhí)行這個過程時會要求輸入一次hadoop用戶在目標機器上的密碼輸入后工具會自動把公鑰追加到對方~/.ssh/authorized_keys并做權(quán)限收斂。一切正常后驗證一下ssh hadoopworker01 echo ok: $(hostname)如果直接輸出ok: worker01說明master01到worker01的免密已經(jīng)通了。如果ssh-copy-id不可用也可以手工方式。一條命令完成cat ~/.ssh/id_rsa.pub | ssh hadoopworker01 mkdir -p ~/.ssh cat ~/.ssh/authorized_keys需要注意如果是第一次連接會彈出Are you sure you want to continue connecting (yes/no)輸入yes。這種方式不會自動收斂權(quán)限你之后需要到每一臺機器上手動執(zhí)行chmod。所以ssh-copy-id優(yōu)先。3.3 批量分發(fā)腳本可選集群節(jié)點多的時候一個個ssh-copy-id也挺煩??梢詫懸粋€簡單的for循環(huán)腳本放在比如/home/hadoop/bin/目錄下#!/bin/bash # 需要在每臺機器hadoop用戶下執(zhí)行將本機公鑰分發(fā)到所有節(jié)點 NODESmaster01 worker01 worker02 for node in $NODES; do echo Copy public key to $node... ssh-copy-id -i ~/.ssh/id_rsa.pub hadoop$node done分發(fā)時依然需要逐臺輸入一次密碼。這是不可避免的除非你用配置管理工具Ansible之類去集中分發(fā)但那要另起一套帶認證的通道不在本文范圍內(nèi)。這里把腳本內(nèi)容給你結(jié)合hosts文件的寫法以后加新節(jié)點時執(zhí)行一遍就夠。3.4 驗證免密登錄在所有節(jié)點上都完成上述配置后從master01依次執(zhí)行for node in master01 worker01 worker02; do echo $node ; ssh hadoop$node hostname whoami; done理想輸出是三行主機名加hadoop。如果一切正常你還可以繼續(xù)做一個更貼近Hadoop場景的驗證切換到Hadoop安裝目錄比如/usr/local/hadoop執(zhí)行sbin/start-dfs.sh觀察是否不再卡在密碼提示。這一步才是真正的驗收。4. 權(quán)限與配置文件細節(jié)避坑重點4.1 權(quán)限為何必須嚴格前面提到OpenSSH會檢查文件權(quán)限這里要展開說。很多新手配了半天authorized_keys里有公鑰但就是免密失敗90%的原因是權(quán)限問題。下面是一張標準權(quán)限表照著設(shè)置基本不會錯路徑/文件屬主權(quán)限說明~/.sshhadoop700目錄不能組/其他用戶有寫權(quán)限~/.ssh/authorized_keyshadoop600公鑰文件不能組/其他用戶可寫~/.ssh/id_rsahadoop600私鑰必須只有屬主可讀寫~home目錄hadoop755不能被組/其他用戶寫否則SSH會拒絕我見過最典型的一個錯誤是有人將整個home目錄遞歸做了chmod -R 777然后所有權(quán)限校驗全掛。OpenSSH有一個StrictModes設(shè)置默認是yes它會拒絕任何它認為權(quán)限過松的密鑰認證。你可以臨時把StrictModes改成no來驗證但這不是“修復(fù)”是繞過治標不治本而且會引入風險。正確做法就是把權(quán)限掰正。如果遇到權(quán)限導(dǎo)致的失敗可以檢查服務(wù)端的日志通常是/var/log/secure或/var/log/auth.log里面會明確寫Authentication refused: bad ownership or modes for file /home/hadoop/.ssh/authorized_keys看到這句話直接chmod 600 ~/.ssh/authorized_keys再確認.ssh目錄是700基本就能解決。4.2 SSH配置項影響除了權(quán)限/etc/ssh/sshd_config里的幾項直接影響免密是否生效PubkeyAuthentication yes必須啟用公鑰認證。有些默認配置為了安全會關(guān)閉需要手動打開。AuthorizedKeysFile .ssh/authorized_keys指定服務(wù)端認可的公鑰文件路徑。如果你的配置被修改過比如寫成了絕對路徑或別的文件名就要調(diào)整。PasswordAuthentication no如果服務(wù)端直接把密碼登錄禁掉了而且公鑰又沒配好那你會連登錄都登不進去。建議先把免密打通再考慮是否關(guān)掉密碼登錄。StrictModes yes前面提到的權(quán)限嚴格檢查。修改配置后記得重啟sshd服務(wù)sudo systemctl restart sshd如果你愿意也可以先做sshd -t檢查配置語法避免重啟失敗。4.3 known_hosts和StrictHostKeyChecking免密登錄成功后另一個經(jīng)常出現(xiàn)的坑是主機密鑰確認。當SSH客戶端第一次連接一臺新機器時會詢問是否接受該主機的主機公鑰。批量和腳本場景下這個詢問會卡住。處理方案有兩類。第一類是正規(guī)做法提前把所有目標主機密鑰插入到~/.ssh/known_hosts讓客戶端不再詢問。你可以這樣ssh-keyscan master01 worker01 worker02 ~/.ssh/known_hosts第二類是降低客戶端檢查級別。在~/.ssh/config里為特定主機設(shè)置Host *.example.com StrictHostKeyChecking no UserKnownHostsFile /dev/null或者臨時在命令行加-o StrictHostKeyCheckingno。但是要清楚關(guān)閉主機密鑰檢查會降低安全性所以建議只在受信任的內(nèi)網(wǎng)測試環(huán)境使用生產(chǎn)環(huán)境還是用ssh-keyscan預(yù)置為好。5. 常見問題與排查實錄5.1 問題速查表下面這些是我在多個模擬項目環(huán)境里實際踩過的狀況你也可以直接對照排查現(xiàn)象直接原因排查/解決提示“Permission denied (publickey,password)”沒配好公鑰或權(quán)限不對在目標機上重新ssh-copy-id檢查.ssh權(quán)限卡在“yes/no”主機確認提示known_hosts沒有目標主機記錄執(zhí)行ssh-keyscan填充或臨時關(guān)閉StrictHostKeyChecking免密登錄本機可以遠程不行只需把本機公鑰分發(fā)到遠程機器檢查authorized_keys是否包含對應(yīng)公鑰配置沒問題但隔幾天又失效home目錄權(quán)限被動過或賬號被鎖重新執(zhí)行chmod檢查密碼策略Hadoop啟動腳本部分節(jié)點卡住某個節(jié)點網(wǎng)絡(luò)/password/公鑰未同步先從該節(jié)點手動ssh看具體報錯執(zhí)行腳本時私鑰提示輸入Passphrase生成密鑰時加了密碼重新生成帶-P 的密鑰對或者刪除私鑰密碼5.2 一個完整的排查案例說一個當時的真實情況。有次我?guī)团笥颜{(diào)一套三節(jié)點的集群hadoop用戶配了免密master01能ssh到worker01但ssh到worker02每次還要密碼。我先在master01上確認~/.ssh/id_rsa.pub內(nèi)容再去worker02比對~/.ssh/authorized_keys最后一行發(fā)現(xiàn)公鑰是有的。繼續(xù)查權(quán)限代碼如下ls -ld /home/hadoop /home/hadoop/.ssh ls -l /home/hadoop/.ssh/authorized_keys結(jié)果發(fā)現(xiàn)/home/hadoop/.ssh目錄權(quán)限是775不是700。問題就出在這里。因為SSH的權(quán)限校驗會檢查hadoop用戶所在組是否擁有寫權(quán)限即使你當前不是組內(nèi)用戶它仍然會拒絕。我執(zhí)行chmod 700 /home/hadoop/.ssh chmod 600 /home/hadoop/.ssh/authorized_keys再試免密立即通過了。所以很多免密失敗真的不是“公鑰沒配好”而是“就差一個數(shù)字權(quán)限”。另外還有一個容易忽略的如果你曾經(jīng)以root身份對hadoop用戶的文件做過chown -R導(dǎo)致.ssh目錄的屬主變成root那公鑰認證一樣會失敗。正確屬主必須始終是hadoop用戶自己。你可以在客戶端用ssh -v查看debug信息服務(wù)端看auth.log兩邊對一下問題很快定位。6. 收尾擴展維護層面的幾點體會免密配好不是終點后續(xù)維護中還要注意幾件事。隨著集群擴容新節(jié)點的免密配置要納入初始化流程別等啟動失敗才想起來。我一般會寫一個setup_ssh.sh把ssh-keygen、ssh-copy-id、權(quán)限修正全部串在一起每次加節(jié)點后跑一遍能省很多事。另外盡量別把hadoop用戶的私鑰復(fù)制到不穩(wěn)定或不受控的第三方機器上。私鑰一旦泄露等于所有節(jié)點都能被登錄。對于重要集群可以在防火墻層面限制SSH的訪問來源并把sshd_config里的AllowUsers hadoop網(wǎng)段加上把風險收斂到一個相對小的范圍。我個人在實際操作中最深的體會是配置SSH免密難的不是敲命令而是理解“權(quán)限到底在保護什么”。很多教程只給命令不給原因?qū)е鲁隽藛栴}只能瞎撞。把公鑰認證的校驗流程和文件的ownership、permission對應(yīng)起來想清楚之后這套配置基本就是一次搞定。希望這篇文章能幫你少走彎路。