嵌入到Spark应用程序中的Impala JDBC驱动程序的Kerberos登录

时间:2018-04-25 17:52:53

标签: java apache-spark jdbc impala

我正在测试一个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?

0 个答案:

没有答案