使用 Java 和来自 Windows 的 Kerberos Keytab 在 Cloudera 上访问 HDFS

Accessing HDFS on Cloudera with Java and Kerberos Keytab from Windows

我正在尝试连接到我在 Cloudera 上的 HDFS 实例 运行。我的第一步是启用 Kerberos 并创建密钥表(如图所示 here)。

在下一步中,我想使用密钥表进行身份验证。

Configuration conf = new Configuration();
conf.set("fs.defaultFS", "hdfs://cloudera:8020");
conf.set("hadoop.security.authentication", "kerberos");

UserGroupInformation.setConfiguration(conf);
UserGroupInformation.loginUserFromKeytab("hdfs@CLOUDERA", "/etc/hadoop/conf/hdfs.keytab");

FileSystem fs = FileSystem.get(conf);
FileStatus[] fsStatus = fs.listStatus(new Path("/"));
for (int i = 0; i < fsStatus.length; i++) {
    System.out.println(fsStatus[i].getPath().toString());
}

失败并出现以下错误

java.io.IOException: Login failure for hdfs@CLOUDERA from keytab /etc/hadoop/conf/hdfs.keytab: javax.security.auth.login.LoginException: Unable to obtain password from user

问题是:如何正确处理keytab?我必须将它复制到我的本地机器吗?

您是否设置了适当的权限?

 chown hdfs:hadoop /etc/hadoop/conf/hdfs.keytab
 chmod 440 /etc/hadoop/conf/hdfs.keytab

当 运行在 Windows 上连接 Hadoop 客户端以访问 kerberized 集群时,您需要 一个特定的 "native library"(即 DLL)。
据我所知,这没有充分的理由,因为该库实际上并未在某些自动回归测试之外使用(!?!),因此 Hadoop 提交者给 Hadoop 用户带来了痛苦。

更糟糕的是,该 DLL 没有官方构建(以及 Windows "stub" 允许从 Java 使用)。您必须 (a) 从源代码自己构建它——祝您好运——或者 (b) 在互联网上搜索可下载的 Hadoop- for-Windows 运行时间,并祈祷它不包含任何恶意软件。
最好的选择(64 位 Windows)在这里:https://github.com/steveloughran/winutils
...自述文件解释了为什么您可以合理地相信 运行 时间。但是,如果您受困于较旧的 32 位 Windows,那么您就只能靠自己了。

现在假设您在
下的 Windows 盒子上部署了 运行 时间 C:\Some Dir\hadoop\bin\
(最后的 bin 是必需的;嵌入的 space 只是额外的乐趣)

您必须使用几个 Java 属性将 Hadoop 客户端指向那个 运行 时间:
"-Dhadoop.home.dir=C:/Some Dir/hadoop" "-Djava.library.path=C:/Some Dir/hadoop/bin"
(注意 Windows args 周围的双引号作为一个整体,以保护路径中嵌入的 spaces,它们已被翻译成 Java 风格以获得额外的乐趣)
(在 Eclipse 中,只需将这些道具填充到 "VM Arguments" 下,包括引号)

现在是 Kerberos 配置。如果您的 KDC 是您公司的 Active Directory 服务器,那么 Java 应该会自动找到配置参数。但是如果你的 KDC 是一个独立的 "MIT Kerberos" 安装在 Linux 上,那么你必须在集群上找到一个有效的 /etc/krb5.conf 文件,将它复制到你的 Windows 盒子上,然后Java 将其与额外的 属性...
一起使用 "-Djava.security.krb5.conf=C:/Some Other Dir/krb5.conf"

然后假设您使用 ktutil 在 Linux 框上创建了您的密钥表文件(或者 Active Directory 管理员使用一些 AD 命令为您创建了它)并且您将文件放在了下面
C:\Some Other Dir\foo.keytab
首先,如果 keytab 用于真实的 Windows 帐户——即您自己的帐户——或 Prod 服务帐户,那么 确保 keytab 是安全的!使用 Windows 安全对话框仅限制对您帐户的访问 (可能还有系统,用于备份)。因为该文件可以让任何人在任何机器上对集群(以及任何支持 Kerberos 的系统,包括 Windows)进行身份验证。

现在您可以尝试使用
进行身份验证 UserGroupInformation.loginUserFromKeytab("foo@BAR.ORG", "C:/Some Other Dir/foo.keytab");

如果它不起作用,请使用环境变量启用 Kerberos 调试跟踪
set HADOOP_JAAS_DEBUG=true
...和 ​​Java 属性
-Dsun.security.krb5.debug=true
(在Eclipse中,分别在"Environment"和"VM Arguments"中设置)