彻底解决 Mechanism level: Failed to find any Kerberos tgt
错误描述
Secure Client Cannot Connect ([Caused by GSSException: No valid credentials provided(Mechanism level: Failed to find any Kerberos tgt)])
症状
- 如果不是klist keytab有效期的问题,却还报这个错
- 如果是常驻型的服务,例如 nohup ,tomcat等等服务,报错具备某种规律,比如每天12点,或者某个时间段之后。
- Flink应用程序例如读写Hbase时Kerberos无法自动重连,JDK8
解决方案
屡试不爽
https://hbase.apache.org/book.html#trouble.client.security.rpc
https://docs.oracle.com/javase/8/docs/technotes/guides/security/jgss/tutorials/Troubleshooting.html
还有一个问题需要排除,检查服务所用JDK的这个文件。
Java Unlimited Strength Crypto Policy
针对jdk1.8.44以上版本,请将jre/lib/security/java.security文件中的
将 #crypto.policy=unlimited
改为 crypto.policy=unlimited
其他不变,也不需要其他权限jar
针对jdk1.8.44以下版本,请将jre/lib/security/ 下 的 local_policy.jar和US_export_policy.jar替换为官方网站提供了JCE无限制权限策略文件
有关Hadoop组件bug导致的问题
例如 hadoop-common-2.6.0 就有一个bug:
但其他发行版,例如 hadoop-common-2.6.0-CDH5.12.1 则没有此bug。
判定该bug的依据是
- 使用了java 8
- 查看项目内引入的UGI类构造函数
依据HADOOP-10786的Patch,
KeyTab.class
为正确版本,KerberosKey.class
为故障的版本
private UserGroupInformation(Subject subject, final boolean isLoginExternal) {
this.subject = subject;
this.user = subject.getPrincipals(User.class).iterator().next();
//- this.isKeytab = !subject.getPrivateCredentials(KerberosKey.class).isEmpty();
+ this.isKeytab = !subject.getPrivateCredentials(KeyTab.class).isEmpty();
this.isKrbTkt = !subject.getPrivateCredentials(KerberosTicket.class).isEmpty();
this.isLoginExternal = isLoginExternal;
}
修复方法
- 没必要写代码添加自动重连,UGI本身就有。
- UGI这个类来源于传递依赖,直接依赖,或者shade依赖。
解决有问题的jar依赖即可。