Spark應(yīng)用在on yarn模式下運(yùn)行,需要打開(kāi)集群中的節(jié)點(diǎn)的端口以便完成應(yīng)用的提交和運(yùn)行。下面針對(duì)yarn-cluster模式下提交spark應(yīng)用需要的集群端口進(jìn)行測(cè)試。
非安全集群場(chǎng)景下
測(cè)試結(jié)論:
集群外節(jié)點(diǎn)yarn-clsuter模式下提交spark應(yīng)用,需要連接ResourceManager完成app的提交,同時(shí)也需要上傳部分文件到hdfs以供container使用。因此至少需要開(kāi)通ResourceManager,NameNode,DataNode等節(jié)點(diǎn)與客戶端的通信端口。
非安全模式下需要對(duì)客戶端開(kāi)通的幾個(gè)端口:
| 服務(wù) | 使用原因 | 參數(shù) | 端口默認(rèn)值 | 端口協(xié)議 |
|---|---|---|---|---|
| ResourceManager | 提交app時(shí)與RM通信 | yarn.resourcemanager.address | 8050 | TCP |
| Namenode | 上傳文件至hdfs時(shí)與NN通信 | dfs.namenode.rpc-address | 8020 | TCP |
| DataNode | 上傳文件時(shí)與DN通信 | dfs.datanode.address | 50010 | TCP |
測(cè)試方法:
準(zhǔn)備工作
* 準(zhǔn)備一個(gè)三節(jié)點(diǎn)hadoop集群(節(jié)點(diǎn)ip分別設(shè)為ip1,ip2,ip3)和一個(gè)集群外節(jié)點(diǎn)(ip_external)
* 在ip_external創(chuàng)建創(chuàng)建hadoop_conf目錄(將集群中$HADOOP_HOME/conf目錄下文件copy至hadoop_conf目錄)
* 安裝spark客戶端(將集群中的$SPARK_HOME下文件copy至集群外ip_external節(jié)點(diǎn)),在spark-env.sh中配置HADOOP_CONF_DIR并指向hadoop_conf目錄
測(cè)試步驟
- 屏蔽集群中節(jié)點(diǎn)對(duì)客戶端的所有端口
通過(guò)在集群中各節(jié)點(diǎn)執(zhí)行如下命令將集群中節(jié)點(diǎn)通過(guò)iptables設(shè)置對(duì)ip_external的所有端口(用戶端口)均屏蔽
iptables -A INPUT -s ip_external -p tcp --dport 1025:65535 -j DROP
此時(shí)以cluster模式提交spark應(yīng)用,有如下打印,長(zhǎng)時(shí)間無(wú)法提交應(yīng)用
Retrying connect to server: ip3:8050. Already tried 1 time(s); maxRetries=45
......
Retrying connect to server: ip3:8050. Already tried 44 time(s); maxRetries=45
Retrying connect to server: ip3:8050. Already tried 0 time(s); maxRetries=45
異常分析:
在hdp集群中,8050的ResourdeManager端口(yarn.resourcemanager.address參數(shù)控制,默認(rèn)8050),顯然相關(guān)打印是由于端口被屏蔽,導(dǎo)致客戶端無(wú)法和ResourceManager通信導(dǎo)致。
- 打開(kāi)ResourceManager節(jié)點(diǎn)對(duì)客戶端節(jié)點(diǎn)的端口
登錄ipv3節(jié)點(diǎn),執(zhí)行如下命令,打開(kāi)8050端口與ip_external的通信
//清理iptables設(shè)置
iptables -F
//添加iptables設(shè)置
iptables -A INPUT -s ip_external -p tcp --dport 8050 -j ACCEPT
iptables -A INPUT -s ip_external -p tcp --dport 1025:65535 -j DROP
再次提交spark應(yīng)用,有如下打印,長(zhǎng)時(shí)間無(wú)法提交應(yīng)用
Retrying connect to server: ip2:8020. Already tried 1 time(s); maxRetries=45
......
Retrying connect to server: ip2:8020. Already tried 44 time(s); maxRetries=45
Retrying connect to server: ip2:8020. Already tried 0 time(s); maxRetries=45
異常分析:
在hdp集群中,8020的NameNode端口(dfs.namenode.rpc-address參數(shù)控制,默認(rèn)8020),顯然相關(guān)打印是由于端口被屏蔽,導(dǎo)致客戶端無(wú)法和NameNode通信導(dǎo)致。
- 打開(kāi)NameNode節(jié)點(diǎn)對(duì)客戶端節(jié)點(diǎn)的端口
登錄ip2節(jié)點(diǎn),執(zhí)行如下命令,打開(kāi)8020端口與ip_external的通信
//清理iptables設(shè)置
iptables -F
//添加iptables設(shè)置
iptables -A INPUT -s ip_external -p tcp --dport 8020 -j ACCEPT
iptables -A INPUT -s ip_external -p tcp --dport 1025:65535 -j DROP
再次提交spark應(yīng)用,拋出如下異常,提交失敗
RemoteException(java.io.IOException): File /user/abc/.sparkStaging/application_1521424748238_0198/spark-assembly-1.6.2.2.5.0.0-1245-hadoop2.7.3.2.5.0.0-1245.jar could only be replicated to 0 nodes instead of minReplication (=1). There are 3 datanode(s) running and 3 node(s) are excluded in this operation.
異常分析:
該異常顯示連接datanode失敗,無(wú)法將文件上傳至datanode,引發(fā)失敗??蛻舳伺cdatanode通信端口(dfs.datanode.address參數(shù)控制,默認(rèn)50010)
- 打開(kāi)DataNode節(jié)點(diǎn)對(duì)客戶端節(jié)點(diǎn)的端
分別登錄ip1,ip2,ip3三個(gè)節(jié)點(diǎn),打開(kāi)50010的端口與客戶端的通信。同樣是先清理iptable配置,再添加,參考如上操作即可。
此時(shí)提交spark應(yīng)用,成功運(yùn)行。
安全集群場(chǎng)景下
測(cè)試結(jié)論:
安全集群場(chǎng)景下除了打開(kāi)以上端口外,還需要關(guān)注安全認(rèn)證的kdc服務(wù)端口,以及可能的timelineservice服務(wù)的端口。
安全模式下需要對(duì)客戶端開(kāi)通的幾個(gè)端口:
| 服務(wù) | 使用原因 | 參數(shù) | 端口默認(rèn)值 | 端口協(xié)議 |
|---|---|---|---|---|
| kdc | 與集群交互前需要在kdc進(jìn)行認(rèn)證用戶信息 | kdc_ports | 88 | UDP |
| ResourceManager | 提交app時(shí)與RM通信 | yarn.resourcemanager.address | 8050 | TCP |
| TimeLineService | 安全模式下,需要客戶端獲取TImeLineService服務(wù)的token | yarn.timeline-service.webapp.address | 8188 | TCP |
| Namenode | 上傳文件至hdfs時(shí)與NN通信 | dfs.namenode.rpc-address | 8020 | TCP |
| DataNode | 上傳文件時(shí)與DN通信 | dfs.datanode.address | 50010 | TCP |
測(cè)試方法:
準(zhǔn)備工作
* 準(zhǔn)備一個(gè)三節(jié)點(diǎn)安全hadoop集群(節(jié)點(diǎn)ip分別設(shè)為ip4,ip5,ip6)和一個(gè)集群外節(jié)點(diǎn)(ip_external) ,hadoop集群的kdc節(jié)點(diǎn)的ip為ip_kdc
* 在ip_external節(jié)點(diǎn)創(chuàng)建hadoop_conf_security目錄(將集群中$HADOOP_HOME/conf目錄下文件copy至hadoop_conf目錄)
* 安裝spark客戶端(將集群中的$SPARK_HOME下文件copy至集群外ip_external節(jié)點(diǎn)),在spark-env.sh中配置HADOOP_CONF_DIR并指向hadoop_conf_security目錄
* 將集群的/etc/security/keytab下要用于提交應(yīng)用的keytabf文件copy至ip_external節(jié)點(diǎn)相關(guān)目錄下,和/etc/krb5.con文件copy至ip_external節(jié)點(diǎn)的/etc目錄下
測(cè)試步驟
根據(jù)非安全集群下的測(cè)試情況,首先打開(kāi)所需rm,nn,dn相關(guān)端口
先不對(duì)kdc幾點(diǎn)做處理,提交應(yīng)用,應(yīng)用提交成功
-
屏蔽kdc節(jié)點(diǎn)的所有端口
登錄登錄kerberos節(jié)點(diǎn),關(guān)閉所有端口與ip_external節(jié)點(diǎn)的通信,使用如下命令(由于kdc服務(wù)默認(rèn)使用的是88端口,直接關(guān)閉1:65536)
iptables -A INPUT -s ip_external -p tcp --dport 1:65535 -j DROP提交spark應(yīng)用,應(yīng)用正常運(yùn)行。這與預(yù)期不一致。
分析: 在安全集群中所有與集群中安全的服務(wù)通信的進(jìn)程(客戶端)都需要完成與kdc認(rèn)證之后才能訪問(wèn)集群中的服務(wù),在關(guān)閉端口與客戶端通信之后,居然可以完成認(rèn)證而且還可以提交運(yùn)行應(yīng)用,比較詭異。
再次登錄kdc節(jié)點(diǎn),使用netstat -anp | grep 88 查看到如下信息:
tcp 0 0 0.0.0.0:88 0.0.0.0:* LISTEN 20414/krb5kdc udp 0 0 0.0.0.0:88 0.0.0.0:* 20414/krb5kdc說(shuō)明此服務(wù)同時(shí)支持tcp和udp協(xié)議,猜測(cè)客戶端進(jìn)行kerberos認(rèn)證是通過(guò)udp協(xié)議完成
-
屏蔽kdc節(jié)點(diǎn)的udp協(xié)議的88端口
iptables -A INPUT -s ip_external -p tcp --dport 88 -j DROP再次提交spark應(yīng)用,客戶端卡主,無(wú)法完成應(yīng)用的提交,說(shuō)明需要打開(kāi)kdc服務(wù)使用端口的udp服務(wù),客戶端才能提交應(yīng)用
-
打開(kāi)kdc節(jié)點(diǎn)的udp協(xié)議的88端口
再次提交spark應(yīng)用,應(yīng)用提交失敗出現(xiàn)如下異常:
18/06/21 16:26:11 INFO impl.TimelineClientImpl: Exception caught by TimelineClientConnectionRetry, will try 30 more time(s). Message: connect timed out 18/06/21 16:27:12 INFO impl.TimelineClientImpl: Exception caught by TimelineClientConnectionRetry, will try 29 more time(s). ...該異常顯示timelineClient和timeLineService服務(wù)通信時(shí)異常,引發(fā)失敗,通信端口(yarn.timeline-service.webapp.address參數(shù)控制,默認(rèn)8188)
-
打開(kāi)timelineservice 服務(wù)節(jié)點(diǎn)的8188端口
由于本集群的timelineService服務(wù)和RM服務(wù)在同一節(jié)點(diǎn),登錄該節(jié)點(diǎn):// 清理原有的iptables設(shè)置 iptables -F //添加iptables設(shè)置 iptables -A INPUT -s ip_external -p tcp --dport 8188 -j ACCEPT iptables -A INPUT -s ip_external -p tcp --dport 1019 -j ACCEPT iptables -A INPUT -s ip_external -p tcp --dport 8050 -j ACCEPT iptables -A INPUT -s ip_external -p tcp --dport 1:65535 -j DROP此時(shí)提交應(yīng)用,運(yùn)行正常。
安全和非安全環(huán)境下對(duì)timelineservice服務(wù)的端口訪問(wèn)要求不同的原因
查看yarnclientImpl 源碼發(fā)現(xiàn)在submitApplication的函數(shù)中,有如下邏輯:
//根據(jù)集群安全性和timeLineService情況判斷是否需要為am添加timeLine服務(wù)的token
if (isSecurityEnabled() && timelineServiceEnabled) {
addTimelineDelegationToken(appContext.getAMContainerSpec());
}
//該函數(shù)中會(huì)調(diào)用到
timelineDelegationToken = getTimelineDelegationToken();
繼續(xù)跟蹤代碼可以發(fā)現(xiàn)在安全模式下,與其他服務(wù)(hdfs,hive,hbase)的默認(rèn)的訪問(wèn)機(jī)制一樣,客戶端會(huì)先獲取timelineservicetoken并存入hdfs目錄, 以供applicationMaster運(yùn)行時(shí)使用。
由于只有在安全模式下,才可能使用此邏輯,因此在安全和非全的集群中,使用cluster模式提交應(yīng)用,需要關(guān)注一下集群的timelineService服務(wù)。