微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

java – 我应该在hadoop上的每个动作之前调用ugi.checkTGTAndReloginFromKeytab()?

在我的服务器应用程序中,我正在从我的 java应用程序连接到Kerberos安全的Hadoop集群.我正在使用像HDFS文件系统,Oozie,Hive等各种组件.在应用程序启动时,我打电话
UserGroupinformation.loginUserFromKeytabAndReturnUGI( ... );

这返回我的UsereGroupinformation实例,我保留它的应用程序的生命周期.在做特权行动时,我发起他们ugi.doAs(动作).

这很好,但是我想知道如何和何时应该在UserGroupinformation中续订kerberos机票?我发现一个方法UserGroupinformation.checkTGTAndReloginFromKeytab(),似乎在接近到期时进行更新.我也发现这个方法正在被诸如WebHdfsFileSystem之类的各种Hadoop工具所调用.

现在如果我想要我的服务器应用程序(可能运行几个月甚至几年)永远不会体验票证到期什么是最好的方法?提出具体问题:

>我可以依靠他们称之为checkTGTAndReloginFromKeytab的各种Hadoop客户端吗?
我应该在我的代码调用checkTGTAndReloginFromKeytab吗?
>如果是这样,请在每次调用ugi.doAs(…)之前,或者设置一个定时器并定期调用它(多久)?

解决方法

Hadoop提交者在这里!这是一个很好的问题.

不幸的是,如果没有深入了解应用程序的特定使用模式,很难给出一个明确的答案.相反,我可以提供一般的指导方针,并描述何时Hadoop会为您自动处理更新或重新登录密码匙,何时不会.

Hadoop生态系统中Kerberos认证的主要用例是Hadoop的RPC框架,它使用SASL进行认证. Hadoop生态系统中的大多数守护进程通过在进程启动时对UserGroupinformation#loginUserFromKeytab执行一次一次性调用来处理此问题.其示例包括必须验证其对NameNode的RPC调用的HDFS Datanode以及必须验证其对ResourceManager的调用的YARN NodeManager.如何像Datanode这样的守护进程可以在进程启动时进行一次性登录,然后继续运行几个月,很久以前的典型票证过期时间?

由于这是一个常见的用例,Hadoop在RPC客户端层内直接实现了自动重新登录机制.该代码在RPC Client#handleSaslConnectionFailure方法中可见:

// try re-login
          if (UserGroupinformation.isLoginKeytabBased()) {
            UserGroupinformation.getLoginUser().reloginFromKeytab();
          } else if (UserGroupinformation.isLoginTicketBased()) {
            UserGroupinformation.getLoginUser().reloginFromTicketCache();
          }

您可以将此视为重新登录的“懒惰评估”.它仅在尝试的RPC连接上重新执行登录以响应身份验证失败.

知道这一点,我们可以给出部分答案.如果您的应用程序的使用模式是从密钥表登录,然后执行典型的Hadoop RPC调用,则可能不需要滚动您自己的重新登录代码. RPC客户端层将为您做. “典型的Hadoop RPC”意味着与Hadoop交互的绝大多数Java API,包括HDFS FileSystem API,YarnClient和MapReduce Job提交.

然而,一些应用程序使用模式根本不涉及Hadoop RPC.一个例子是与Hadoop的REST API(例如WebHDFSYARN REST APIs)完全交互的应用程序.在这种情况下,认证模型通过SPNEGO使用Kerberos,如Hadoop HTTP Authentication文档中所述.

知道这一点,我们可以添加更多的答案.如果您的应用程序的使用模式根本不使用Hadoop RPC,而是单独使用REST API,那么您必须滚动您自己的重新登录逻辑.这正是070​​07的原因,就像你注意到的那样. WebHdfsFileSystem选择在每个操作之前进行通话.这是一个很好的策略,因为UserGroupInformation#checkTGTAndReloginFromkeytab only renews the ticket if it’s “close” to expiration.否则,这个呼叫是无效的.

作为最终用例,让我们考虑一个交互过程,而不是从keytab登录,而是要求用户在启动应用程序之前在外部运行kinit.在绝大多数情况下,这些将是短期运行的应用程序,例如Hadoop CLI命令.然而,在某些情况下,这些可以是更长时间运行的过程.为了支持更长时间运行的进程,Hadoop启动后台线程以将Kerberos故障单“关闭”更新到到期.这个逻辑在UserGroupInformation#spawnAutoRenewalThreadForUserCreds是可见的.与RPC层提供的自动重新登录逻辑相比,这里有一个重要的区别.在这种情况下,Hadoop只能够更新机票并延长其使用寿命.门票具有最大的可再生生命周期,如Kerberos基础设施所规定.之后,票不再可用了.在这种情况下重新登录实际上是不可能的,因为这将意味着重新提示用户输入密码,并且可能会离开终端.这意味着如果进程在票证到期之后持续运行,那么它将无法再进行身份验证.

再次,我们可以使用这些信息来告知我们的整体答案.如果您依靠用户在启动应用程序之前通过kinit进行交互式登录,并且如果您确信应用程序的运行时间不会超过Kerberos机票的最长可再生生命周期,那么您可以依靠Hadoop内部部件来为您定期更新.

如果您正在使用基于键盘登录,而您只是不确定应用程序的使用模式是否可以依赖于Hadoop RPC层的自动重新登录,那么保守的方法就是滚动自己的. @SamsonScharfrichter在这里给出了一个很好的答案,就是滚动自己的.

HBase Kerberos connection renewal strategy

最后,我应该添加一个关于API稳定性的注释. Apache Hadoop Compatibility指南详细讨论了Hadoop开发社区对向后兼容性的承诺. UserGroupinformation的界面注释为“有限私有”和“演进”.在技​​术上,这意味着UserGroupinformation的API不被视为公共的,它可能会以向后不兼容的方式发展.实际上,有很多代码已经取决于UserGroupinformation的接口,所以我们根本不可能做出突破性的改变.当然,在当前的2.x发行版本中,我不会担心方法签名从你下面改变而破坏你的代码.

现在我们拥有所有这些背景信息,让我们回顾一下你的具体问题.

Can I rely on the varIoUs Hadoop clients they call checkTGTAndReloginFromKeytab whenever it’s needed?

如果您的应用程序的使用模式是调用Hadoop客户端,这反过来又利用Hadoop的RPC框架,您可以依赖这一点.如果您的应用程序的使用模式仅调用Hadoop REST API,则无法依赖此.

Should I call ever checkTGTAndReloginFromKeytab myself in my code?

如果应用程序的使用模式仅用于调用Hadoop REST API而不是Hadoop RPC调用,则可能需要执行此操作.您不会在Hadoop的RPC客户端中实现自动重新登录的好处.

If so should I do that before every single call to ugi.doAs(…) or rather setup a timer and call it periodically (how often)?

在需要验证的每个操作之前调用UserGroupinformation#checkTGTAndReloginFromKeytab是很好的.如果票不接近到期,那么该方法将是无效的.如果您怀疑Kerberos基础架构不稳定,并且您不希望客户端操作支付重新登录的延迟成本,那么这将是在单独的后台线程中执行此操作的一个原因.只要确保在票的实际到期时间之前留一点点.您可以借用UserGroupinformation内的逻辑来确定票据是否“关闭”到期.实际上,我从来没有亲眼看到重新登录的延迟是有问题的.

原文地址:https://www.jb51.cc/java/125484.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐