Вход Kerberos в драйвер Impala JDBC, встроенный в приложение Spark - PullRequest
0 голосов
/ 25 апреля 2018

Я тестирую приложение 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, когда приложение выполняется в режиме кластера пряжи?

...