Доступ к java-действию Oozie HDFS с помощью Kerberos

#java #hadoop #hdfs #kerberos #oozie

#java #hadoop #hdfs #kerberos #oozie

Вопрос:

Я разработал Java-приложение для подключения к серверу Ldap и получения подробной информации в формате csv на основе пользовательских аргументов. Результирующий csv-файл будет сохранен в HDFS (файловая система Hadoop).

Для записи в HDFS я импортировал org.apache.hadoop.security.UserGroupInformation и правильно настроил конфигурацию Kerberos. Ниже приведен фрагмент кода.

 config.set("hadoop.security.authentication","Kerberos");
UserGroupInformation.setConfiguration(config);
UserGroupInformation.loginUserFromKeytab(Principal,KeyTabfile); 
 

мы сохранили файл keytab на пограничном сервере среды POC. Когда я запускаю Java-приложение с пограничного сервера, оно считывает файл keytab, который работает нормально, и записывает результаты в HDFS.

Но моя проблема начинается, когда я пытаюсь отключить это приложение с помощью oozie. Oozie запускает java-действия на любом из узлов данных в кластере в зависимости от доступности ресурсов, и oozie не может получить доступ к пограничному серверу. Из-за этого мое java-действие в oozie завершилось ошибкой с исключением безопасности, поскольку оно не может прочитать файл keytab на пограничном сервере.

Ниже приведены сведения об исключении.

 java.io.IOException: Login failure for hdfs://namenode:8020 from keytab xxxxx@zz.yy.COM: javax.security.auth.login.LoginException: java.lang.IllegalArgumentException: Empty nameString not allowed
at sun.security.krb5.PrincipalName.validateNameStrings(PrincipalName.java:171)
at sun.security.krb5.PrincipalName.<init>(PrincipalName.java:393)
at sun.security.krb5.PrincipalName.<init>(PrincipalName.java:460)
at com.sun.security.auth.module.Krb5LoginModule.attemptAuthentication(Krb5LoginModule.java:650)
at com.sun.security.auth.module.Krb5LoginModule.login(Krb5LoginModule.java:617)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at javax.security.auth.login.LoginContext.invoke(LoginContext.java:755)
at javax.security.auth.login.LoginContext.access$000(LoginContext.java:195)
at javax.security.auth.login.LoginContext$4.run(LoginContext.java:682)
at javax.security.auth.login.LoginContext$4.run(LoginContext.java:680)
at java.security.AccessController.doPrivileged(Native Method)
at javax.security.auth.login.LoginContext.invokePriv(LoginContext.java:680)
at javax.security.auth.login.LoginContext.login(LoginContext.java:587)
at org.apache.hadoop.security.UserGroupInformation.loginUserFromKeytab(UserGroupInformation.java:967)
at RunLdap_Utility.ldapLookupLoop(RunLdap_Utility.java:142)
at RunLdap_Utility.main(RunLdap_Utility.java:72)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at org.apache.oozie.action.hadoop.JavaMain.run(JavaMain.java:56)
at org.apache.oozie.action.hadoop.LauncherMain.run(LauncherMain.java:47)
at org.apache.oozie.action.hadoop.JavaMain.main(JavaMain.java:35)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at org.apache.oozie.action.hadoop.LauncherMapper.map(LauncherMapper.java:241)
at org.apache.hadoop.mapred.MapRunner.run(MapRunner.java:54)
at org.apache.hadoop.mapred.MapTask.runOldMapper(MapTask.java:453)
at org.apache.hadoop.mapred.MapTask.run(MapTask.java:343)
at org.apache.hadoop.mapred.YarnChild$2.run(YarnChild.java:168)
at java.security.AccessController.doPrivileged(Native Method)
at javax.security.auth.Subject.doAs(Subject.java:422)
at org.apache.hadoop.security.UserGroupInformation.doAs(UserGroupInformation.java:1709)
at org.apache.hadoop.mapred.YarnChild.main(YarnChild.java:162)
 

Пожалуйста, предложите мне решение этой проблемы

Комментарии:

1. Вы пытались удалить этот специальный вызов UGI из своего кода и просто использовать аутентификацию по умолчанию? — т.е. на пограничном узле заранее создайте билет Kerberos с kinit помощью; и внутри рабочего процесса Oozie просто позвольте Oozie запросить контейнер YARN с соответствующим токеном делегирования Hadoop (который предоставляет прозрачный доступ к HDFS).

2. Кроме того, загляните в документацию Oozie для «учетных данных». Они необходимы для Hive, HBase и т. Д., Которые не полагаются на токены делегирования и требуют необработанной аутентификации Kerberos.

3. @SamsonScharfrichter Это сработало. Спасибо!