首页 > 编程语言 >0578-5.15.1-Kerberos环境下Java应用程序认证超时异常分析

0578-5.15.1-Kerberos环境下Java应用程序认证超时异常分析

时间:2022-10-04 12:02:23浏览次数:88  
标签:UGI Java Kerberos 应用程序 认证 0578 lifetime ticket

作者:谢敏灵/辉少


1

文档编写目的


在Kerberos环境中,我们的应用程序通过Java代码来提交任务需要先进行Kerberos凭证的初始化然后进行应用程序的提交,本文档主要讲述Java应用程序长时间运行作业Kerberos不自动重新认证问题


  • 测试环境

1.CM和CDH版本为5.15.1

2.操作系统版本为RedHat7.2

3.集群已启用Kerberos


2

问题描述


在使用JDK 8时,在Kerberos环境下应用程序在执行的过程中报以下错误:

Failed on local exception: java.io.IOException: javax.security.sasl.SaslException: GSS initiate failed [Caused by GSSException: No valid credentials provided (Mechanism level: Failed to find any Kerberos tgt)]


3

问题分析


在Kerberos环境下长时间运行的作业会出现认证失败问题,认证失败是由于Ticket过期导致。Ticket过期是由ticket_lifetime和renew_lifetime两个参数控制,具体分析如下:

先了解下krb5.conf里ticket_lifetime和renew_lifetime参数:


ticket_lifetime = 24h
renew_lifetime = 7d


注:这里其实还跟kdc.conf里的ticket_lifetime和renew_lifetime相关,本文不做讨论,假设你配置都是一致的。


每一个Kerberos的ticket,包括TGT,都有一个ticket_lifetime(默认:1天);Ticket可以被延续,但最多只能延续到renew_lifetime(默认:7天),超过7天后无法再延续,此时ticket失效,只能重新login。


如果你的应用程序需要运行很长时间或者需要持续不断地一直运行,就会有一个问题,即:

在应用程序启动时进行Kerberos认证登录后,是否还需要定时renew ticket或在ticket期满失效后使用keytab重新login?例如,是否需要在应用程序代码里,在每个UGI.doAS(...)前调用UGI.checkTGTAndReloginFromKeytab或者使用一个Timer周期性地调用UGI.checkTGTAndReloginFromKeytab?


关于这个问题,首先需要了解在Hadoop系统里是如何进行Kerberos认证的:

Hadoop Kerberos认证的主要使用场景是Hadoop RPC框架(使用SASL进行kerberos认证)。大部分Hadoop daemon进程在启动时会调用UGI(org.apache.hadoop.security.UserGroupInformation),UGI.loginUserFromKeytab做kerberos认证并获取ticket,并在后续每一次RPC调用时使用该ticket认证。比如,DataNode必须认证它对NameNode的RPC调用,NodeManager也必须认证它对ResourceManager的RPC调用。那么,这些daemon进程为什么能在启动后长时间持续运行而不会出现kerberos ticket错误呢(甚至已经超过了renew_lifetime)?这是因为Hadoop在RPC Client层实现了一种自动relogin机制。在Client.handleSaslConnectionFailure(org.apache.hadoop.ipc.Client)方法里有如下代码:


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


0578-5.15.1-Kerberos环境下Java应用程序认证超时异常分析_应用程序


上述代码说明在使用RPC连接时,如果因为ticket失效造成认证失败,会自动relogin。

基于以上认识,可以得出以下结论:


1.如果应用程序的使用模式是从keytab登录后执行典型的Hadoop RPC Java调用(如调用HDFS FileSystem API),那么是不需要在应用层增加renew ticket或relogin代码的,因为RPC Client层已经帮你实现了。


2.如果应用程序的使用模式是不使用Hadoop RPC,而是调用HDFS REST API或YARN REST API(使用SPNEGO进行kerberos认证),那么需要在应用程序里增加relogin代码。具体实现方式是:

Java方式:主Java程序使用keytab调用UGI.loginUserFromKeytab登录,然后在每个UGI.doAS前调用UGI.checkTGTAndReloginFromKeytab方法,或者另启动一个线程周期性调用该方法。


0578-5.15.1-Kerberos环境下Java应用程序认证超时异常分析_hadoop_02


Shell方式:主程序使用kinit登录,然后启动另一个子进程周期性的调用kinit -R去renew ticket或者调用kinit -kt去relogin。


需要注意的是当使用JDK 8时,UGI的relogin存在一个bug,即HADOOP-10786。该bug是因为JDK 8的Krb5LoginModule有些小改动,这些改动会造成UGI的relogin代码认为之前的登录并不是基于keytab登录的。所以,UGI.reloginFromKeytab和UGI.checkTGTAndReloginFromKeytab方法实际上什么都没有做,并没有执行relogin。所以,此时应用程序仍然会报以下错误:


Failed on local exception: java.io.IOException: javax.security.sasl.SaslException: GSS initiate failed [Caused by GSSException: No valid credentials provided (Mechanism level: Failed to find any Kerberos tgt)]


4

解决办法


对于使用JDK 8应用程序不能正常reloginFromKeytab的 bug,workaround是:


1. 使用JDK 7而不是JDK 8,或者

2. 确保hadoop-common包含了HADOOP-10786补丁。


建议使用CDH5.13.0或者以上版本的包,这些包已经包括了该补丁。如果仍然在IDE开发环境出现了以上问题,可以检查一下IDE依赖的hadoop-common包的版本是否有问题。

参考文档:

​https://issues.apache.org/jira/browse/HADOOP-10786​


标签:UGI,Java,Kerberos,应用程序,认证,0578,lifetime,ticket
From: https://blog.51cto.com/u_14049791/5731176

相关文章

  • 几个常见的javascript手写题,你能写出来几道
    实现new过程:要点:函数第一个参数是构造函数实例的__proto__指向构造函数的原型属性prototype函数剩余参数要挂载到一个实例对象上构造函数有返回值时,就返回这个返回......
  • JAVA-DDD项目结构
    通过一套合理的代码结构、框架和约束,来降低DDD的实践门槛,提升代码质量、可测试性、安全性、健壮性。废话少说,直接上最终架构图:项目架构DDD的架构能够有效的解决传统......
  • 0469-如何使用DBeaver访问Kerberos环境下的Impala
    温馨提示:如果使用电脑查看图片不清晰,可以使用手机打开文章单击文中的图片放大查看高清原图。Fayson的github:​​https://github.com/fayson/cdhproject​​提示:代码块部分可......
  • 0468-如何使用DBeaver访问Kerberos环境下的Hive
    温馨提示:如果使用电脑查看图片不清晰,可以使用手机打开文章单击文中的图片放大查看高清原图。Fayson的github:​​https://github.com/fayson/cdhproject​​提示:代码块部分可......
  • 0887-7.1.4-如何在CDP中为Kafka启用Kerberos认证及使用
    1.文档编写目的在CDP集群中启用了Kerberos认证,那么Kafka集群能否与Kerberos认证服务集成呢?本文主要讲述如何通过ClouderaManager为Kafka集群启用Kerberos认证及客户端配置......
  • Java并发编程 | 从进程、线程到并发问题实例解决
    计划写几篇文章讲述下Java并发编程,帮助一些初学者成体系的理解并发编程并实际使用,而不只是碎片化的了解一些Synchronized、ReentrantLock等技术点。在讲述的过程中,也想融入......
  • Java SE 宋红康 days04-高级篇-反射
    1.需要掌握的点:①理解Class类并获取Class实例;②创建运行时类的对象;③调用运行时类的指定结构;2.反射(Reflection)正常方式:引入需要的“包类”......
  • 构建Java高并发高性能分布式框架,高可维护性Java应用系统
    构建Java高并发高性能分布式框架,高可维护性Java应用系统微服务架构模式(MicroserviceArchitectPattern)。近两年在服务的疯狂增长与云计算技术的进步,让微服务架构受到重......
  • 桥接模式【Java设计模式】
    桥接模式【Java设计模式】​​前言​​​​推荐​​​​桥接模式​​​​介绍​​​​实现​​​​最后​​前言2022/9/2313:34路漫漫其修远兮,吾将上下而求索本文是根据袁......
  • Java10/04
    数组1.数组概述数组的定义:数组是相同类型数据的有序集合数组描述的是相同类型的若干个数控,按照一定的先后次序排列组合而成其中,每一个数据称为一个数组元素,每个数......