overview
编写YARN应用程序的任何人都需要了解该过程,以便编写短期应用程序或长期服务。 他们还需要在早期开发阶段开始对安全集群进行测试,以便编写实际可行的代码。
How YARN Security works
YARN资源管理器(RM)和节点管理器(NM)合作以使用该用户的身份和访问权限来执行用户的应用程序。
The (active) Resource Manager:
1. 在集群中查找空间以部署应用程序的核心,即Application Master(AM)。
2. 请求该节点上的NM分配容器并在其中启动AM。
3. 与AM通信,以便AM可以请求新容器并操纵/释放当前容器,并提供有关已分配和正在运行的容器的通知。
The Node Managers:
1. 本地化资源:从HDFS或其他文件系统下载到本地目录。 这是使用附加到容器启动上下文的委托令牌完成的。 (对于非HDFS资源,使用其他凭据,例如群集配置文件中的对象存储登录详细信息)
2. 以用户身份启动应用程序。
3. 监控应用程序并向RM报告故障。
要在集群中执行代码,YARN应用程序必须:
- 有一个客户端应用程序,它设置ApplicationSubmissionContext,详细说明要启动的内容。 这包括:
集群文件系统中要“本地化”的文件列表。
要在容器中设置的环境变量。
在容器中执行以启动应用程序的命令。
YARN启动应用程序所需的任何安全凭证。
应用程序与任何Hadoop集群服务和应用程序交互所需的任何安全凭证。
2.拥有一个应用程序主机,它在启动时向YARN RM注册并监听事件。 任何希望在其他容器中执行工作的AM必须从RM请求它们,并且在分配时,创建一个ContainerLaunchContext,其中包含要执行的命令,执行命令的环境,本地化的二进制文件以及所有相关的安全凭证。
3.即使NM处理本地化过程,AM本身也必须能够检索在启动时提供的安全凭证,以便它本身可以与HDFS和任何其他服务一起使用,并将部分或全部这些凭证传递给启动容器。
获取和添加令牌到YARN应用程序
必须从作为经过身份验证的用户执行的程序中获取YARN应用程序所需的委托令牌。 对于YARN应用程序,这意味着用户启动应用程序。 它是YARN应用程序的客户端部分必须执行此操作:
- 通过UserGroupInformation登录。
- 确定必须获取的所有令牌。
- 从特定的Hadoop服务请求这些令牌。
- Marshall将所有令牌转换为字节缓冲区。
- 将它们添加到ApplicationSubmissionContext中的ContainerLaunchContext。
需要哪些令牌? 通常,至少有一个令牌来访问HDFS。
应用程序必须从与其打算交互的每个文件系统请求委托令牌 - 包括集群的主FS。 FileSystem.addDelegationTokens(更新者,凭证)可用于收集这些; 对于那些不发行令牌的文件系统(包括非kerberized HDFS集群),这是一个无操作。
与其他服务(例如Apache HBase和Apache Hive)交谈的应用程序必须使用这些服务的库来请求来自这些服务的令牌以获取委托令牌。 可以将所有令牌添加到同一组凭据中,然后保存到字节缓冲区以进行提交。
应用程序时间轴服务器还需要一个委托令牌。 这是在AM发布时自动处理的。
在AM中提取令牌
启动Application Master并调用触发用户登录的任何UGI / Hadoop操作时,UGI类将自动加载保存在由环境变量HADOOP_TOKEN_FILE_LOCATION命名的文件中的所有标记。
即使应用程序使用了密钥表,这也会发生在不安全的群集和安全群集上,以及安全群集上。 为什么? 因为使用YARN RM验证应用程序所需的AM / RM令牌始终以这种方式提供。
这意味着您在安全和不安全的群集中拥有相对类似的工作流程。
- 确保AM启动,登录Kerberos。 对UserGroupInformation.isSecurityEnabled()的调用将触发此操作。
- 通过调用UserGroupInformation.getCurrentUser()。getCredentials()枚举当前用户的凭据。
- 过滤掉AMRM令牌,生成一组新凭据。 在不安全的群集中,凭据列表现在将为空; 在他们将包含的安全集群中
- 将要启动的所有容器的凭据设置为此(可能为空)凭据列表。
- 如果要更新的标记的已过滤列表是非空的,则启动一个线程来续订它们。
令牌续订
代币过期:它们的寿命有限。 希望在此到期日期之后使用令牌的应用程序必须在令牌过期之前续订令牌。
Hadoop会在需要时自动设置委托令牌续订线程,即DelegationTokenRenewer。
应用程序有责任续订除AMRM和时间线令牌之外的所有令牌。
以下是不同的策略
- 不要。 依赖于应用程序的生命周期如此之短,以至于不需要令牌更新。 对于寿命总是可以在几分钟或几十分钟内测量的应用,这是一种可行的策略。
- 启动后台线程/执行程序以定期更新令牌。 这是大多数YARN应用程序所做的
YARN安全的其他方面
AM / RM令牌刷新
AM / RM令牌自动更新; AM在分配消息中将新令牌推送到AM。 请参阅AMRMClientImpl类以查看该过程。 您的AM代码无需担心此过程
AM 令牌续订重启
即使应用程序定期更新令牌,如果AM失败并重新启动,它也会从原始的ApplicationSubmissionContext重新启动。 那里的令牌可能已经过期,因此即使在发出与其他服务进行通信的凭证之前,本地化也可能会失败。
这个问题是如何解决的? 如果需要,YARN资源管理器将为节点管理器获取新令牌。
更确切地说
- RM根据需要刷新/更新由RM传递给NM以进行本地化的令牌。
- 应用程序启动上下文中供应用程序使用的标记不会刷新。 也就是说,如果它有一个过时的HDFS令牌 - 该令牌没有更新。 这也适用于Hive,HBase等的令牌。
- 因此,为了在令牌到期后重新启动AM,您的AM必须让NM在本地化keytab或不进行HDFS访问,直到(某种方式)从客户端传递新令牌。
这主要是长期服务的问题(见下文)。
非管理应用程序masters
未管理的应用程序主服务器不会在RM和NM设置的容器中启动,因此无法在启动时自动获取AM / RM令牌。 YarnClient.getAMRMToken()API允许非托管AM请求AM / RM令牌。 有关详细信息,请参阅UnmanagedAMLauncher。
不安全群集上的身份:HADOOP_USER_NAME
在不安全的群集中,应用程序将作为节点管理器帐户的标识运行,通常是诸如yarn或mapred之类的东西。 默认情况下,应用程序将以该用户身份访问HDFS,具有不同的主目录,并在审核日志和文件系统所有者属性中标识不同的用户。
通过让客户端识别预期应用程序运行的HDFS / Hadoop用户的标识,可以避免这种情况。 这不会影响操作系统级用户或应用程序对本地计算机的访问权限。
禁用Kerberos时,Hadoop首先从环境变量HADOOP_USER_NAME中获取用户的身份,然后从操作系统级别的用户名(例如系统属性user.name)中获取用户的身份。
YARN应用程序应通过设置此环境变量来传播启动应用程序的用户的用户名。
Map<String, String> env = new HashMap<>();
String userName = UserGroupInformation.getCurrentUser().getUserName();
env.put(UserGroupInformation.HADOOP_USER_NAME, userName);
containerLaunchContext.setEnvironment(env);
请注意,此环境变量在所有通过hadoop库与HDFS通信的应用程序中被选中。 也就是说,如果设置,它是由HBase和在YARN容器的环境中执行的其他应用程序拾取的标识,在该容器中设置了此环境变量。
Oozie集成HADOOP_TOKEN_FILE_LOCATION
Apache Oozie可以通过获取所有相关凭据,将它们保存到本地文件系统中的文件,然后在环境变量HADOOP_TOKEN_FILE_LOCATION中设置此文件的路径,在安全集群中启动应用程序。 这当然是YARN在已启动容器中传递的相同环境变量,类似内容也是如此:带有凭据的字节数组。
但是,在此处,环境变量是在执行YARN客户端的环境中设置的。 此客户端必须使用保存在指定文件中的令牌信息,而不是获取自己的任何令牌。
在令牌文件中加载是自动的:UGI在用户登录期间执行此操作。
然后,客户端负责将相同的凭据传递到AM启动上下文。 这可以通过传递当前凭证来完成。
credentials = new Credentials(
UserGroupInformation.getCurrentUser().getCredentials());
时间线服务器集成
应用程序时间轴服务器可以部署为安全服务 - 在这种情况下,应用程序将需要相关令牌来对其进行身份验证。 如果在安全集群中启用了ATS,则会在YarnClientImpl中自动处理此过程。 同样,AM端的TimelineClient YARN服务类通过ATS的SPNEGO认证的REST API自动管理令牌续订。
如果您需要通过Oozie为YARN应用程序启动准备一组委托令牌,可以通过时间线客户端API完成。
try(TimelineClient timelineClient = TimelineClient.createTimelineClient()) {
timelineClient.init(conf);
timelineClient.start();
Token<TimelineDelegationTokenIdentifier> token =
timelineClient.getDelegationToken(rmprincipal));
credentials.addToken(token.getService(), token);
}
取消令牌
应用程序可能希望在终止其AM时取消它们持有的令牌。 这可确保令牌不再有效。
这不是强制性的,并且由于无法保证YARN应用程序的干净关闭,因此无法保证令牌始终在应用程序终止期间。 但是,它确实减少了被盗令牌的漏洞。
确保长期的YARN服务
所有令牌续订都有一个时间限制,之后令牌将不会续订,导致应用程序停止工作。 这大概是七十二小时到七天。
任何打算长时间运行的YARN服务都必须有更新凭据的策略。
以下是策略:
为AM和容器预安装Keytabs
提供了一个密钥表,供应用程序在每个节点上使用。
这是通过:
- 在每个群集节点的本地文件系统中安装它。
- 在配置选项中提供此路径。
- 应用程序通过UserGroupInformation.loginUserFromKeytab()加载凭据。
密钥表必须位于安全目录路径中,只有服务(和其他可信帐户)才能读取它。 分配成为集群运营团队的责任。
这实际上是所有静态Hadoop应用程序获取其安全凭证的方式。
AM和容器的Keytabs通过YARN分发
- 密钥表上传到HDFS。
- 启动AM时,keytab被列为要本地化到AM容器的资源。
- Application Master配置了keytab的相对路径,并使用
- UserGroupInformation.loginUserFromKeytab()登录。
- 当AM启动容器时,它会将keytab的HDFS路径列为要本地化的资源。
- 它将HDFS委托令牌添加到容器启动上下文中,以便可以对keytab和其他应用程序文件进行本地化。
- 启动的容器必须自己通过UserGroupInformation.loginUserFromKeytab()登录。 UGI处理登录,并安排后台线程定期重新登录用户。
- 令牌创建在Hadoop IPC和REST API中自动处理,容器在整个持续时间内通过kerberos保持登录状态。
这避免了在整个群集中为特定服务安装keytabs的管理任务。
它确实要求客户端访问密钥表,并且在上载到分布式文件系统时,必须通过适当的路径权限/ ACL进行保护。
由于所有容器都可以访问密钥表,因此必须信任在容器中执行的所有代码。 恶意代码(或转义某种形式的沙箱的代码)可以读取密钥表,因此可以访问群集,直到密钥过期或被撤销。
这是Apache Slider(孵化)实施的策略。
AM keytab通过YARN分发; AM为容器重新生成委托令牌。
- 密钥表由客户端上载到HDFS。
- 启动AM时,keytab被列为要本地化到AM容器的资源。
- Application Master配置了keytab的相对路径,并使用UserGroupInformation.loginUserFromKeytab()登录。 UGI代码路径仍将通过$ HADOOP_TOKEN_FILE_LOCATION自动加载文件引用,这是获取AMRM令牌的方式。
- 当AM启动容器时,它会获取该容器所需的所有委托令牌,并将它们添加到容器的容器启动上下文中。
- 启动的容器必须从$ HADOOP_TOKEN_FILE_LOCATION加载委托令牌,并使用它们(包括续订),直到无法再续订为止。
- AM必须实现IPC接口,允许容器请求一组新的委托令牌;此接口本身必须使用身份验证和理想的有线加密。
- 在委托令牌到期之前,容器中运行的进程必须通过IPC通道从Application Master请求新令牌。
- 当容器需要新令牌时,使用密钥表登录的AM会向各种集群服务请求新令牌。
(注意,刷新操作有另一个方向:从AM到容器,再次在AM和容器之间实现任何IPC通道)。 算法的其余部分:AM重新生成的令牌通过IPC传递给容器。
这是Apache Spark 1.5+使用的策略,在容器和AM之间使用基于netty的协议进行令牌更新。
因为只有AM可以直接访问密钥表,所以它的暴露程度较低。 在容器中运行的代码只能访问委托令牌。
但是,这些容器可以从容器启动时传入的令牌访问HDFS,因此可以访问用于启动AM的密钥表副本。 虽然AM可以在启动时删除该密钥表,但这样做会阻止YARN在任何故障后成功重新启动AM。
客户端令牌推送
此策略可能是严格操作团队可接受的唯一策略:在持有Kerberos TGT的帐户上运行的客户端进程与新的委托令牌,令牌协商所有需要的集群服务,然后通过某些RPC接口将其推送到Application Master。
这确实需要定期重新执行客户端进程; 一个cron或Oozie工作可以做到这一点。 AM需要实现IPC API,可以在其上提供更新的令牌。 (请注意,由于Oozie可以自己收集令牌,所以每当执行时,所有更新程序应用程序都需要执行与AM建立IPC连接并传递当前用户的凭据)。
保护YARN应用程序Web UI和REST API
YARN提供了一种直接的方式,为每个YARN应用程序提供SPNEGO认证的Web页面:它在Resource Manager Proxy中实现SPNEGO身份验证。
YARN Web UI在设置其Web UI时应该加载AM代理过滤器; 此过滤器会将来自RM Proxy主机以外的任何主机的所有HTTP请求重定向到RM代理,客户端应用程序/浏览器必须重新发出请求。 客户端将根据RM代理的主体(通常是yarn)进行身份验证,并且一旦通过身份验证,就会对其进行请求。
因此,所有客户端交互都经过SPNEGO身份验证,而YARN应用程序本身不需要任何kerberos主体来进行身份验证。
这种方法的已知缺点是:
- 由于来自代理主机的呼叫未被重定向,因此在这些主机上运行的任何应用程序都可以无限制地访问YARN应用程序。 这就是为什么在安全集群中,代理主机必须在不运行最终用户代码的集群节点上运行(即不运行YARN NodeManagers,因此调度YARN容器,也不支持最终用户登录)。
- 代理和YARN RM Server之间的HTTP请求当前未加密。 即:不支持HTTPS。
保护YARN应用程序REST API
与YARN应用程序的注册Web UI在同一端口上运行的YARN REST API将通过RM代理中的SPNEGO身份验证自动进行身份验证。
在不同端口上启动的任何REST端点(以及同样地,任何Web UI)都不支持SPNEGO身份验证,除非在YARN应用程序本身中实现。
YARN应用程序清单
以下是YARN应用程序必须要在YARN群集中成功启动的核心操作清单。
Client
客户端通过UserGroupInformation.isSecurityEnabled()检查是否启用了安全性
在安全集群中:
如果未设置HADOOP_TOKEN_FILE_LOCATION,则客户端将获取本地文件系统的委托令牌,并将RM主体设置为续订者。
如果未设置HADOOP_TOKEN_FILE_LOCATION,则客户端将获取要在YARN应用程序中使用的所有其他服务的委派令牌。
如果设置了HADOOP_TOKEN_FILE_LOCATION,则客户端使用当前用户的凭据作为要添加到容器启动上下文的所有令牌的源。
客户端在AM ContainerLaunchContext.setTokens()上设置所有令牌。
建议:如果在客户端环境中设置,则客户端在AM的Container启动上下文中设置环境变量HADOOP_JAAS_DEBUG = true。
在不安全的集群中:
将本地用户名传播到YARN AM,因此通过HADOOP_USER_NAME环境变量传输HDFS标识。
App Master
在安全集群中,AM从HADOOP_TOKEN_FILE_LOCATION环境变量中检索安全性令牌(由UGI自动完成)。
过滤令牌集的副本以删除AM / RM令牌和任何时间轴令牌。
线程或执行程序开始定期更新线程。
推荐:AM在应用程序完成时取消令牌。
Container Launch by AM(通过AM启动容器)
传递给容器的标记通过ContainerLaunchContext.setTokens()传递。
在不安全的集群中,传播HADOOP_USER_NAME环境变量。
建议:如果在AM的环境中设置了AM,则在Container启动上下文中设置环境变量HADOOP_JAAS_DEBUG = true。
Launched Containers
调用UserGroupInformation.isSecurityEnabled()以触发安全性设置。
线程或执行程序开始定期更新线程。
YARN service
应用程序开发人员已选择并实施了令牌续订策略:共享密钥表,AM密钥表或客户端令牌刷新。
在安全集群中,密钥表已经处于HDFS(并且已检查),或者它位于客户端的本地FS中,在这种情况下,必须将其上载并添加到要本地化的资源列表中。
如果存储在HDFS中,则应检查keytab权限。如果keytab可由当前用户以外的主体读取,则发出警告,并考虑实际启动失败(类似于正常的ssh应用程序)。
客户端获取HDFS委托令牌并附加到AM容器启动上下文,
AM通过loginUserFromKeytab()以keytab身份登录。
(AM从HADOOP_TOKEN_FILE_LOCATION环境变量中提取AM / RM令牌)。
[]对于已启动的容器,要么传播密钥表,要么AM将所有必需的委托令牌附加/附加到容器启动上下文以及NM所需的HDFS委派令牌。
Testing YARN applications in a secure cluster.
可以直接确信YARN应用程序在安全集群中工作。这样做的过程是:在安全集群上进行测试。
甚至可以在启用安全性的情况下设置单个VM群集。如果这样做,我们建议使用SPNEGO认证的Web UI(以及RM代理)以及IPC线加密来最大限度地提高安全性。将kerberos令牌到期时间设置为不到一小时就会发现早期的kerberos到期问题 - 所以也建议使用。
应用程序在安全集群中启动。
启动应用程序作为用户提交作业运行(提示:AM中的log user.name系统属性)。
在安全群集中验证的Web浏览器交互。
REST客户端交互(GET操作)测试。
应用程序在Kerberos令牌到期后继续运行。
如果用户缺少Kerberos凭据,则不会启动应用程序。
如果应用程序支持时间轴服务器,请验证它是否在安全群集中发布事件。
如果应用程序与其他应用程序(如HBase或Hive)集成,请验证交互是否在安全群集中有效。
如果应用程序与远程HDFS集群通信,请验证它是否可以在安全集群中执行此操作(即,客户端在启动时为此提取了任何委托令牌)
Important
如果您不在安全的Hadoop集群中测试YARN应用程序,它将无法运行。
如果没有这些测试:您的用户将会发现您的应用程序无法在安全集群中运行。
在考虑将多少开发工作投入到Kerberos支持时,请记住这一点。