yarn-cluster模式spark应用客户端与集群的通信端口

Spark应用在on yarn模式下运行,需要打开集群中的节点的端口以便完成应用的提交和运行。下面针对yarn-cluster模式下提交spark应用需要的集群端口进行测试。

非安全集群场景下

测试结论:

集群外节点yarn-clsuter模式下提交spark应用,需要连接ResourceManager完成app的提交,同时也需要上传部分文件到hdfs以供container使用。因此至少需要开通ResourceManager,NameNode,DataNode等节点与客户端的通信端口。

非安全模式下需要对客户端开通的几个端口:

服务 使用原因 参数 端口默认值 端口协议
ResourceManager 提交app时与RM通信 yarn.resourcemanager.address 8050 TCP
Namenode 上传文件至hdfs时与NN通信 dfs.namenode.rpc-address 8020 TCP
DataNode 上传文件时与DN通信 dfs.datanode.address 50010 TCP

测试方法:

准备工作

* 准备一个三节点hadoop集群(节点ip分别设为ip1,ip2,ip3)和一个集群外节点(ip_external)  
* 在ip_external创建创建hadoop_conf目录(将集群中$HADOOP_HOME/conf目录下文件copy至hadoop_conf目录)
* 安装spark客户端(将集群中的$SPARK_HOME下文件copy至集群外ip_external节点),在spark-env.sh中配置HADOOP_CONF_DIR并指向hadoop_conf目录

测试步骤

  • 屏蔽集群中节点对客户端的所有端口

通过在集群中各节点执行如下命令将集群中节点通过iptables设置对ip_external的所有端口(用户端口)均屏蔽

iptables -A INPUT -s ip_external -p tcp --dport 1025:65535  -j DROP

此时以cluster模式提交spark应用,有如下打印,长时间无法提交应用

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参数控制,默认8050),显然相关打印是由于端口被屏蔽,导致客户端无法和ResourceManager通信导致。
  • 打开ResourceManager节点对客户端节点的端口

登录ipv3节点,执行如下命令,打开8050端口与ip_external的通信

//清理iptables设置
iptables -F
//添加iptables设置
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应用,有如下打印,长时间无法提交应用

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参数控制,默认8020),显然相关打印是由于端口被屏蔽,导致客户端无法和NameNode通信导致。
  • 打开NameNode节点对客户端节点的端口

登录ip2节点,执行如下命令,打开8020端口与ip_external的通信

//清理iptables设置
iptables -F
//添加iptables设置
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应用,抛出如下异常,提交失败

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失败,无法将文件上传至datanode,引发失败。客户端与datanode通信端口(dfs.datanode.address参数控制,默认50010)
  • 打开DataNode节点对客户端节点的端

分别登录ip1,ip2,ip3三个节点,打开50010的端口与客户端的通信。同样是先清理iptable配置,再添加,参考如上操作即可。

此时提交spark应用,成功运行。

安全集群场景下

测试结论:

安全集群场景下除了打开以上端口外,还需要关注安全认证的kdc服务端口,以及可能的timelineservice服务的端口。

安全模式下需要对客户端开通的几个端口:

服务 使用原因 参数 端口默认值 端口协议
kdc 与集群交互前需要在kdc进行认证用户信息 kdc_ports 88 UDP
ResourceManager 提交app时与RM通信 yarn.resourcemanager.address 8050 TCP
TimeLineService 安全模式下,需要客户端获取TImeLineService服务的token yarn.timeline-service.webapp.address 8188 TCP
Namenode 上传文件至hdfs时与NN通信 dfs.namenode.rpc-address 8020 TCP
DataNode 上传文件时与DN通信 dfs.datanode.address 50010 TCP

测试方法:

准备工作

* 准备一个三节点安全hadoop集群(节点ip分别设为ip4,ip5,ip6)和一个集群外节点(ip_external) ,hadoop集群的kdc节点的ip为ip_kdc
* 在ip_external节点创建hadoop_conf_security目录(将集群中$HADOOP_HOME/conf目录下文件copy至hadoop_conf目录)
* 安装spark客户端(将集群中的$SPARK_HOME下文件copy至集群外ip_external节点),在spark-env.sh中配置HADOOP_CONF_DIR并指向hadoop_conf_security目录
* 将集群的/etc/security/keytab下要用于提交应用的keytabf文件copy至ip_external节点相关目录下,和/etc/krb5.con文件copy至ip_external节点的/etc目录下

测试步骤

根据非安全集群下的测试情况,首先打开所需rm,nn,dn相关端口

  • 先不对kdc几点做处理,提交应用,应用提交成功

  • 屏蔽kdc节点的所有端口

    登录登录kerberos节点,关闭所有端口与ip_external节点的通信,使用如下命令(由于kdc服务默认使用的是88端口,直接关闭1:65536)

      iptables -A INPUT -s ip_external -p tcp --dport 1:65535  -j DROP
    

    提交spark应用,应用正常运行。这与预期不一致。

    分析: 在安全集群中所有与集群中安全的服务通信的进程(客户端)都需要完成与kdc认证之后才能访问集群中的服务,在关闭端口与客户端通信之后,居然可以完成认证而且还可以提交运行应用,比较诡异。

    再次登录kdc节点,使用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 
    

    说明此服务同时支持tcp和udp协议,猜测客户端进行kerberos认证是通过udp协议完成

  • 屏蔽kdc节点的udp协议的88端口

     iptables -A INPUT -s ip_external -p tcp --dport 88  -j DROP
    

    再次提交spark应用,客户端卡主,无法完成应用的提交,说明需要打开kdc服务使用端口的udp服务,客户端才能提交应用

  • 打开kdc节点的udp协议的88端口

    再次提交spark应用,应用提交失败出现如下异常:

      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服务通信时异常,引发失败,通信端口(yarn.timeline-service.webapp.address参数控制,默认8188)

  • 打开timelineservice 服务节点的8188端口
    由于本集群的timelineService服务和RM服务在同一节点,登录该节点:

     // 清理原有的iptables设置
     iptables -F
     //添加iptables设置
     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
    

    此时提交应用,运行正常。

安全和非安全环境下对timelineservice服务的端口访问要求不同的原因

查看yarnclientImpl 源码发现在submitApplication的函数中,有如下逻辑:

//根据集群安全性和timeLineService情况判断是否需要为am添加timeLine服务的token
if (isSecurityEnabled() && timelineServiceEnabled) {
  addTimelineDelegationToken(appContext.getAMContainerSpec());
}
//该函数中会调用到
timelineDelegationToken = getTimelineDelegationToken();

继续跟踪代码可以发现在安全模式下,与其他服务(hdfs,hive,hbase)的默认的访问机制一样,客户端会先获取timelineservicetoken并存入hdfs目录, 以供applicationMaster运行时使用。

由于只有在安全模式下,才可能使用此逻辑,因此在安全和非全的集群中,使用cluster模式提交应用,需要关注一下集群的timelineService服务。

你可能感兴趣的:(yarn-cluster模式spark应用客户端与集群的通信端口)