任何编写YARN应用程序的人都需要了解该过程,才能编写寿命短的应用程序或寿命长的服务。他们还需要在开发的早期阶段就对安全集群进行测试,以便编写出切实可行的代码。
YARN资源管理器(RM)和节点管理器(NM)协作以执行具有用户身份和该用户访问权限的用户应用程序。
(活动的)资源管理器:
在群集中查找空间,以部署应用程序的核心应用程序主(AM)。
请求该节点上的NM分配一个容器并在其中启动AM。
与AM进行通信,以便AM可以请求新容器并操纵/释放当前容器,并提供有关已分配和正在运行的容器的通知。
节点管理器:
本地化资源:从HDFS或其他文件系统下载到本地目录。这是使用附加到容器启动上下文的委托令牌完成的。(对于非HDFS资源,请使用其他凭据,例如群集配置文件中的对象存储登录详细信息)
以用户身份启动应用程序。
监视应用程序并将故障报告给RM。
要在集群中执行代码,YARN应用程序必须:
有一个客户端应用程序,该应用程序设置了ApplicationSubmissionContext,详细说明了要启动的内容。这包括:
拥有一个应用程序主程序,该应用程序主程序在启动时会向YARN RM注册并监听事件。任何希望在其他容器中执行工作的AM必须在RM之外请求它们,并在分配后创建一个ContainerLaunchContext,其中包含要执行的命令,要执行该命令的环境,要本地化的二进制文件以及所有相关的安全凭证。
即使使用NM处理本地化过程,AM本身也必须能够检索在启动时提供的安全凭证,以便它本身可以与HDFS和任何其他服务一起使用,并将部分或全部这些凭证向下传递给已启动容器。
必须从以身份验证的用户身份执行的程序中获取YARN应用程序所需的委托令牌。对于YARN应用程序,这意味着用户将启动该应用程序。它是YARN应用程序的客户端部分,它必须执行以下操作:
需要哪些令牌?通常,至少有一个令牌可以访问HDFS。
应用程序必须从与之交互的每个文件系统(包括集群的主FS)中请求委托令牌。FileSystem.addDelegationTokens(更新器,凭证)可用于收集这些;在那些不发行令牌的文件系统(包括非kerberized HDFS群集)上,此操作是禁止操作的。
与其他服务(例如Apache HBase和Apache Hive)交谈的应用程序必须使用这些服务的库来从这些服务中请求令牌,以获取委托令牌。可以将所有令牌添加到同一组凭据中,然后保存到字节缓冲区中以进行提交。
应用程序时间轴服务器还需要委托令牌。这是在AM启动时自动处理的。
启动Application Master并调用任何触发用户登录的UGI / Hadoop操作时,UGI类将自动加载保存在由环境变量HADOOP_TOKEN_FILE_LOCATION命名的文件中的所有令牌。
即使在不安全的群集和安全的群集上,也发生这种情况,即使在应用程序使用了密钥表的情况下,在安全的群集上也是如此。为什么?因为始终以这种方式提供使用YARN RM验证应用程序所需的AM / RM令牌。
这意味着您在安全群集和不安全群集上的工作流程相对类似。
Suring AM启动,登录到Kerberos。调用UserGroupInformation.isSecurityEnabled()将触发此操作。
通过调用UserGroupInformation.getCurrentUser()。getCredentials()枚举当前用户的凭据。
过滤掉AMRM令牌,从而得到一组新的凭据。在不安全的群集中,凭据列表现在将为空;在安全的群集中,它们将包含
将所有要启动的容器的凭据设置为此凭据列表(可能为空)。
如果过滤的要更新的令牌列表为非空,请启动线程以更新它们。
即使应用程序定期更新令牌,如果AM失败并重新启动,它也会从该原始ApplicationSubmissionContext重新启动。那里的令牌可能已经过期,因此即使在颁发凭据以与其他服务对话之前,本地化也可能失败。
该问题如何解决?如果需要,YARN资源管理器将为节点管理器获取一个新令牌。
更确切地说
这是长期服务的主要问题(请参见下文)。
非托管应用程序主服务器不会在RM和NM设置的容器中启动,因此无法在启动时自动获取AM / RM令牌。所述YarnClient.getAMRMToken() API允许未受管AM请求的AM / RM令牌。有关详细信息,请咨询UnmanagedAMLauncher。
在不安全的群集中,应用程序将以节点管理器帐户的身份运行,通常是诸如yarn或mapred之类的东西。默认情况下,应用程序将以该用户身份访问HDFS,具有不同的主目录,并具有在审核日志和文件系统所有者属性中标识的其他用户。
可以通过让客户端标识应在其下运行应用程序的HDFS / Hadoop用户的标识来避免这种情况。这不会影响操作系统级别的用户或应用程序对本地计算机的访问权限。
禁用Kerberos后,Hadoop会首先从环境变量HADOOP_USER_NAME中获取用户的身份,然后从操作系统级用户名(例如,系统属性user.name)中获取用户的身份。
YARN应用程序应通过设置此环境变量来传播启动应用程序的用户的用户名。
Map <String,String> env =新的HashMap <>(); 字符串userName = UserGroupInformation.getCurrentUser()。getUserName(); env.put(UserGroupInformation.HADOOP_USER_NAME,用户名); containerLaunchContext.setEnvironment(env);
请注意,在通过hadoop库与HDFS通讯的所有应用程序中都会拾取此环境变量。也就是说,如果已设置,则为HBase和在设置了该环境变量的YARN容器的环境中执行的其他应用程序获取的标识。
Apache Oozie可以通过获取所有相关凭据,将它们保存到本地文件系统中的文件中,然后在环境变量HADOOP_TOKEN_FILE_LOCATION中设置该文件的路径,来在安全集群中启动应用程序。当然,这与YARN在启动的容器中传递的环境变量相同,内容类似:带有凭据的字节数组。
但是,这里的环境变量是在执行YARN客户端的环境中设置的。该客户端必须使用保存在命名文件中的令牌信息,而不是获取其自身的任何令牌。
令牌文件中的加载是自动的:UGI在用户登录期间进行加载。
然后,客户端负责将相同的凭据传递到AM启动上下文中。这可以简单地通过传递当前凭据来完成。
凭据=新凭据( UserGroupInformation.getCurrentUser()。getCredentials());
可以将Application Timeline Server部署为安全服务-在这种情况下,应用程序将需要相关令牌来对其进行身份验证。如果在安全群集中启用了ATS,则会在YarnClientImpl中自动处理此过程。同样,AM端TimelineClient YARN服务类通过ATS的SPNEGO认证的REST API自动管理令牌更新。
如果您需要为通过Oozie启动YARN应用程序准备一组委托令牌,则可以通过时间轴客户端API来完成。
试试(TimelineClient timelineClient = TimelineClient.createTimelineClient()){ timelineClient.init(conf); timelineClient.start(); 令牌<TimelineDelegationTokenIdentifier>令牌= timelineClient.getDelegationToken(rmprincipal)); certificate.addToken(token.getService(),令牌); }
所有令牌续约都有时间限制,此后令牌将不会续约,从而导致应用程序停止工作。这大约在72小时到7天之间。
任何打算长时间运行的YARN服务都必须具有更新证书的策略。
以下是策略:
提供了一个密钥表,供应用程序在每个节点上使用。
这是通过以下方式完成的:
密钥表必须位于安全目录路径中,只有服务(和其他受信任帐户)才能在其中读取密钥表。分发成为集群运营团队的责任。
这是所有静态Hadoop应用程序有效获得其安全凭证的方式。
密钥表将上传到HDFS。
启动AM时,密钥表被列为本地化到AM容器的资源。
Application Master配置有keytab的相对路径,并使用UserGroupInformation.loginUserFromKeytab()登录。
AM启动容器时,它将列出密钥表的HDFS路径作为要本地化的资源。
它将HDFS委派令牌添加到容器启动上下文中,以便可以对keytab和其他应用程序文件进行本地化。
启动的容器必须自己通过UserGroupInformation.loginUserFromKeytab()登录。UGI处理登录,并安排后台线程定期重新登录用户。
令牌创建在Hadoop IPC和REST API中自动处理,容器在整个使用期间都通过kerberos保持登录状态。
这避免了为整个集群中的特定服务安装密钥表的管理任务。
它确实要求客户端有权访问密钥表,并且在将密钥表上传到分布式文件系统时,必须通过适当的路径权限/ ACL对其进行保护。
由于所有容器都可以访问密钥表,因此必须信任容器中执行的所有代码。恶意代码(或逃避某种形式的沙箱的代码)可以读取密钥表,因此可以访问群集,直到密钥过期或被撤消为止。
这是由Apache Slider(孵化)实现的策略。
客户端将密钥表上传到HDFS。
启动AM时,密钥表被列为本地化到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。
YARN提供了一种向每个YARN应用程序提供SPNEGO身份验证的网页的简单方法:它在资源管理器代理中实现SPNEGO身份验证。
设置YARN Web UI时应加载AM代理过滤器。此过滤器会将来自除RM代理主机之外的任何主机的所有HTTP请求重定向到一个RM代理,客户端应用/浏览器必须向该RM代理重新发出请求。客户端将根据RM代理的主体(通常是yarn)进行身份验证,并在身份验证后将其请求存储起来。
结果,所有客户端交互都经过SPNEGO身份验证,而YARN应用程序本身不需要任何kerberos委托人即可对客户端进行身份验证。
这种方法的已知缺点是:
由于来自代理主机的呼叫不会被重定向,因此在这些主机上运行的任何应用程序都可以不受限制地访问YARN应用程序。这就是为什么在安全群集中,代理主机必须在不运行最终用户代码的群集节点上运行(即,不运行YARN NodeManager,从而调度YARN容器,也不支持最终用户登录)。
代理和YARN RM服务器之间的HTTP请求当前未加密。即:不支持HTTPS。
与YARN应用程序的注册Web UI在相同端口上运行的YARN REST API将通过RM代理中的SPNEGO身份验证自动进行身份验证。
除非在YARN应用程序本身中实现,否则在其他端口上启动的任何REST端点(以及任何Web UI)均不支持SPNEGO身份验证。
这是YARN应用程序必须执行的核心操作清单,才能成功在YARN群集中启动。
[]客户端检查是否通过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身份传播。
[]在安全集群中,AM从HADOOP_TOKEN_FILE_LOCATION环境变量中检索安全令牌(由UGI自动完成)。
[]过滤令牌集副本,以删除AM / RM令牌和任何时间轴令牌。
[]线程或执行程序开始定期更新线程。
[]推荐:应用程序完成后,AM会取消令牌。
[]要传递给容器的令牌是通过ContainerLaunchContext.setTokens()传递的。
[]在不安全的群集中,传播HADOOP_USER_NAME环境变量。
[]推荐:如果在AM的环境中设置,则AM在Container启动上下文中设置环境变量HADOOP_JAAS_DEBUG = true。
[]应用程序开发人员选择并实施了令牌更新策略:共享密钥表,AM密钥表或客户端令牌刷新。
[]在安全群集中,密钥表要么已经在HDFS中(并已检查),要么已在客户端的本地FS中,在这种情况下,必须将其上载并添加到要本地化的资源列表中。
[]如果存储在HDFS中,则应检查keytab权限。如果keytab可由当前用户以外的其他主体读取,则发出警告并考虑实际启动失败(类似于普通的ssh应用程序)。
[]客户端获取HDFS委托令牌,并将其附加到AM容器启动上下文中,
[] AM通过loginUserFromKeytab()在keytab中作为主体登录。
[](AM从HADOOP_TOKEN_FILE_LOCATION环境变量中提取AM / RM令牌)。
[]对于启动的容器,可以传播密钥表,或者AM将所有必需的委托令牌与NM所需的HDFS委托令牌一起获取/附加到Container Launch上下文。
确信YARN应用程序可在安全群集中运行很简单。这样做的过程是:在安全群集上进行测试。
即使启用了安全性,也可以设置单个VM群集。如果这样做,我们建议使用SPNEGO认证的Web UI(以及RM代理)以及IPC有线加密,将安全性提高到最严格的水平。将kerberos令牌过期设置为一小时以下会发现kerberos过期问题,因此也建议这样做。
[]在安全集群中启动了应用程序。
[]启动的应用程序作为用户提交作业运行(提示:在AM中记录user.name系统属性)。
[] Web浏览器交互已在安全集群中验证。
[] REST客户端交互(GET操作)已测试。
[]应用程序在Kerberos令牌到期后继续运行。
[]如果用户缺少Kerberos凭据,则应用程序不会启动。
[]如果应用程序支持时间轴服务器,请验证它是否在安全集群中发布事件。
[]如果应用程序与其他应用程序(例如HBase或Hive)集成,请验证交互是否在安全群集中进行。
[]如果应用程序与远程HDFS群集进行通信,请验证它是否可以在安全群集中进行通信(即,客户端在启动时为此提取了任何委派令牌)