我的resources文件夹中有从HDFS读取/写入HDFS所需的所有4个文件,创建HDFS对象的方法如下。
public static FileSystem getHdfsOnPrem(String coreSiteXml, String hdfsSiteXml, String krb5confLoc, String keyTabLoc){
// Setup the configuration object.
try {
Configuration config = new Configuration();
config.addResource(new org.apache.hadoop.fs.Path(coreSiteXml));
config.addResource(new org.apache.hadoop.fs.Path(hdfsSiteXml));
config.set("hadoop.security.authentication", "Kerberos");
config.addResource(krb5confLoc);
config.set("fs.hdfs.impl",org.apache.hadoop.hdfs.DistributedFileSystem.class.getName());
config.set("fs.file.impl",org.apache.hadoop.fs.LocalFileSystem.class.getName());
System.setProperty("java.security.krb5.conf", krb5confLoc);
org.apache.hadoop.security.HadoopKerberosName.setConfiguration(config);
UserGroupInformation.setConfiguration(config);
UserGroupInformation.loginUserFromKeytab("my_username", keyTabLoc);
return org.apache.hadoop.fs.FileSystem.get(config);
}
catch(Exception ex) {
ex.printStackTrace();
return null;
}
}
当我在本地运行它并在下面作为路径时,它就工作了
C:Usersmy_usernameIdeaProjectsmy_project_nametargetscala-2.12classescore-site.xml
C:Usersmy_usernameIdeaProjectsmy_project_nametargetscala-2.12classeshdfs-site.xml
C:Usersmy_usernameIdeaProjectsmy_project_nametargetscala-2.12classeskrb5.conf
C:Usersmy_usernameIdeaProjectsmy_project_nametargetscala-2.12classesmy_username.user.keytab
当我在本地运行它时,它运行得很好,但当我将它绑定为JAR并在类似kubernetes的环境中运行时,它会抛出以下错误(由于绑定为JAR,我可以将资源文件的内容作为流读取,但我需要为loginuserFromKeytab方法传入路径(
org.apache.hadoop.security.KerberosAuthException: failure to login: for principal: my_username from keytab file:/opt/spark-3.0.0/jars/foo-project-name!/my_username.user.keytab javax.security.auth.login.LoginException: Unable to obtain password from user
欢迎提出任何建议/建议。
我建议您使用Jaas配置文件,而不是编写此代码。这有助于从代码中删除安全管道并将其外部化;无法获得密码";如果运行你的应用程序的用户没有访问该文件的权限,就会发生这种情况。