本文固定链接:https://www.askmac.cn/archives/hadoop-permissions-guide.html
本文是官方文档的翻译,原文地址是:
http://hadoop.apache.org/docs/current/hadoop-project-dist/hadoop-hdfs/HdfsPermissionsGuide.html
1.概述
HDFS为文件和目录实现了一个权限模块,一大部分共享是POSIX模式。每个文件和目录关联到一个用户和一个组。文件和目录以用户所有者来权限划分,其他的用户可以是一个组的成员,也可以是所有其他的用户。对于文件来说,r 权限是读文件的权限,w 权限是写或者追加到文件的权限。对于目录来说,r权限是列出目录内容的权限,w权限是删除和创建文件或目录的权限,x权限是访问子目录的权限。
于POSIX模式对比,文件没有setuid或setgid位,因为没有可执行文件的概念。同样地,对于目录也没有setuid和setgid位。粘贴位可以被设置在目录上,可以防止除了超级用户之外,目录所有者或文件所有者在这个目录中删除或移动文件。在文件上设置粘贴位没有作用。总的来说,一个文件或目录的权限是它们的模式。一般来说,Unix用户的表现模式将被使用,包括这个表述上的8进制方法。当文件或目录被创建,它们的所有者是客户端进程的标识,它们的组时父目录的组(BSD规则)。
HDFS也提供了POSIX ACLs(访问控制列表)支持,来增加对特定命名用户或命名组的更细粒度规则的文件权限。ACLs在后面有更详细的讨论(www.askmac.cn)。
每个客户端进程访问HDFS拥有2部分标识:用户名和组列表。当文件和目录被一个客户端进程访问时,HDFS必须进行权限检查。
- 如果用户名匹配所有者,那么所有者权限是通过的。
- 如果组权限匹配组列表中任何一个成员,那么组权限是通过的。
- 否则,其他权限是通过的。
如果权限检查失败,客户端操作就失败。
2. 用户身份
在hadoop 0.22中,Hadoop支持2种不同的模式的操作决定用户的身份,通过指定hadoop.security.authentication 属性:
- simple
在这个模式操作中,客户端进程的身份被主机操作系统决定。在类unix系统中,用户名等价于`whoami`
- kerberos
在这个操作中,客户端进程的身份被Kerberos凭据决定。例如,在一个Kerber环境中,一个用户可能使用kinit工具来包含一个kerberos 门票(TGT)和使用klist来决定它们当前的负责人。当映射一个kerberos负责人到一个HDFS用户名时,所有除了主组件之外的都被删除。例如一个 负责人 todd/[email protected],将作为HDFS上一个简单的命名todd
不管是什么操作模式,用户身份是HDFS本身的一个机制。没有规定HDFS来创建用户身份,建立组或处理用户凭据(www.askmac.cn)。
3.组映射
一旦一个用户名被上面所描述的决定,组类表会被一个组映射服务决定,被hadoop.security.group.mapping属性配置。默认实现了org.apache.hadoop.security.JniBasedUnixGroupsMappingWithFallback,将决定JNI是可用的。如果JNI可用,那么这个实现将使用hadoop的API来解决一个用户的组列表。如果JNI不可用,那么shell实现org.apache.hadoop.security.ShellBasedUnixGroupsMapping 将被使用。其使用bash -c groups命令(linux/unix环境)或者net group命令(windows环境)来在shell中解决一个用户的组列表
一个替代的实现,是直接连接一个LDAP服务来解决组列表,其通过org.apache.hadoop.security.LdapGroupsMapping可用。但是,这个只能在当需求的组在LDAP中唯一存在时使用,并且不会被unix 服务实现。更多关于组映射服务的配置和可参考javadoc。
对于HDFS,在NameNode上执行用户到组的映射。因此,NameNode主机系统配置决定了用户的组映射。
注意HDFS作为配置存储了文件或目录的用户和组;在常规的unix中,用户和组身份号是没做过转换的(www.askmac.cn)。
4.理解和实现
每个文件或目录操作传递全路径名称到 namenode,并且在每个操作的路径上进行权限检查。客户端框架将隐式的关联用户身份到namenode,减少对现有客户端API的更改。这是很常见的场景,当一个操作在一个文件上成功时,下一次操作可能由于文件或者路径已经不存在而失败。例如,当客户端第一次开始读一个文件,其会进行第一次请求namenode来发现文件第一个块的位置。第二次请求来发现其他块可能失败。另一方面,删除一个文件不会撤销已经被客户端知道的文件块的访问。加上权限,一个客户端访问一个文件在请求之前就可能撤回。另外,变更权限不会撤销已经知道文件块的客户端访问权限。
5. 对文件系统API的更改
所有方法使用一个路径参数,如果权限检查失败会报出一个访问控制异常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;将额外返回关于路径的用户,组模式(www.askmac.cn)。
一个新文件或者目录的模式被一个配置参数 unmash设置所限制。当现有的create(path,…)方法(没有权限参数)被使用,新文件的模式是0666&^ unmak。当新create(path,permission,…)方法(有权限参数P)被使用时,新文件的模式是P&^unmask&0666。当新目录是被现有的mkdirs(path)方法(没有权限参数)创建,目录的模式是0777&^unmask。当新目录是被现有的mkdirs(path,permission)方法(有权限参数P)创建,目录的模式是P&^unmask&0777.
6. 应用程序shell变更
新操作:
- chmod [-R] 模式 文件 …
只有文件的所有者或者超级用户可以变更这个文件的模式
- chgrp [-R] 组 文件…
调用chgrp的用户必须属于指定的组中,并且是文件的所有者或者超级用户(www.askmac.cn)。
- chown [-R] [owner][:[group]] 文件….
只有超级用户才能修改文件的所有者
- ls 文件…
- lsr 文件…
格式化输出,显示所有者,组和模式。
7. 超级用户
超级用户是在name node进程上也有相同身份的用户。简单来说,如果你启动了namenode,那么你就是超级用户。超级用户可以做任何事情,并且超级用户在权限检查上不会失败。这里没有明确的概念说明谁是超级用户;name node启动的的进程身份决定当前谁是超级用户。HDFS超级用户并不是name node主机行的超级用户,集群上也不是必须要有相同的超级用户。同时,实验者在个人机器上,可以方便的安装并成为超级用户,而不需要任何配置。
除此之外,管理员可以通过一个配置参数明确标识为一个组。如果设置了,那么这个组里面所有的成员都是超级用户(www.askmac.cn)。
8.WEB服务器
默认情况下,WEB服务的身份被参数配置。也就是name node并没有真正用户身份的概念,但是WEB服务表现出其有身份(用户和组),通过管理员的用户选择、除非选择的身份和超级用户匹配,否则部分name space可能无法访问web服务器
9. ACLS(访问控制列表)
除了传统的POSIX权限模型,HDFS也支持POSIX ACLs(访问控制列表)。ACLs于用户组和组的自然层级组织不同,可以很容易的实现权限需求。一个ACL提供了对于指定用户和组名称,设置不同权限的方式,不仅仅是文件的所有者和文件的组。
默认情况下,ACLs支持是禁用的,并且NameNode不允许创建ACLs。为了启用ACLs支持,要在namenode配置中设置dfs.namenode.acls.enabled为true。
一个ACL由一系列ACL设置条目组成。每个ACL条目指定特定的用户或组,并授予或拒绝读,写和执行特定用户或组的权限。例如(www.askmac.cn):
user::rw- user:bruce:rwx #effective:r-- group::r-x #effective:r-- group:sales:rwx #effective:r-- mask::r-- other::r--
ACL条目包含类型,可选名称和权限字符串。在上面显示的例子中,”:”被用来作为区域的分隔符。在这个ACL例子中,文件的所有者有读写权限,文件的组由读-执行权限,其他的有读权限。到目前为止,这个等价于设置文件权限位为654。
此外,有2个额外的条目,对于名称为bruce的用户和名称为sales的组,这2这都有所有权限。mask是一个单独的ACL条目,用来过滤所有有名称的用户条目,组条目和未命名组条目。在这个例子中,mask只用读权限,我们可以看到实际这些ACL条目有效权限被相应的过滤。
每个ACL必须有一个mask。如果用户在设置一个ACL时没有提供一个mask,那么会自动的计算所有条目权限的集合,来自动的增加一个mask来进行过滤。
在一个有ACL的文件上运行chmod会实际的变更mask权限。因此,mash作为一个过滤器,其有效地约束了所有拓展的ACL条目,而不是只换组条目和可能丢失其他拓展ACL条目。
这个模式也分为“access ACL”,定义了在权限检查中执行的规则,和“default ACL ”,定义了ACL条目在新的子文件或者子目录在创建的时候,自动接受。例如(www.askmac.cn):
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
只有目录可以有一个default ACL。当一个新文件或子目录被创建,其自动的拷贝其父项的默认ACL作为自身的 访问ACL。一个新的子目录也拷贝其作为其自身的default ACL。在这种方式下,default ACL将通过任意层次的文件系统新子目录创建的树进行传递。
在新的子访问ACL中的精确权限值,都受到模式参数的过滤。考虑默认的umask是022,这使得通常创建的新目录为755,文件为644.这个模式参数过滤从未命名的用户(文件所有制),掩码和其他中拷贝的权限值。在这个实际的ACL例子中,创建一个新子目录为755模式,这个模式过滤唯有影响到最终的结果。但是,如果我们考虑创建一个文件是644模式,那么模式过滤会导致新文件的ACL从未命名的用户(文件所有者)接收读写权限,从mask接收读权限,从其他接收读权限。这个mask也意味着,对于名称为bruce和名称为sales的组实际上只有读权限。
注意到复制发生在创建一个新文件或子目录时。随后对父项默认ACL的变更不会改变现有的子项(www.askmac.cn)。
默认的ACL必须有所有最小需求的ACL条目,包括未命名的用户(文件所有者),未命名的组(文件组)和其他的条目。当设置一个默认的ACL时,如果用户不提供这些条目,那么这些条目会自动的从相应的访问ACL中拷贝,如果没有访问ACL则从权限位中插入。默认的ACL也必须有mask。如上所诉,如果mask未指定,那么mask会自动的通过所有的条目的联合,自动的计算出值,用来进行过滤。
当考虑一个文件有ACL时,权限检查算法变更为:
- 如果用户名称和文件所有者匹配,那么所有者权限通过;
- 如果用户名匹配到用户条目中的一个,那么这些权限通过,并被mask权限过滤。
- 如果文件的组名称(或者组名称条目)匹配到组列表中任意一个,并且如果这些权限通过了mask过滤,那么这些权限被使用;
- 如果文件的组或者任何组条目匹配到组列表中任意一个,但是这些权限并未被任何权限授予,这些权限被否认;
- 否则文件的其他权限通过。
最佳实践是依靠传统的权限位来实现大部分的权限需求,定义少量的ACLs来增强那些权限位之外的规则。对比那些文件中只有权限位的,AL文件会在NameNode内存成本上带来额外的开销(www.askmac.cn)。
10. ACLS文件系统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;
11. ACLs shell 命令
- hdfs dfs -getfacl [-R] <patch>
列出文件和目录的ACLs。如果一个目录有默认ACL,其也会列出默认ACL。
- hdfs dfs -setfacl [-R] [-b |-k -m |-x <acl_spec> <path>] |[–set <acl_spec> <path>]
设置文件和目录的ACLs
- hdfs dfs -ls <args>
ls 输出中会将任何有ACL的通过”+”号字符串来显示(www.askmac.cn)
参考文件系统shell命令文件来查看所有命令的参数用法
12. 配置参数
- dfs.permissions.enabled = true
如果是true表明使用权限系统。如果不是,权限检查将关闭,但是所有其他的行为不会发生变化。变更参数的值不会变更文件或目录的模式,所有者和组。不管权限开启或关闭,chmod,chgrp,chown和setfacl总是检查权限。这些功能只能权限上下文中有用,所有没有向后兼容性的问题。此外,这使得管理员在打开常规权限检查之前,能够可靠地设置所有者和权限。
- dfs.web.ugi = webuser,webgroup
这个用户名被web服务器使用。设置此名称的超级用户允许web客户端可以看到一切。将此变更为其他未使用的身份,允许网络客户点只能看到其他权限可见的东西。附加组可以添加到逗号分隔的列表中。
- dfs.permissions.superusergroup = supergroup
超级用户的组名
- fs.permissions.umask-mode = 0022
在创建文件和目录时被使用的umask。对于配置文件,可以使用十进制 18.
- dfs.cluster.administrators = ACL-for-admins
集群中ACL的管理员。这个控制了HDFS中谁可以访问默认的servlets。
- dfs.namenode.acls.enabled = true
设置为true表示HDFS支持ACLs。默认情况下,ACLs是禁用的。当ACLs被禁用,NameNode会拒绝所有试图设置ACL的操作。
Leave a Reply