Весенняя загрузка Hadoop, Webhdfs и Apache Knox

У меня есть загрузочное приложение Spring, которое обращается к HDFS через Webhdfs, защищенное через Apache Knox, защищенное Kerberos. Я создал свой собственный KnoxWebHdfsFileSystem с пользовательской схемой (swebhdfsknox) в качестве подкласса WebHdfsFilesystem который изменяет только URL-адреса, содержащие префикс Knox-прокси. Таким образом, он эффективно перераспределяет запросы из формы:

http://host:port/webhdfs/v1/...

Ноксу:

http://host:port/gateway/default/webhdfs/v1/...

Я делаю это, переопределяя два метода:

  1. public URI getUri()
  2. URL toUrl(Op op, Path fspath, Param<?, ?>... parameters)

Все идет нормально. Я позволил весеннему ботинку создать FsShell для меня и использовать его для различных операций, таких как список файлов, MKDIR и т. д. Все работает нормально. За исключением copyFromLocal, который согласно документу требует 2 шага и перенаправления. И на последнем шаге, когда файловая система пытается PUT на последний URL-адрес, полученный в заголовке Location, происходит ошибка:

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.

1 ответ

Решение

Это известная проблема, связанная с использованием существующих клиентов Hadoop против Apache Knox с использованием поставщика HadoopAuth для kerberos в Knox. Если бы вы использовали curl или какой-либо другой REST-клиент, он, вероятно, сработал бы для вас. Существующий Java-клиент Hadoop не ожидает вызова SPNEGO от узла DataNode, о котором говорит PUT на этапе отправки. DataNode ожидает присутствия маркера доступа блока / токена делегирования, выданного NameNode на первом этапе. Однако шлюзу Knox потребуется проверка подлинности SPNEGO для каждого запроса к этой топологии.

Это проблема, которая должна быть рассмотрена в дорожной карте, и, вероятно, она станет более горячей, так как интерес будет больше перемещаться внутри кластера, а не только через ресурсы извне.

Следующая JIRA отслеживает этот элемент и, как вы можете видеть из заголовка, относится к DistCp, который является аналогичным вариантом использования: https://issues.apache.org/jira/browse/KNOX-482

Не стесняйтесь взглянуть и помочь с тестированием или разработкой - все это будет приветствоваться!

Другой возможностью было бы изменить Java-клиент Hadoop для решения задачи SPNEGO и для DataNode.

Другие вопросы по тегам