如何在 HBase 中更新过期的 Kerberos 票证?
How to renew expiring Kerberos ticket in HBase?
我有一个小型 spring 服务,它提供基本功能,例如来自 hbase table 的 put/delete/get。一切似乎都正常,但有一个问题。启动我的 tomcat 服务器 10 小时后,我的 kerberos 票证到期,所以我应该更新它。我尝试将 java api 用于 hbase,并在连接到 hbase 的每个方法的代码中添加了这一行:
UserGroupInformation.getLoginUser().checkTGTAndReloginFromKeytab();
我也试过:
UserGroupInformation.getLoginUser().reloginFromKeytab()
和:
SecurityUtil.login(configuration, keytabFilePath, kerberosUser)
但这没有用,我在服务器重启 10 小时后收到此异常:
javax.security.sasl.SaslException: GSS initiate failed [Caused by GSSException: No valid credentials provided (Mechanism level: Failed to find any Kerberos tgt)]
at com.sun.security.sasl.gsskerb.GssKrb5Client.evaluateChallenge(Unknown Source)
at org.apache.hadoop.hbase.security.HBaseSaslRpcClient.saslConnect(HBaseSaslRpcClient.java:179)
at org.apache.hadoop.hbase.ipc.RpcClientImpl$Connection.setupSaslConnection(RpcClientImpl.java:617)
at org.apache.hadoop.hbase.ipc.RpcClientImpl$Connection.access0(RpcClientImpl.java:162)
at org.apache.hadoop.hbase.ipc.RpcClientImpl$Connection.run(RpcClientImpl.java:743)
at org.apache.hadoop.hbase.ipc.RpcClientImpl$Connection.run(RpcClientImpl.java:740)
at java.security.AccessController.doPrivileged(Native Method)
at javax.security.auth.Subject.doAs(Unknown Source)
at org.apache.hadoop.security.UserGroupInformation.doAs(UserGroupInformation.java:1614)
at org.apache.hadoop.hbase.ipc.RpcClientImpl$Connection.setupIOstreams(RpcClientImpl.java:740)
at org.apache.hadoop.hbase.ipc.RpcClientImpl$Connection.writeRequest(RpcClientImpl.java:906)
at org.apache.hadoop.hbase.ipc.RpcClientImpl$Connection.tracedWriteRequest(RpcClientImpl.java:873)
at org.apache.hadoop.hbase.ipc.RpcClientImpl.call(RpcClientImpl.java:1241)
at org.apache.hadoop.hbase.ipc.AbstractRpcClient.callBlockingMethod(AbstractRpcClient.java:227)
at org.apache.hadoop.hbase.ipc.AbstractRpcClient$BlockingRpcChannelImplementation.callBlockingMethod(AbstractRpcClient.java:336)
at org.apache.hadoop.hbase.protobuf.generated.ClientProtos$ClientService$BlockingStub.multi(ClientProtos.java:34142)
at org.apache.hadoop.hbase.client.MultiServerCallable.call(MultiServerCallable.java:128)
at org.apache.hadoop.hbase.client.MultiServerCallable.call(MultiServerCallable.java:53)
at org.apache.hadoop.hbase.client.RpcRetryingCaller.callWithoutRetries(RpcRetryingCaller.java:210)
at org.apache.hadoop.hbase.client.AsyncProcess$AsyncRequestFutureImpl$SingleServerRequestRunnable.run(AsyncProcess.java:733)
at java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source)
at java.util.concurrent.FutureTask.run(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
我在日志中也发现了这几行:
2017-01-03 19:09:16 DEBUG UserGroupInformation:1638 - PrivilegedAction as:user@MAIL.COM (auth:KERBEROS) from:org.apache.hadoop.hbase.ipc.RpcClientImpl$Connection.setupIOstreams(RpcClientImpl.java:740)
2017-01-03 19:09:16 DEBUG UserGroupInformation:1618 - PrivilegedActionException as:user@MAIL.COM (auth:KERBEROS) cause:javax.security.sasl.SaslException: GSS initiate failed [Caused by GSSException: No valid credentials provided (Mechanism level: Failed to find any Kerberos tgt)]
2017-01-03 19:09:16 DEBUG UserGroupInformation:1638 - PrivilegedAction as:user@MAIL.COM (auth:KERBEROS) from:org.apache.hadoop.hbase.ipc.RpcClientImpl$Connection.handleSaslConnectionFailure(RpcClientImpl.java:643)
2017-01-03 19:09:16 WARN UserGroupInformation:1113 - Not attempting to re-login since the last re-login was attempted less than 600 seconds before.
有任何点击或提示我做错了什么吗?
编辑:
我使用此代码使用 kerberos 进行身份验证:
Configuration configuration = HBaseConfiguration.create();
configuration.addResource("some config file");
UserGroupInformation.setConfiguration(configuration);
UserGroupInformation.loginUserFromKeytab(kerberosUser, keytabFilePath);
我在项目中将 hadoop 依赖项的版本更改为 2.6.5。
最终的解决方案,似乎有效:
1.升级Hadoop依赖到2.6.5版本(hadoop-auth,hadoop-mapreduce-client-core,hadoop-common)。
2. 创建简单的调度程序,每 5-6 分钟执行一次下面的代码。
3. 在使用 HBase 数据库的每个操作之前执行下面的代码。
UserGroupInformation.getLoginUser().checkTGTAndReloginFromKeytab();
我有一个小型 spring 服务,它提供基本功能,例如来自 hbase table 的 put/delete/get。一切似乎都正常,但有一个问题。启动我的 tomcat 服务器 10 小时后,我的 kerberos 票证到期,所以我应该更新它。我尝试将 java api 用于 hbase,并在连接到 hbase 的每个方法的代码中添加了这一行:
UserGroupInformation.getLoginUser().checkTGTAndReloginFromKeytab();
我也试过:
UserGroupInformation.getLoginUser().reloginFromKeytab()
和:
SecurityUtil.login(configuration, keytabFilePath, kerberosUser)
但这没有用,我在服务器重启 10 小时后收到此异常:
javax.security.sasl.SaslException: GSS initiate failed [Caused by GSSException: No valid credentials provided (Mechanism level: Failed to find any Kerberos tgt)]
at com.sun.security.sasl.gsskerb.GssKrb5Client.evaluateChallenge(Unknown Source)
at org.apache.hadoop.hbase.security.HBaseSaslRpcClient.saslConnect(HBaseSaslRpcClient.java:179)
at org.apache.hadoop.hbase.ipc.RpcClientImpl$Connection.setupSaslConnection(RpcClientImpl.java:617)
at org.apache.hadoop.hbase.ipc.RpcClientImpl$Connection.access0(RpcClientImpl.java:162)
at org.apache.hadoop.hbase.ipc.RpcClientImpl$Connection.run(RpcClientImpl.java:743)
at org.apache.hadoop.hbase.ipc.RpcClientImpl$Connection.run(RpcClientImpl.java:740)
at java.security.AccessController.doPrivileged(Native Method)
at javax.security.auth.Subject.doAs(Unknown Source)
at org.apache.hadoop.security.UserGroupInformation.doAs(UserGroupInformation.java:1614)
at org.apache.hadoop.hbase.ipc.RpcClientImpl$Connection.setupIOstreams(RpcClientImpl.java:740)
at org.apache.hadoop.hbase.ipc.RpcClientImpl$Connection.writeRequest(RpcClientImpl.java:906)
at org.apache.hadoop.hbase.ipc.RpcClientImpl$Connection.tracedWriteRequest(RpcClientImpl.java:873)
at org.apache.hadoop.hbase.ipc.RpcClientImpl.call(RpcClientImpl.java:1241)
at org.apache.hadoop.hbase.ipc.AbstractRpcClient.callBlockingMethod(AbstractRpcClient.java:227)
at org.apache.hadoop.hbase.ipc.AbstractRpcClient$BlockingRpcChannelImplementation.callBlockingMethod(AbstractRpcClient.java:336)
at org.apache.hadoop.hbase.protobuf.generated.ClientProtos$ClientService$BlockingStub.multi(ClientProtos.java:34142)
at org.apache.hadoop.hbase.client.MultiServerCallable.call(MultiServerCallable.java:128)
at org.apache.hadoop.hbase.client.MultiServerCallable.call(MultiServerCallable.java:53)
at org.apache.hadoop.hbase.client.RpcRetryingCaller.callWithoutRetries(RpcRetryingCaller.java:210)
at org.apache.hadoop.hbase.client.AsyncProcess$AsyncRequestFutureImpl$SingleServerRequestRunnable.run(AsyncProcess.java:733)
at java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source)
at java.util.concurrent.FutureTask.run(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
我在日志中也发现了这几行:
2017-01-03 19:09:16 DEBUG UserGroupInformation:1638 - PrivilegedAction as:user@MAIL.COM (auth:KERBEROS) from:org.apache.hadoop.hbase.ipc.RpcClientImpl$Connection.setupIOstreams(RpcClientImpl.java:740)
2017-01-03 19:09:16 DEBUG UserGroupInformation:1618 - PrivilegedActionException as:user@MAIL.COM (auth:KERBEROS) cause:javax.security.sasl.SaslException: GSS initiate failed [Caused by GSSException: No valid credentials provided (Mechanism level: Failed to find any Kerberos tgt)]
2017-01-03 19:09:16 DEBUG UserGroupInformation:1638 - PrivilegedAction as:user@MAIL.COM (auth:KERBEROS) from:org.apache.hadoop.hbase.ipc.RpcClientImpl$Connection.handleSaslConnectionFailure(RpcClientImpl.java:643)
2017-01-03 19:09:16 WARN UserGroupInformation:1113 - Not attempting to re-login since the last re-login was attempted less than 600 seconds before.
有任何点击或提示我做错了什么吗?
编辑: 我使用此代码使用 kerberos 进行身份验证:
Configuration configuration = HBaseConfiguration.create();
configuration.addResource("some config file");
UserGroupInformation.setConfiguration(configuration);
UserGroupInformation.loginUserFromKeytab(kerberosUser, keytabFilePath);
我在项目中将 hadoop 依赖项的版本更改为 2.6.5。
最终的解决方案,似乎有效: 1.升级Hadoop依赖到2.6.5版本(hadoop-auth,hadoop-mapreduce-client-core,hadoop-common)。 2. 创建简单的调度程序,每 5-6 分钟执行一次下面的代码。 3. 在使用 HBase 数据库的每个操作之前执行下面的代码。
UserGroupInformation.getLoginUser().checkTGTAndReloginFromKeytab();