我正在开发一个Java应用程序,这个应用程序正在将结果数据保存到HDFS。java应用程序应该在我的Windows机器中运行。
我们使用 Kerberos 身份验证,并在 NAS 驱动器中放置了一个密钥表文件。我们将Hadoop配置文件保存在同一个NAS驱动器中。
我的问题是当我从 NAS 驱动器加载 Hadoop 配置文件时,它给我抛出了一些身份验证错误,但是如果我从本地文件系统加载配置文件,我的应用程序运行良好(我还将配置文件保存在 C:\Hadoop 中)
下面是我的工作代码片段。(NAS 中的密钥表文件,本地文件系统中的 Hadoop 配置文件)
static String KeyTabPath = "\\path\2\keytabfile\name.keytab"
Configuration config = new Configuration();
config.set("fs.defaultFS", "hdfs://xxx.xx.xx.com:8020");
config.addResource(new Path("C:\Hadoop\core-site.xml"));
config.addResource(new Path("C:\Hadoop\hdfs-site.xml"));
config.addResource(new Path("C:\Hadoop\mapred-site.xml"));
config.addResource(new Path("C:\Hadoop\yarn-site.xml"));
config.set("fs.hdfs.impl", org.apache.hadoop.hdfs.DistributedFileSystem.class.getName());
config.set("fs.file.impl",org.apache.hadoop.fs.LocalFileSystem.class.getName());
// Kerberos Authentication
config.set("hadoop.security.authentication", "Kerberos");
UserGroupInformation.setConfiguration(config);
UserGroupInformation.loginUserFromKeytab("name@xx.xx.COM",KeyTabPath);
我也尝试从 NAS 驱动器加载配置文件,但收到 kerberos 身份验证错误。下面是抛出错误的代码片段(NAS 中的密钥表文件和 NAS 中的 Hadoop 配置文件)
static String KeyTabPath = "\\path\2\keytabfile\name.keytab"
Configuration config = new Configuration();
config.set("fs.defaultFS", "hdfs://xxx.xx.xx.com:8020");
config.addResource(new Path("\\NASDrive\core-site.xml"));
config.addResource(new Path("\\NASDrive\hdfs-site.xml"));
config.addResource(new Path("\\NASDrive\mapred-site.xml"));
config.addResource(new Path("\\NASDrive\yarn-site.xml"));
config.set("fs.hdfs.impl", org.apache.hadoop.hdfs.DistributedFileSystem.class.getName());
config.set("fs.file.impl",org.apache.hadoop.fs.LocalFileSystem.class.getName());
// Kerberos Authentication
config.set("hadoop.security.authentication", "Kerberos");
UserGroupInformation.setConfiguration(config);
UserGroupInformation.loginUserFromKeytab("name@xx.xx.COM",KeyTabPath);
下面是错误消息
java.io.IOException: Login failure for name@XX.XX.COM from keytab \NASdrivename.keytab: javax.security.auth.login.LoginException: java.lang.IllegalArgumentException: Illegal principal name name@XX.XX.COM: org.apache.hadoop.security.authentication.util.KerberosName$NoMatchingRule: No rules applied to name@XX.XX.COM
at org.apache.hadoop.security.UserGroupInformation.loginUserFromKeytab(UserGroupInformation.java:962)
at Appname.ldapLookupLoop(Appname.java:111)
at Appname.main(Appname.java:70)
Caused by: javax.security.auth.login.LoginException: java.lang.IllegalArgumentException: Illegal principal name name@XX.XX.COM: org.apache.hadoop.security.authentication.util.KerberosName$NoMatchingRule: No rules applied to name@XX.XX.COM
at org.apache.hadoop.security.UserGroupInformation$HadoopLoginModule.commit(UserGroupInformation.java:199)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at javax.security.auth.login.LoginContext.invoke(Unknown Source)
at javax.security.auth.login.LoginContext.access$000(Unknown Source)
at javax.security.auth.login.LoginContext$4.run(Unknown Source)
at javax.security.auth.login.LoginContext$4.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at javax.security.auth.login.LoginContext.invokePriv(Unknown Source)
at javax.security.auth.login.LoginContext.login(Unknown Source)
at org.apache.hadoop.security.UserGroupInformation.loginUserFromKeytab(UserGroupInformation.java:953)
... 2 more
Caused by: java.lang.IllegalArgumentException: Illegal principal name name@XX.XX.COM: org.apache.hadoop.security.authentication.util.KerberosName$NoMatchingRule: No rules applied to name@XX.XX.COM
at org.apache.hadoop.security.User.<init>(User.java:51)
at org.apache.hadoop.security.User.<init>(User.java:43)
at org.apache.hadoop.security.UserGroupInformation$HadoopLoginModule.commit(UserGroupInformation.java:197)
... 14 more
Caused by: org.apache.hadoop.security.authentication.util.KerberosName$NoMatchingRule: No rules applied to name@XX.XX.COM
at org.apache.hadoop.security.authentication.util.KerberosName.getShortName(KerberosName.java:389)
at org.apache.hadoop.security.User.<init>(User.java:48)
... 16 more
Jul 06, 2016 4:29:14 PM com.XX.it.logging.JdkMapper info
INFO: IO Exception occured: java.io.IOException: Login failure for name@XX.XX.COM from keytab \NASdrivename.keytab: javax.security.auth.login.LoginException: java.lang.IllegalArgumentException: Illegal principal name name@XX.XX.COM: org.apache.hadoop.security.authentication.util.KerberosName$NoMatchingRule: No rules applied to name@XX.XX.COM
所以问题似乎正在加载配置文件。我的应用程序从 NAS 驱动器读取密钥表文件,但不能读取 Hadoop 配置文件。可能是什么问题。我检查了所有 NAS 驱动器权限和文件权限。一切都很好。我不知道问题出在哪里。请任何人帮助我找出问题。
kerberos 主体名称转换auth_to_local
"默认"规则。
org.apache.hadoop.security.authentication.util.KerberosName$NoMatchingRule: 没有适用于的规则
请参阅此处的示例 -
https://hadoop.apache.org/docs/current/hadoop-project-dist/hadoop-common/SecureMode.html#Mapping_from_Kerberos_principals_to_OS_user_accounts
所以基本上只需在core-site.xml
hadoop.security.auth_to_local
末尾添加单词"DEFAULT"。
另请查看 Kerberos 文档中的auth_to_local
。
附言。这是Hadoop代码库中发生此异常的地方,以防您有兴趣更深入地研究此主题。