我有一个Spring引导应用程序,该应用程序通过通过Kerberos保护的Apache Knox通过Webhdfs访问HDFS。我使用自定义方案(swebhdfsknox)创建了自己的KnoxWebHdfsFileSystem
作为WebHdfsFilesystem
的子类,该子类仅更改URL以包含Knox代理前缀。因此,它可以有效地重新映射来自表单的请求:http://host:port/webhdfs/v1/...
到诺克斯:http://host:port/gateway/default/webhdfs/v1/...
我通过重写两种方法来做到这一点:
public URI getUri()
URL toUrl(Op op, Path fspath, Param<?, ?>... parameters)
到现在为止还挺好。我让spring boot为我创建
FsShell
并将其用于各种操作,例如列表文件,mkdir等。一切正常。除了copyFromLocal之外,据记录需要2个步骤并重定向。在最后一步,当文件系统尝试PUT
到Location header 中收到的最终URL时,它失败并显示错误:org.apache.hadoop.security.AccessControlException: Authentication required
at org.apache.hadoop.hdfs.web.WebHdfsFileSystem.validateResponse(WebHdfsFileSystem.java:334) ~[hadoop-hdfs-2.6.0.jar:na]
at org.apache.hadoop.hdfs.web.WebHdfsFileSystem.access$200(WebHdfsFileSystem.java:91) ~[hadoop-hdfs-2.6.0.jar:na]
at org.apache.hadoop.hdfs.web.WebHdfsFileSystem$FsPathOutputStreamRunner$1.close(WebHdfsFileSystem.java:787) ~[hadoop-hdfs-2.6.0.jar:na]
at org.apache.hadoop.io.IOUtils.copyBytes(IOUtils.java:54) ~[hadoop-common-2.6.0.jar:na]
at org.apache.hadoop.io.IOUtils.copyBytes(IOUtils.java:112) ~[hadoop-common-2.6.0.jar:na]
at org.apache.hadoop.fs.FileUtil.copy(FileUtil.java:366) ~[hadoop-common-2.6.0.jar:na]
at org.apache.hadoop.fs.FileUtil.copy(FileUtil.java:338) ~[hadoop-common-2.6.0.jar:na]
at org.apache.hadoop.fs.FileUtil.copy(FileUtil.java:302) ~[hadoop-common-2.6.0.jar:na]
at org.apache.hadoop.fs.FileSystem.copyFromLocalFile(FileSystem.java:1889) ~[hadoop-common-2.6.0.jar:na]
at org.springframework.data.hadoop.fs.FsShell.copyFromLocal(FsShell.java:265) ~[spring-data-hadoop-core-2.2.0.RELEASE.jar:2.2.0.RELEASE]
at org.springframework.data.hadoop.fs.FsShell.copyFromLocal(FsShell.java:254) ~[spring-data-hadoop-core-2.2.0.RELEASE.jar:2.2.0.RELEASE]
我怀疑问题出在某种程度上是重定向,但无法弄清楚这里可能是什么问题。如果我通过curl进行相同的请求,则文件已成功上传到HDFS。
最佳答案
对于Knox上的kerberos使用HadoopAuth提供程序,针对Apache Knox使用现有Hadoop客户端,这是一个已知问题。如果您要使用curl或其他一些REST客户端,则可能对您有用。现有的Hadoop Java客户端并不希望DataNode遇到SPNEGO挑战-这就是发送步骤中的PUT所要讨论的内容。 DataNode希望由NameNode在第一步中发布的块访问 token /委托(delegate) token 存在。但是,对于对该拓扑的每个请求,Knox网关都需要SPNEGO身份验证。
这是一个有待解决的路线图上的问题,随着兴趣更多地转移到群集内部而不是仅从外部通过群集访问资源,该问题可能会变得更热。
以下JIRA跟踪此项目,从标题中可以看到,该案例与DistCp有关,这是一个类似的用例:
https://issues.apache.org/jira/browse/KNOX-482
随意看一下并提供测试或开发帮助-非常欢迎!
另一种可能性是更改Hadoop Java客户端,以应对DataNode的SPNEGO挑战。