Spark与hdfs delegation token过期的排查思路总结

news/2024/5/20 1:15:49 标签: hdfs, spark, hadoop

背景

hadoop delegation token的问题相对比较混乱和复杂,简单说下这东西的出现背景,最早的hadoop的因没有的完善的安全机制(安全机制主要包括:认证 + 鉴权,hadoop这里主要是身份认证机制没有),所以导致操作风险比较大,你可以理解只要获取了一台装有hadoop client的机器,就可以任意操作HDFS系统了,深究原因是因为hadoop身份认证机制太薄弱,所以只要黑了一台机器就可以发起各种危险操作了,所以各方大佬们云集讨论了一个可靠的安全方案,最终在SSL协议和Kerberos协议中,选择了Kerberos,主要有两个原因:

1,性能。因为SSL数据传输中包含非对称加密算法,相对耗时比较大,而Kerberos则完全采用对称加密

2,易于维护管理。Kerberos里面如果撤销一个客户端的访问权,直接在KDC(key distribution center)秘钥分发中心删除掉这个用户即可,而SSL里面,则需要生成一个证书吊销列表然后分发到所有的服务器中,对比而言Kerberos的集中式管理更方便维护

Kerberos介绍

Kerberos一些术语:

  • KDC:密钥分发巾心,负责管理发放票据,记录授权。
  • Realm: Kerberos管理领域的标识。
  • principalKerberos 下的用户可以称为 Principal,当每添加一个用户或服务的时候都需要向kdc添加一条principal, principal的形式为:主名称/实例名@领域名
  • 主名称:主名称可以是用户名或服务名,表示是用于提供各种网络服务(如hdfs、yam,、hive) 的主体。
  • 实例名:实例名简单理解为主机名。
  • keytab文件:存储了用户的加密密码。常用这种方式认证。

使用Kerberos协议后,一次客户端访问服务端的认证流程如下:

Kerberos的架构和工作原理

  • AS_REQ 是在初始化一个用户(kinit)的时候发出的用户认证请求,这个请求是发给KDC中的Authentication Server (AS);
  • AS_REP 是 AS回复给client的信息,其中包括TGT (用TGS secret key加密过的) and the session key (用发请求的用户的secret key加密过的);
  • TGS_REQ 是client为了一个service ticket向Ticket Granting Server (TGS)的信息. 其中包括上一条信息中获得的TGT (用TGS secret key加密过的) ,一个客户端产生的一个authenticator(用session key加密过的).
  • TGS_REP 是TGS回复给TGS_REQ的信息. 其中包括service ticket(用appservice的secret key加密过),和 一个TGS产生的service sessinon key(之前AS产生的一条session key给加密过的)
  • AP_REQ 是一条客户端发给appserver的访问服务的请求,其中包括service ticket和一个authenticator(使用TGS产生的service session key 加密过的)
  • AP_REP 是appserver回复给client的一条信息,证明这个appserver确实是客户端希望访问的server。不过这条信息也不一定总是要回复的。比如当客户端和appserver需要相互认证的时候,客户端向appserver发出请求,这个时候就不需要回复信息。

Delegation Token介绍

Delegation Token(委托令牌,缩写DT),前面我们知道了Kerberos的工作原理,那么Hadoop的 Delegation Token又是怎么来的?

虽然理论上可以单独使用 Kerberos 进行身份验证,但在 Hadoop 等分布式系统中使用时,它有一些弊端。想象一下,对于每个 MapReduce 作业,如果所有YARN的NodeManager节点或者Spark的Executor节点,都必须使用委托的 TGT(Ticket Granting Ticket)通过 Kerberos 进行身份验证,那么 Kerberos 密钥分发中心 (KDC) 将很快成为瓶颈。一次大的Job作业可能有数千个节点到节点的通信,这样就会导致放大对KDC中心的请求服务。事实上,它会无意中在非常大的集群中对 KDC 执行分布式拒绝服务攻击。

因此,Hadoop Delegation Token委托令牌作为一种轻量级身份验证方法被引入,以补充 Kerberos 身份验证。 Kerberos 是一个三方协议;相反,Delegation Token 身份验证是一种两方身份验证协议。

DT的工作原理如下:

1,客户端最初使用kinit或者keytab文件,完成与 Kerberos 的身份验证,并拿到TGT,然后通过TGT到TGS获取到HDFS服务的票证之后,再拿着Ticket从Name Node服务中获取委托令牌

2,客户端使用DT委派令牌与YARN进行通信和提交任务进行后续身份验证,整个过程不再使用 Kerberos

更详细的图示如下:

YARN Long Running应用的问题

看起来一切很美好,但这里面有个最大的问题是KDC颁发的票据是有最大生命周期的默认是7天,然后在7天内,每隔24颁发的票据就会失效,如果票据过期了,可以通过程序renew token来续约,这个时间一般是在过期前就会完成,准确来说是24*0.75=18个小时。

那么当票据的最大时间到了之后,会发生什么情况呢?很简单服务直接挂掉,因为token过期失效了,也就是我们经常遇到的两种异常情况:

1,Token is expired

2,Token can’t be found in cache

其实都是一个意思,只不过根据失效的时间长短抛出来的有所不同

默认的7天,对于普通离线Job基本绰绰有余了,但对于实时应用,如flink,spark流等的程序,可能就会失败,所以这里的问题又改怎么解决呢。

Hadoop YARN的官方文档给出了四种主流策略:

一,使用本地文件系统存储keytab文件

为应用程序在每个节点上的使用提供了一个keytab文件,将其安装在每个集群节点的本地文件系统中。

在配置选项中提供此路径,一般是环境变量注入。应用程序通过 UserGroupInformation.loginUserFromKeytab() 加载凭据。密钥表必须位于安全目录路径中,只有服务(和其他受信任的帐户)可以读取它。这实际上是所有静态 Hadoop 应用程序获取其安全凭证的方式

二,使用HDFS文件系统存储keytab文件

将keytab文件密钥表被上传到 HDFS。启动 AM 时,keytab 被列为本地化到 AM 容器的资源。

Application Master 配置了 keytab 的相对路径,并使用 UserGroupInformation.loginUserFromKeytab() 登录。

当 AM 启动容器时,它会将指向 keytab 的 HDFS 路径列为要本地化的资源。它将 HDFS 委托令牌添加到容器启动上下文中,以便可以本地化 keytab 和其他应用程序文件。

启动的容器必须自己通过 UserGroupInformation.loginUserFromKeytab() 登录。 UGI 处理登录,并安排一个后台线程定期重新登录用户。

令牌创建在 Hadoop IPC 和 REST API 中自动处理,容器在整个持续时间内通过 kerberos 保持登录状态。

这避免了为整个集群中的特定服务安装 keytab 的管理任务。它确实要求客户端有权访问密钥表,并且当它上传到分布式文件系统时,必须通过适当的路径权限/ACL 来保护它。

由于所有容器都可以访问密钥表,因此必须信任在容器中执行的所有代码。恶意代码(或逃避某种形式的沙箱的代码)可以读取密钥表,因此可以访问集群,直到密钥过期或被撤销。

三,使用HDFS存储keytab,通过AM生成token和续约token,并通过RPC分发给所有的Executor节点

1,client把keytab上传到HDFS

2,当启动AM的时候,会把这个keytab文件下载到AM运行的container里面

3,Application Master 配置了 keytab 的相对路径,并使用 UserGroupInformation.loginUserFromKeytab() 登录。 UGI 代码路径仍将通过 $HADOOP_TOKEN_FILE_LOCATION 自动加载文件引用,这是获取 AMRM 令牌的方式

4,当 AM 启动一个容器时,它会获取该容器所需的所有委托令牌,并将它们添加到容器的容器启动上下文中,典型的就是AM提交YARN任务时,会把token添加到上下文中,发送给RM,当RM启动NM时,又会把token下发到各个NM中

5,启动的容器必须从 $HADOOP_TOKEN_FILE_LOCATION 加载委托令牌,并使用它们(包括续订),直到它们无法再续订

6,AM和Executor 必须实现一个 IPC 接口,该接口允许接受请求一组新的委托令牌;

7,在委托令牌到期之前,client也就是driver进程会重新new新的token,然后通过 IPC 通道发送给AM和Execuor,从而确保他们能够长时间运行

这就是 Apache Spark 1.5+ 以后使用的策略,在容器和 AM 之间使用基于自定义的RPC网络的协议(最早是akka,目前已经重写)进行令牌更新

四,使用本地文件系统存储keytab,在机器上定时kinit认证

这种方式比较简单,与应用程序解耦,需要一个crontab定时任务,在token续约到期之前,自动执行kinit即可,唯一需要注意的就是,如果集群扩容什么的,新加的机器要确保也执行了,否则任务运行在这上面就会失败

上面几种策略,我们可以根据实际情况选择合适的一种来操作,从而避免让我们的实时应用只能跑7天

hadoop配置中和token相关的配置参数:

dfs.namenode.delegation.token.max-lifetime = 604800000 ms (7天)
dfs.namenode.delegation.key.update-interval = 86400000 ms  (1天)
dfs.namenode.delegation.token.renew-interval = 86400000 ms (1天)

在测试验证时,可以修改短点来验证,比如10,,3,3

Spark的Token过期问题

从前面的介绍中,我们现在应该大致了解了整个委托token的相关知识,但在实际使用过程中,仍然会遇到各种问题,因为像大数据系统涉及组件多,出一个问题说实话不太容易定位或者容易把排查方向搞偏,这里总结一下排查这种问题的经验,我总结为4个层面:

1,kerberbos层面

这个层面一般不容易遇到问题,但是如果要支持多个开启了Kerberos认证的hadoop集群之间互相访问数据,大概率会遇到访问失败问题,因为这种情况是需要打通两边kerberos的,当然好消息是kerberos是支持的,只需要我们配置正确即可

2,hadoop层面

Hadoop层面是最容易出现问题的,因为现在hadoop有很多个版本,建议新集群大家直接用hadoop 2.8+以上的版本,基本不会在遇到token问题,但在这个版本之前比如2.7和2.6都有各种各样的bug存在,需要我们打patch才能解决,详情可参考HDFS 9276的ISSUE

3,spark层面

spark层面其实还好,不容易出现这种问题,因为Spark使用的人多,社区也比较活跃,所以spark在1.5版本的时候都设计了可以解决实时应用长时间跑在yarn上的问题。当然也不要心存侥幸,有两个地方也会出问题:

spark编译的时候依赖了低于hadoop 2.8的版本,那么长时间运行的应用大概率也会遇到token过期的问题,所以编译时候要注意,另外就算依赖高于hadoop 2.8的版本,spark自身的代码也会存在bug从而引发token问题,我们就遇到了:

第一个是renew schdule的时长是一个long的最大值,这样会导致driver永远不会更新token,解决方法:把hadoop-hdfs-2.8.5的jar拷贝到spark的jars目录就行了,因为缺失一个SPI的描述文件导致的。

第二个是spark3.0.1版本独有的bug,driver生成的token无法传给AM,从而导致在token超过7天之后,AM新生成的Executor都会失败。解决方法:参考SPARK-32905

这里推荐两个稳定版本:spark 2.4.3 和 spark 3.0.2,有条件直接上最新的更好。

4,应用层面

这个主要指的是,如果你的应用是通过shade的fat jar提交运行的,那么很有可能你的shade jar里面包含了一些hadoop或者spark版本不一致的代码,从而可能会引发类冲突或者加载顺序的问题,导致命中某个bug,所以这里建议大家服务端提供了依赖,fat jar就不要再打进去了,减少这种问题发生的几率。

总结

本篇介绍的内容,都是我们在生产环境遇到的一些问题,当然我们现在主要用的是spark,所以介绍的spark的内容会多一点,如果你正在使用的是flink,也不要紧,解决问题的思路都是是相通的,也可以按照文中的思路在遇到token过期问题时来进行排查,大数据组件因为复杂和繁多,当组合到一起时经常会遇到一些问题,这个时候我们也不要着急,多用谷歌搜索+善用组件的官网ISSUE文档,如果实在还没迹可循,那只能看源码细细捋了,可以造一个测试环境,方便排查,这样可以验证我们的各种想法,也会大大提升我们排查问题的效率。

参考文章:

Kerberos认证原理与环境部署 - 大数据老司机 - 博客园

Hadoop Delegation Tokens Explained - Cloudera Blog

https://issues.apache.org/jira/secure/attachment/12428537/security-design.pdf

https://www.slideshare.net/oom65/hadoop-security-architecture

[HADOOP-4487] Security features for Hadoop - ASF JIRA

[HDFS-9276] Failed to Update HDFS Delegation Token for long running application in HA mode - ASF JIRA

[SPARK-32905] ApplicationMaster fails to receive UpdateDelegationTokens message - ASF JIRA

Apache Hadoop 3.3.4 – YARN Application Security

https://github.com/apache/spark/blob/master/core/src/main/scala/org/apache/spark/deploy/security/README.md


http://www.niftyadmin.cn/n/787143.html

相关文章

为什么人会摆高姿态_高姿态是什么意思(恋爱中的高姿态有哪些坏处

文/肆叔&安心 图/来源网络01前不久倩倩和男友分手了,朋友们知道后都非常诧异。倩倩的男友小宇是出了名的二十四孝男友。从日常生活的点滴关怀到从不缺席的节日礼物,绝对是个理想型男友。有一年倩倩生日,为了给她买礼物,小宇硬…

一次jenkins-kubernetes服务报错排查记录 (Request Header Fields Too Large)

背景 最近我们自研的云原生发布平台新支持了一种发布场景,简单来说client里面会把k8s里面的各资源文件比如: deploy.yaml service.yaml ingress.yaml pvc.yaml 分别用字符串变量保存,然后通过jenkins开源库sdk传给一个带参数的jenkins …

分层结构的生活例子_分层架构中的服务层-服务层实战

引言服务层是在交互的两个层中间又定义了另外一个层,典型的是在表现层和业务逻辑层之间。这个中间层只是实现应用的用例的类集合。服务和面向服务的出现,使得整个解决方案更有价值、更加成功。与表现层相比,服务层提供了松散的耦合&#xff0…

asc.desc

DESC 是descend 降序意思 asc 是ascend 升序的意思转载于:https://www.cnblogs.com/toSeeMyDream/p/5860480.html

企业级实战——畅购商城SpringCloud-微服务网关鉴权限流解决方案-JWT+nginx——添加商品参数查询实现

QQ 1274510382 Wechat JNZ_aming 商业联盟 QQ群538250800 技术搞事 QQ群599020441 解决方案 QQ群152889761 加入我们 QQ群649347320 共享学习 QQ群674240731 纪年科技aming 网络安全 ,深度学习,嵌入式,机器强化,生物智能,生命科学。 纸上得来终觉浅,绝知此事要躬行 &#xff0…

vue3+axios刷新浏览器interceptors无效问题

问题描述 vue前端应用在用户登录之后,服务端会返回一个认证token,前端会将此token存在cookie中,之后前端每次发起的向服务端的请求时,会通过axios的interceptors.request方法,来自动将cookie中的token取出来放在请求头…

【数据挖掘】时间序列教程【一】

第一章 说明 对于时间序列的研究,可以追溯到19世纪末和20世纪初。当时,许多学者开始对时间相关的经济和社会现象进行研究,尝试发现其规律和趋势。其中最早的时间序列研究可以追溯到法国经济学家易贝尔(Maurice Allais)…

企业级实战——畅购商城SpringCloud-微服务网关鉴权限流解决方案-JWT+nginx——根据分类ID查询规格集合实现

QQ 1274510382 Wechat JNZ_aming 商业联盟 QQ群538250800 技术搞事 QQ群599020441 解决方案 QQ群152889761 加入我们 QQ群649347320 共享学习 QQ群674240731 纪年科技aming 网络安全 ,深度学习,嵌入式,机器强化,生物智能,生命科学。 纸上得来终觉浅,绝知此事要躬行 &#xff0…