HDFS权限(HDFS Permissions)指南

Posted 程序猿码码

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HDFS权限(HDFS Permissions)指南相关的知识,希望对你有一定的参考价值。

Apache Hadoop 2.9.0

请查看原文:http://hadoop.apache.org/docs/stable/hadoop-project-dist/hadoop-hdfs/HdfsPermissionsGuide.html

(如果转发,请标明出处)

本文另外参考了官网0.18的中文文档http://hadoop.apache.org/docs/r1.0.4/cn/hdfs_permissions_guide.html

概述

Hadoop分布式文件系统实现了一个和POSIX系统类似的文件和目录的权限模型。每个文件和目录有一个所有者(owner)和一个组(group)。文件或目录对其所有者、同组的其他用户以及所有其他用户分别有着不同的权限。对文件而言,当读取这个文件时需要有r权限,当写入或者追加到文件时需要有w权限。对目录而言,当列出目录内容时需要具有r权限,当新建或删除子文件或子目录时需要有w权限,当访问目录的子节点时需要有x权限。

不同于POSIX模型,由于没有可执行文件的概念,所以HDFS权限模型中的文件没有setuidsetgid位。对于目录而言作为简化,也没有setuidsetgid可以在目录上设置sticky bit,防止超级用户、目录所有者或文件所有者以外的任何人删除或移动目录中的文件对一个文件设置sticky bit是没有任何作用的。总的来说,文件或目录的权限就是它的模式(mode)。HDFS采用了Unix表示和显示模式的习惯,包括使用八进制数来表示权限。当新建一个文件或目录,它的所有者即客户进程的用户,它的所属组是父目录的组(BSD的规定)。

HDFS还为POSIX ACLs (Access Control Lists)提供了可选支持,以便为特定的命名用户或命名组使用更细粒度的规则来增强文件权限。本文档稍后将更详细地讨论ACLs

 

每个访问HDFS客户端进程的标识分为两个部分,分别是用户名和组名列表。每次客户端进程访问一个文件或目录fooHDFS都要对其进行权限检查,

① 如果用户即foo的所有者,则检查所有者的访问权限;

② 如果foo关联的组在组名列表中出现,则检查组用户的访问权限;

③ 否则检查foo其他用户的访问权限。

如果权限检查失败,则客户的操作会失败。

用户身份

Hadoop 0.22开始,Hadoop支持两种不同的操作模式来确定用户的身份,由hadoop.security.authentication属性指定

1) simple

在此操作模式中,客户端进程的标识由主机操作系统确定。在类似Unix的系统上,用户名相当于“whoami”

2) kerberos

Kerberized操作中,客户端进程的身份由其 Kerberos credentials确定。例如,在Kerberized环境中,用户可以使用kinit实用程序来获得Kerberosticket-granting-ticket (TGT),并使用klist来确定其当前principal。将Kerberos principal映射到HDFS用户名时,将删除除主组件之外的所有组件。例如,一principal  todd/foobar@CORP.COMPANY.COM将充当HDFS上的简单用户名todd 

 

无论操作模式如何,用户标识机制对于HDFS本身都是外部的。HDFS中没有提供用于创建用户身份、建立组或处理用户证书(credentials)的功能

Group Mapping

根据上面的描述,当一个用户名被确定后,组列表将由组映射服务确定,该服务是由 hadoop.security.group.mapping来配置的。更多细节请查看 Hadoop Groups Mapping

权限检查

每个HDFS操作都要求用户具有通过文件所有权、组成员资格或其他权限授予的特定权限(读取、写入和EXECUTE 的某种组合)。操作可以在路径的多个组件(而不仅仅是最终组件)上执行权限检查。此外,某些操作依赖于对路径所有者的检查。

所有操作都需要遍历访问。遍历访问要求对路径的所有现有组件(最终路径组件除外)具有EXECUTE权限。例如,对于访问/ foo / bar / baz的任何操作,调用方必须对// foo/ foo / bar具有EXECUTE 权限。

 

下表描述了HDFS对路径的每个组件执行的权限检查。

① Ownership: 是否需要检查调用者是否是目录的所有者。通常,更改所有权或者元数据的权限操作要求调用者是当前目录的所有者。

 

② Parent:请求路径的父目录。例如,对目录 /foo/bar/baz来说父目录是/foo/bar

③ Ancestor: 请求路径的上个现有组件。例如,对于路径/ foo / bar / baz,如果存在/ foo / bar,则祖先路径为/ foo / bar。如果/ foo存在,但/ foo / bar不存在则祖先路径为/ foo

 

④ Final: 请求路径的最终组件。例如,目录/foo/bar/baz最终路径组件是/foo/bar/baz

⑤ Sub-tree: 对于作为目录的路径,递归地指定目录本身及其所有子目录。例如,对于具有两个名为buzboo的子目录的路径/ foo / bar / baz,子树是/ foo / bar / baz/ foo / bar / baz / buz/ foo / bar / baz / boo

 


 

1) 仅当调用使用overwrite 选项并且路径上已经存在文件时,才需要在create 对最终路径组件进行WRITE 访问。

2) 如果设置了 sticky bit,则检查父目录上的WRITE 权限的任何操作也将检查所有权。

3) 调用setOwner以更改文件的拥有用户需要HDFS超级用户访问权限。更改组不需要HDFS超级用户访问权限,但调用者必须是文件的所有者和指定组的成员。

理解系统的实现

每次文件或目录操作都需要传递完整的路径名给NameNode,每一个操作都会对此路径做权限检查。客户框架会隐式地将用户身份和与NameNode的连接关联起来,从而减少改变现有客户端API的需求。经常会有这种情况,当对一个文件的某一操作成功后,之后同样的操作却会失败,这是因为文件或路径上的某些目录已经不复存在了。比如,客户端首先开始读一个文件,它向NameNode发出一个请求以获取文件第一个数据块的位置。但接下去的获取其他数据块的第二个请求可能会失败。另一方面,删除一个文件并不会撤销客户端已经获得的对文件数据块的访问权限。而权限管理能使得客户端对一个文件的访问许可在两次请求之间被收回。重复一下,权限的改变并不会撤销当前客户端对文件数据块的访问许可。

File System API的改变

如果权限检查失败,所有使用path参数的方法都将引发AccessControlException 

新增方法:

① public FSDataOutputStream create(Path f, FsPermission permission, boolean overwrite, int bufferSize, short replication, long blockSize, Progressable progress) throws IOException;

② public boolean mkdirs(Path f, FsPermission permission) throws IOException;

③ public void setPermission(Path p, FsPermission permission) throws IOException;

④ public void setOwner(Path p, String username, String groupname) throws IOException;

⑤ public FileStatus getFileStatus(Path f) throws IOException; 也会返回路径关联的所有者、组和模式属性

新建文件或目录的模式受配置参数umask的约束。当使用之前的 create(path, …) 方法(没有指定权限参数)时,新文件的模式是0666  & ^umask。当使用新的 create(path, permission, …)方法(指定了权限参数P)时,新文件的模式是P & ^umask & 0666。当使用先前的 mkdirs(path) 方法(没有指定 权限参数)新建一个目录时,新目录的模式是0777 & ^umask。当使用新的mkdirs(path, permission ) 方法(指定了权限参数P)新建一个目录时,新目录的模式是P & ^umask & 0777

Shell命令变更

新增操作:

① chmod [-R] mode file

只有文件的所有者或者超级用户才有权限改变文件模式。

② chgrp [-R] group file

使用chgrp命令的用户必须属于特定的组且是文件的所有者,或者用户是超级用户。

③ chown [-R] [owner][:[group]] file

文件的所有者的只能被超级用户更改。

④ ls file

⑤ lsr file

输出格式做了调整以显示所有者、组和模式。

超级用户

超级用户即运行NameNode 进程的用户。宽泛的讲,如果你启动了NameNode ,你就是超级用户。超级用户干任何事情,因为超级用户能够通过所有的权限检查。没有永久记号保留谁过去是超级用户;当NameNode 开始运行时,进程自动判断谁现在是超级用户。HDFS的超级用户不一定非得是NameNode 主机上的超级用户,也不需要所有的集群的超级用户都是一个。同样的,在个人工作站上运行HDFS的实验者,不需任何配置就已方便的成为了他的部署实例的超级用户。

另外,管理员可以用配置参数指定一组特定的用户,如果做了设定,这个组的成员也会是超级用户。

Web服务器

Web服务器的身份是一个可配置参数。NameNode 并没有真实用户的概念,但是Web服务器表现地就像它具有管理员选定的用户的身份(用户名和组)一样。除非这个选定的身份是超级用户,否则会有名字空间中的一部分对Web服务器来说不可见。

ACLs (Access Control Lists)

除了传统的POSIX权限模型之外,HDFS还支持POSIX  ACLs (Access Control Lists)ACLs可用于实现不同于用户和组的自然组织层次结构的权限要求。ACL提供了一种方法,可以为特定的命名用户或命名组设置不同的权限,而不仅仅是文件的所有者和文件的组。

默认情况下ACL的支持是禁用的,并且NameNode不允许创建ACLs。要启用对ACL的支持,请在NameNode 配置中将dfs.namenode.acls.enabled设置为true

一个ACL由一组ACL entries组成。每个ACL entry为特定用户或组命名,并授予或拒绝该特定用户或组的读取、写入和执行权限。例如:

    user::rw-

   user:bruce:rwx        #effective:r--

   group::r-x           #effective:r--

   group:sales:rwx       #effective:r--

   mask::r--

   other::r--

 

ACL entries 由类型、可选名称和权限字符串组成。为便于显示,' : '用作每个字段之间的分隔符。在此ACL示例中,文件所有者具有读-写访问权限,文件组具有读-执行访问权限,其他人具有读访问权限。到目前为止,这相当于将文件的权限位设置为654

此外,命名用户bruce 和命名组sales还有两个扩展ACL entries ,这两个条entries 都被授予了完全访问权限。mask是一个特殊的ACL entry ,用于筛选授予所有命名用户entries 和命名组entries以及未命名组entry的权限。在本示例中,mask仅具有读取权限,我们可以看到已相应地筛选了多个ACL entries 的有效权限。

每个ACL必须有一个mask。如果用户设置ACL的时候没有指定mask,那么通过计算所有entries的权限联合填充到mask来自动生成一个mask并插入。

在一个具有ACL的文件上运行chmod命令,将会改变mask的权限。由于mask用作筛选器,因此这有效地限制了所有扩展ACL entries 的权限,而不是仅更改组 entry可能丢失其他扩展ACL entries 

该模型还区分了“access ACL”“default  ACL”,前者定义了权限检查期间要强制执行的规则,后者定义了新子文件或子目录在创建期间自动接收的ACL entries 。例如:

   user::rwx

   group::r-x

   other::r-x

   default:user::rwx

   default:user:bruce:rwx          #effective:r-x

   default:group::r-x

   default:group:sales:rwx         #effective:r-x

   default:mask::r-x

   default:other::r-x

只有目录有默认的ACL,当一个文件或者子目录被创建时,它会自动的从父目录拷贝默认的ACL来作为自己的access ACL。一个新的子目录也将它复制到自己的默认ACL。这样,在创建新的子目录时,默认ACL将通过文件系统树的层次向下复制。

 

   新子级别的access ACL的确切权限将通过mode参数进行筛选。考虑到默认的umask 022,对于新目录来说,通常是755,新文件通常是644mode参数筛选未命名用户(文件所有者)的复制权限值,mask和其他的复制权限值。使用此特定示例ACL,并为该模式创建一个具有755的新子目录,此模式筛选对最终结果没有影响。但是,如果我们考虑为模式创建644的文件,则模式筛选将导致新文件的ACL接收未命名用户(文件所有者)的读写、mask的读取和其他用户的读取。此mask还意味着命名用户bruce 和命名组sales 的有效权限是只读

请注意,拷贝发生在创建新文件或子目录时。对父级默认ACL的后续更改不会更改现有子级。

默认ACL必须具有所有必需的最小ACL entries,包括未命名用户(文件所有者)、未命名组(文件组)和其他entries。如果用户在设置默认ACL时不提供这些entries之一,则通过从访问ACL复制相应的权限自动插入这些entries;如果没有访问ACL,则复制权限位。默认ACL还必须具有mask。如上所述,如果未指定mask,则通过计算掩码将过滤的所有entries上的权限联合来自动插入mask

当考虑具有ACL的文件时,权限检查算法将更改为

① 如果用户名与文件的所有者匹配,则测试所有者权限;

② 如果用户名与其中一个命名用户entries中的名称匹配,则测试这些权限,并通过mask权限进行筛选;

③ 如果文件组与组列表中的任何成员匹配,并且由mask筛选的这些权限授予访问权限,则使用这些权限

④ 如果有一个命名组entry 与组列表的成员匹配,并且由mask筛选的这些权限授予访问权限,则使用这些权限

⑤ 如果文件组或任何命名组entry 与组列表中的成员匹配,但这些权限中的任何一个都没有授予访问权限,则拒绝访问

⑥ 否则测试文件的其他权限。

最佳做法是依赖传统的权限位来实现大多数权限要求,并定义较少数量的ACLs以使用一些例外规则来扩充权限位。与只有权限位的文件相比,具有ACL的文件在NameNode 的内存中会增加额外开销。

ACLs File System API

新方法:

① public void modifyAclEntries(Path path, List<AclEntry> aclSpec) throws IOException;

② public void removeAclEntries(Path path, List<AclEntry> aclSpec) throws IOException;

③ public void public void removeDefaultAcl(Path path) throws IOException;

④ public void removeAcl(Path path) throws IOException;

⑤ public void setAcl(Path path, List<AclEntry> aclSpec) throws IOException;

⑥ public AclStatus getAclStatus(Path path) throws IOException;

ACLs Shell Commands

① hdfs dfs -getfacl [-R] <path>

显示文件和目录的Access Control Lists (ACLs) .如果目录有一个默认的ACL,则getfacl 也会显示默认的ACL

② hdfs dfs -setfacl [-R] [-b |-k -m |-x <acl_spec> <path>] |[--set <acl_spec> <path>]

设置文件和目录的 Access Control Lists (ACLs)

③ hdfs dfs -ls <args>

ls的输出将在具有ACL的任何文件或目录的权限字符串中附加一个“+”字符。

 

查看 File System Shell文档来获得这些命令的详细信息。

配置参数

① dfs.permissions.enabled = true

如果是 true,则打开前文所述的权限系统。如果是 false,权限检查 就是关闭的,但是其他的行为没有改变。这个配置参数的改变并不改变文件或目录的模式、所有者和组等信息。不管权限模式是开还是关,chmodchgrp  chownsetfacl  总是 会检查权限。这些命令只有在权限检查背景下才有用,所以不会有兼容性问题。这样,这就能让管理员在打开常规的权限检查之前可以可靠地设置文件的所有者和权限。

② dfs.web.ugi = webuser,webgroup

Web服务器使用的用户名。如果将这个参数设置为超级用户的名称,则所有Web客户就可以看到所有的信息。如果将这个参数设置为一个不使用的用户,则Web客户就只能访问到other”权限可访问的资源了。额外的组可以加在后面,形成一个用逗号分隔的列表。

③ dfs.permissions.superusergroup = supergroup

超级用户的组名。

④ fs.permissions.umask-mode = 0022

在创建文件和目录时使用umask。在配置文件中,可以使用十进制数18

⑤ dfs.cluster.administrators = ACL-for-admins

指定为ACL集群的管理员。这控制HDFS中,谁可以访问默认servlet

⑥ dfs.namenode.acls.enabled = true

设置为true以启用对ACLs (Access Control Lists)的支持。默认情况下,ACLs处于禁用状态。禁用ACL后,NameNode 将拒绝所有设置ACL的尝试。

 

------------全文完--------------------

 

备注:

模式: mode

 

 

 

 

 

 

 

 

 

 


以上是关于HDFS权限(HDFS Permissions)指南的主要内容,如果未能解决你的问题,请参考以下文章

hive client 登录报权限不足问题/tmp/hive on HDFS should be writable. Current permissions are: rwx------

hive client 登录报权限不足问题/tmp/hive on HDFS should be writable. Current permissions are: rwx------

hive 报错/tmp/hive on HDFS should be writable. Current permissions are: rwx--x--x

hadoop hdfs (java api)

hadoop用户认证--kerberos

客快物流大数据项目(三十五):CDH使用注意