Flink on YARN Security 浅析 (YARN Part)

自我们将作业迁移到 Kerberized 的 YARN 新集群后,运行中的作业有一定几率出现出现认证失败,其中失败有 AMRMToken 过期导致 AM 无法与 RM 通信而被 kill 掉和 AM 申请的新 container 启动时报缺少 credential 两种表现。出现了这个问题后只能重启作业解决,这严重影响了平台的稳定性,因此笔者前后投入了接近两周的时间去研究这个问题,最后定位到问题在于 RM 刷新 viewfs token 时只会刷新第一个挂载的 FS 的 token。另一方面,笔者对于 YARN Security 和 Flink 与 YARN 在安全机制上的集成已经有了一定的积累,所以先记录并分享出来,以便后续有需要时检索(retrive)和与其他同学讨论交流。

下文将先解释 Hadoop delegation token 的作用和种类,然后介绍 YARN Application 是如何应用这些 token 的,最后再解析 Flink 如何使用 YARN 的 API 来完成安全认证。值得注意的是,YARN 框架的系统级认证和 Application 的用户级认证是有所不同的。前者是 YARN 如何代表用户完成系统级的工作(下载所需资源、以用户身份启动进程等),更侧重于 YARN,后者是用户应用自身的安全操作(以什么身份访问 Hive、Hbase 等),更侧重于 Application(Flink)。本文将主要关注前者,而关于 Flink on YARN 应用安全机制的内容将留到下一篇博客。

Hadoop Delegation Token

关于 Hadoop delegation token 的背景和实现,Cloudera 有一篇很棒博客[1],这里简单总结下。

Delegatin token 是 Hadoop 生态圈广泛使用的一种认证机制,包括 HDFS、YARN、HBase 等都支持 delegation token。Delegation token 机制基于 Kerberos,类似于 Kerberos TGT (Ticket Granting Ticket)。区别在于 TGT 的 renewal 需要请求 KDC 完成,是个三方协议,而 delegation token 的 renewal 只涉及到用户和服务,是个两方协议,这样的好处是避免了集群上所有机器初始化作业或后续 renew TGT 对 KDC 造成的巨大请求量。另外由于 delegation token 是服务级别并且由相应的服务管理,delegation token 的泄漏只会造成对应服务在 token 有效期(3-7天)内的不安全,相比分发 keytab 或者 TGT 到机器上更加安全。

Hadoop 安全认证

Delegation token 的工作方式是(见图一): 用户先通过 Kerberos 认证并向需要访问的服务(比如 NameNode、ResourceManager)申请 delegation token,在提交作业时将这些 token 一并附上,然后作业被分发到集群机器上后自动通过附带的 token 来认证。

在 Hadoop 内部 delegation token 有很多种,HDFS 使用的 token 主要是 HDFS delegation token,YARN 使用的 token 可参见董西成的一篇博客[2](版本是较老的 Hadoop 2.0 ,但 2.x 系列变动不大)。下文会主要围绕开发 YARN application 涉及到的最基础的两个 token,即 HDFS delegation token 和 AMRMToken 展开。

YARN Application 的认证方式

YARN Security 在官网[3]有详细的描述,这里结合我们的应用场景简单总结下。

Application 首次运行的认证

在提交作业时,YARN client 需要获取作业运行时用到的所有 delegation token 并设置到 ApplicationSubmissionContext 里面。其中的 token 可以分为两类,一是系统 token,包括 HDFS delegation token 和 AMRMToken,二是用户 token,包括访问 HBase 或其他服务的 token。两者的区别在于系统 token 是 YARN 内部使用并负责管理的,而用户 token 则是可选的。

HDFS delegation token 是 NameNode 赋予的访问 HDFS 的凭证。YARN Client 提交作业前需要先向 NameNode 申请 HDFS delegation token,将作业所需资源上传到 HDFS,然后将 token 设置到 ApplicationSubmissionContext 里。对于 YARN 来说 HDFS delegation token 主要用在两个地方: log aggregation 和 container localization。log aggregation 是指收集用户作业日志上传到 HDFS;container localization 是指在 container 启动前将用户指定的资源从 HDFS 上下载到本地。两者都发生在 container 启动前,但 log aggregation 的失败不会影响 container 的启动,而 localization 则是必须的。

AMRMToken 是 ApplicationMaster 与 ResourceManager 通信的凭证。YARN Client 提交作业后会收到 ResourceManager 生成的 AMRMToken,这个 token 会被设置到 ApplicationSubmissionContext 里面传递给 AM 用于后续的通信。此后每次 AM 和 RM 的心跳或者其他通信,AM 都要附上 AMRMToken。

Application 后续运行的凭证刷新

虽然首次运行没有问题,但随着作业运行时间变长 token 会失效,因此需要相应的 token 刷新机制来保证作业认证凭证的有效性。HDFS delegation token 和 AMRMToken 均属于系统 token,因此都由 YARN 来刷新。

对于 HDFS delegation token,YARN 在 [YARN-2704][2] 引入了 proxy-user 的功能,即 YARN RM 可以代替用户刷新 HDFS delegation token。这里的刷新有两种方式,一是 renew,即在 HDFS delegation token 失效前向 RM 续订(默认 1 天),延长 token 的有效期;二是当 token 达到最大生命周期(默认 7 天)后不能再被续订,此时需要申请一个新的 token 来代替旧 token。

对于 AMRMToken,RM 会每天刷新一次,刷新的方式是更新用于生成 AMRMToken 的 master key。在准备启用新 master key 的一个窗口内(默认 15 分钟),当 RM 发现 AM 心跳使用的是旧 master key,就会返回新的 master key 给 AM 通知它更新。过了这个更新窗口,AM 再使用旧 master key 生成的 token 通信,就会得到 Invalid Token 的报错。

Flink on YARN 作业提交流程

Flink on YARN 的 Application 提交流程如下[4]:

  1. Flink client(同时也是 YARN client)会先通过 Kerberos 认证,向 Namenode 申请 HDFS delegation token 并上传作业依赖到 HDFS。
  2. Flink client 将相应的资源和 token 设置到 ApplicationSubmissionContext 里面,提交 Application。
  3. YARN RM 收到提交作业请求后记录下 Application 对应的 token ,并分配一个 container 启动 ApplicationMaster,其中包括了 Flink JobManager。
  4. JobManager 启动后会将自己的 HDFS delegation token 和 TaskManager 启动的资源设置到 ContainerLaunchContext 里面,然后提交给 YARN RM。RM 收到请求后分配 container token 给 AM,AM 再凭借这个 token 向 NodeManager 要求并启动 container。

其中每个 container (包括 AM container 和一般 container)启动前 RM 会将这个 Application 的 token 发送给 NodeManager,因此 NodeManager 能以用户的身份完成 container 启动的前置工作以及最终启动 container。

总结

YARN Security 的设计思想在于用户在 Client 端先通过 Kerberos 认证获取基本服务(YARN、HDFS)的 delegation token,并作为 Application Submission Context 的凭证提交给 RM。如果 Application 可以成功运行则证明了用户凭证的有效性,token 后续的刷新和重新获取都由 RM 来负责。不过新 token 仅限 YARN 内部使用,用户应用本身的 token 失效问题仍需要用户自己处理。

参考文献

1.Hadoop Delegation Tokens Explained
2.Hadoop 2.0(YARN)中的安全机制概述
3.Apache Hadoop 官方文档: YARN Security
4.Apache Flink 官方文档: on YARN 模式