搭建了一个Hadoop的环境,Hadoop集群环境部署在几个Linux服务器上,现在想使用windows上的Java客户端来操作集群中的HDFS文件,但是在操作的过程中出出了如下的认证错误,被折磨了几天,问题终得以解决。以此文记录问题的解决过程。

(如果想看最终解决问题的方法拉到最后,如果想看我的问题解决思路请从上向下看)

问题描述

上传文件的代码:

  1. privatestaticvoid uploadToHdfs() throws FileNotFoundException,IOException {

  2. //我的文件地址

  3. String localSrc = "E:\\快盘\\技术文档\\hadoop\\HDFS初步研究.pdf";

  4. //存放在云端的目的地址

  5. String dest = "hdfs://192.168.2.156:9000/user/HDFS初步研究.pdf";

  6. InputStream in = new BufferedInputStream(new FileInputStream(localSrc));

  7. //得到配置对象

  8. Configuration conf = new Configuration();

  9. //        conf.set("fs.default.name","hdfs://192.168.2.156:9000");

  10. //文件系统

  11. FileSystem fs = FileSystem.get(URI.create(dest), conf);

  12. //输出流

  13. OutputStream out = fs.create(new Path(dest), new Progressable() {

  14. @Override

  15. publicvoid progress() {

  16. System.out.println("上传完一个设定缓存区大小容量的文件!");

  17. }

  18. });

  19. //连接两个流,形成通道,使输入流向输出流传输数据

  20. IOUtils.copyBytes(in, out, 4096, true);

  21. }

错误的详细描述如下:

org.apache.hadoop.security.AccessControlException: org.apache.hadoop.security .AccessControlException: Permission denied: user=Administrator, access=WRITE, inode="hadoop": hadoop:supergroup:rwxr-xr-x

其实这个错误的原因很容易看出来,用户Administator在hadoop上执行写操作时被权限体系拒绝.

解决问题的过程

看到这个错误的,第一步就是将这个错误直接入放到百度google里面进行搜索。找到了N多篇文章,但是主要的思路就如此篇文章所写的两个解决办法:http://www.cnblogs.com/acmy/archive/2011/10/28/2227901.html

1、在hdfs的配置文件中,将dfs.permissions修改为False

2、执行这样的操作 hadoop fs -chmod 777 /user/hadoop

对于上面的第一个方法,我试了行不通,不知道是自己设置错误还是怎么此法不可行,第二个方法可行。第二个方法是让我们来修改HDFS中相应文件夹的权限,后面的/user/hadoop这个路径为HDFS中的文件路径,这样修改之后就让我们的administrator有在HDFS的相应目录下有写文件的权限。

虽然上面的第二步可以解决问题了,上传之后的用户所有者为Administrator,但是总感觉这样的方法不够优雅,而且这样修改权限会有一定的安全问题,总之就是看着不爽,就在想有没有其他的办法?

问题分析

现在我就开始仔细的观察这个错误的详细信息,看到user=Administrator, access=WRITE。这里的user其实是我当用系统的用户名,我期望这里的user=hadoop(hadoop是我的HADOOP上面的用户名),但是他取的是当前的系统的用户名,很明显,如果我将当前系统的用户名改为hadoop,这个肯定也是可以行得通的,但是如果后期将开始的代码部署到服务器上之后,就不能方便的修改用户,此方法明显也不够方便。

现在就想着Configuration这个是一个配置类,有没有一个参数是可以设置以哪个用户运行呢?搜索了半天,无果。没有找到相关的配置参数。

最终只有继续分析代码, FileSystem fs = FileSystem.get(URI.create(dest), conf);代码是在这里的时候开始对HDFS进行调用,所以就想着将HADOOP的源码下下来,debug整个调用过程,这个user=Administator是在啥时候赋予的值。知道了调用过程,还怕找不到解决问题的办法么?

跟踪代码进入 FileSystem.get-->CACHE.get()-->Key key = new Key(uri, conf);到这里的时候发现key值里面已经有Administrator了,所以关键肯定是在new key的过程。继续跟踪UserGroupInformation.getCurrentUser()-->getLoginUser()-->login.login()到这一步的时候发现用户名已经确定了,但是这个方法是Java的核心源码,是一个通用的安全认证,但对这一块不熟悉,但是debug时看到subject里面有NTUserPrincipal:Administator,所以就想着搜索一下这个东西是啥,结果就找到了下面这一篇关键的文章:

http://www.udpwork.com/item/7047.html

在此篇文章里面作者分析了hadoop的整个登录过程,对于我有用的是其中的这一段:

2.login.login();
这个会调用HadoopLoginModule的login()和commit()方法。
HadoopLoginModule的login()方法是一个空函数,只打印了一行调试日志 LOG.debug("hadoop login");
commit()方法负责把Principal添加到Subject中。
此时一个首要问题是username是什么?
在使用了kerberos的情况下,从javax.security.auth.kerberos.KerberosPrincipal的实例获取username。
在未使用kerberos的情况下,优先读取HADOOP_USER_NAME这个系统环境变量,如果不为空,那么拿它作username。否则,读取HADOOP_USER_NAME这个java环境变量。否则,从com.sun.security.auth.NTUserPrincipal或者com.sun.security.auth.UnixPrincipal的实例获取username。
如果以上尝试都失败,那么抛出异常LoginException("Can’t find user name")。
最终拿username构造org.apache.hadoop.security.User的实例添加到Subject中。

看完这一段,我明白了执行login.login的时候调用了hadoop里面的HadoopLoginModule方法,而关键是在commit方法里面,在这里优先读取HADOOP_USER_NAME系统环境变量,然后是java环境变量,如果再没有就从NTUserPrincipal等里面取。关键代码为:

  1. if (!isSecurityEnabled() && (user == null)) {

  2. String envUser = System.getenv(HADOOP_USER_NAME);

  3. if (envUser == null) {

  4. envUser = System.getProperty(HADOOP_USER_NAME);

  5. }

  6. user = envUser == null ? null : new User(envUser);

  7. }

OK,看到这里我的需求也就解决了,只要在系统的环境变量里面添加HADOOP_USER_NAME=hadoop(HDFS上的有权限的用户,具体看自己的情况),或者在当前JDK的变量参数里面添加HADOOP_USER_NAME这个Java变量即可。我的情况添加系统环境变量更方法。

如果是在Eclipse里面运行,修改完环境变量后,记得重启一下eclipse,不然可能不会生效。

解决办法

最终,总结下来解决办法大概有三种:

1、在系统的环境变量或java工程的变量里面添加HADOOP_USER_NAME,这个值具体等于多少看自己的情况,以后会运行HADOOP上的Linux的用户名。(修改完重启eclipse,不然可能不生效)

2、将当前系统的帐号修改为hadoop

3、使用HDFS的命令行接口修改相应目录的权限,hadoop fs -chmod 777 /user,后面的/user是要上传文件的路径,不同的情况可能不一样,比如要上传的文件路径为hdfs://namenode/user/xxx.doc,则这样的修改可以,如果要上传的文件路径为hdfs://namenode/java/xxx.doc,则要修改的为hadoop fs -chmod 777 /java或者hadoop fs -chmod 777 /,java的那个需要先在HDFS里面建立Java目录,后面的这个是为根目录调整权限。

我喜欢第一个方法。

转自:http://www.huqiwen.com/2013/07/18/hdfs-permission-denied/

使用第一种方法解决了该问题,相对于放开hadoop权限而言,该方法更好

转载于:https://blog.51cto.com/libangsen/1349553

HDFS客户端的权限错误:Permission denied相关推荐

  1. HDFS客户端的权限错误:Permission denied: user=Administrator, access=WRITE,....

    错误的详细描述如下: org.apache.hadoop.security.AccessControlException: org.apache.hadoop.security .AccessCont ...

  2. hadoop 权限错误 Permission denied: user=root, access=WRITE, inode=/:hdfs:super

    关于不能执行Hadoop命令 并报权限问题执行错误1.Permission denied: user=root, access=WRITE, inode="/":hdfs:supe ...

  3. nginx的权限问题(Permission denied)解决办法

    nginx的权限问题(Permission denied)解决办法 一个nginx带多个tomcat集群环境,老是报如下错误: failed (13: Permission denied) while ...

  4. linux的 su 错误 Permission denied 和 Incorrect pa...

    2019独角兽企业重金招聘Python工程师标准>>> su时出现的Permission denied 和 Incorrected password这两个错误,都是由su的权限引起的 ...

  5. macos系统中shell脚本权限不足Permission denied的问题

    今天安装IntelliJ IDEA时运行脚本遇到的一些问题,简单总结了一下 首先尝试运行脚本时一直报错:Permission denied 如下图: 于是我给sh脚本文件添加权限 chmod +x s ...

  6. spark读hive没有权限异常Permission denied

    sparkSQL读取hive库或表时提示没有权限异常 spark@h1:~$ spark-shell 20/03/08 13:29:35 WARN NativeCodeLoader: Unable t ...

  7. git pull 报错:权限不够 Permission denied (publickey)

    一.背景 在git 提交的时候,突然就行不通,一直报错: Permission denied (publickey). fatal: Could not read from remote reposi ...

  8. 【Linux】完美解决 nginx 的权限问题( Permission denied)

    问题描述 Linux安装nginx过程中,执行./confiture命令时,报错Permission denied(如图) 解决办法 nginx的目录都是root用户,所以执行命令时提升一下权限即可. ...

  9. ubuntu删除提示权限不够permission denied,以及cannot remove “file“,is a directory.

    最近在配置深度学习环境,但是不知怎么的装错了软件版本,而且文件夹还被上锁了,于是尝试了很多方法,提示"permission denied",以及"cannot remov ...

最新文章

  1. Python~爬虫~2(requests)
  2. Shell之/bin/bash脚本的基础实战
  3. TCP三次握手四次挥手 TCP/UDP区别
  4. WMI介绍及简单实际运用(二,Win32_Processor内容)
  5. php跳转到另外一个方法,PHP 页面跳转到另一个页面的多种方法方法总结
  6. python 模块 类 函数_Python17之函数、类、模块、包、库
  7. python中如何输出空格换行,python将文本中的空格替换为换行的方法
  8. 军用设备环境试验GJB150A-2009检测报告机构
  9. 微型计算机控制技术扫描,微型计算机控制技术(双色)
  10. java Swing+mysql实现的家庭收支管理系统(个人收支录入和查询)
  11. 常用应届生Java开发笔试面试题(更新中)
  12. Web 前端本地化(一)
  13. 会员积分系统设计 1 内容说明
  14. 全国失信被执行人黑名单信息查询API接口
  15. Kerberos鉴权后Spark程序连接Redis数据库,解决No Reachable node in cluster错误
  16. 10.cocos2d坐标系
  17. 1688图片搜索淘宝商品接口
  18. LiDAR点云处理软件
  19. 阿里大鱼:自自定短信模板
  20. Android8.0 安装apk

热门文章

  1. Thinkphp宅音乐html5在线音乐播放器
  2. 全网最新Redis结合Kaptcha实现验证码功能篇二(前后端分离)
  3. 接口定义【领域对象】
  4. .Net 4.0并行库实用性演练[1]
  5. Bootstrap3 价格滑动块 price range bootstrap-slider
  6. 15个带示例的jQuery滚动条插件
  7. Magento: 后台添加预览按钮 View product in frontend from Magento admin
  8. Swift中文教程(十七) 可选链
  9. WordPress 数据库操作WPDB对象($wpdb)用法详解
  10. jquery1.4 API 区别与更新中文版(beta)