彻底解决 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-10786

但其他发行版,例如 hadoop-common-2.6.0-CDH5.12.1 则没有此bug。

判定该bug的依据是

  1. 使用了java 8
  2. 查看项目内引入的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;
  }

修复方法

  1. 没必要写代码添加自动重连,UGI本身就有。
  2. UGI这个类来源于传递依赖,直接依赖,或者shade依赖。

解决有问题的jar依赖即可。

posted @ 2019-01-03 21:21  一杯半盏  阅读(16476)  评论(2编辑  收藏  举报