我正在测试一个Spark Java应用程序,它使用Impala JDBC驱动程序执行用Impala语法编写的查询,并将结果写入Excel模板文件。 此应用程序在本地模式下完美地运行到kerberra Cloudera集群中。
事实是,如果此应用程序以纱线群集模式执行,它会等待Kerberos密码,因此我决定将一些必要的文件包含在spark-submit调用中:
spark-submit --verbose --master yarn-cluster
--files gss-jaas.conf,configuration.properties
--principal myPrincipal --keytab myKeytab
--name "app" --conf spark.executor.cores=2
--conf spark.executor.memory=8G --conf spark.executor.instances=3
--conf spark.driver.memory=256M
--class myClass output.jar queriesConfig.json configuration.properties
修改Java代码以在kerberos登录之前执行对kinit的系统调用,以获得自动访问,就像在本地模式下执行应用程序一样。但是,我没有运气使用以下代码:
System.setProperty("java.security.auth.login.config", prop.getProperty("jdbc.kerberos.jaas"));
System.setProperty("sun.security.jgss.debug", "true");
System.setProperty("sun.security.krb5.debug", "true");
System.setProperty("javax.security.auth.useSubjectCredsOnly", "true");
System.setProperty("java.security.debug", "gssloginconfig,configfile,configparser,logincontext");
System.setProperty("java.security.krb5.conf", prop.getProperty("kerberos.conf"));
if (prop.getProperty("ssl.enabled") != null && "true".equals(prop.getProperty("ssl.enabled"))) {
System.setProperty("javax.net.ssl.trustStore", prop.getProperty("trustStore.path"));
System.setProperty("javax.net.ssl.trustStorePassword", prop.getProperty("trustStore.password"));
}
StringBuffer output = new StringBuffer();
Process p;
try {
final String command = "kinit -k -t myKeytab myUser";
p = Runtime.getRuntime().exec(command);
p.waitFor();
BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream()));
String line = "";
while ((line = reader.readLine())!= null) {
output.append(line + "\n");
}
lc = new LoginContext(JDBC_DRIVER_JAAS, new TextCallbackHandler());
if (lc != null) {
lc.login();
}
} catch (LoginException le) {
LOGGER.error("LoginException . " + le.getMessage(), le);
} catch (SecurityException se) {
LOGGER.error("SecurityException . " + se.getMessage(), se);
} catch (Exception e) {
LOGGER.error("EXCEPTION !!! " + e.getMessage(), e);
}
获取以下错误:
ERROR hive.JDBCHandler: Cannot create LoginContext. Integrity check on decrypted field failed (31) - PREAUTH_FAILED
javax.security.auth.login.LoginException: Integrity check on decrypted field failed (31) - PREAUTH_FAILED
at com.sun.security.auth.module.Krb5LoginModule.attemptAuthentication(Krb5LoginModule.java:804)
at com.sun.security.auth.module.Krb5LoginModule.login(Krb5LoginModule.java:617)
考虑到查询应该使用Impala语法,我有哪些替代方案?当以纱线群集模式执行应用程序时,是否可以登录kerberos?