Я тестирую приложение Spark Java, которое использует драйвер JDBC Impala для выполнения запросов, написанных в синтаксисе Impala, и записи результатов в файл шаблона Excel.Это приложение отлично работает в локальном режиме в кластеризованном кластере 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 для выполнения системного вызова kinit перед входом в Kerberos, чтобы получить автоматический доступ, как при выполнении приложения в локальной сети.Режим.Однако мне не повезло, используя следующий код:
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, когда приложение выполняется в режиме кластера пряжи?