我想代表另一个用户访问HDFS。我可以与下列应用尝试模拟用户访问HDFS时发生错误
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.security.UserGroupInformation;
import org.apache.log4j.Logger;
import org.apache.hadoop.fs.FSDataOutputStream;
import java.security.PrivilegedExceptionAction;
public class HDFSProxyTest {
public static void main (String[] args) throws Exception {
String hadoopConfigurationPath = "/etc/hadoop/conf/";
final Configuration hdfsConfiguration = new Configuration();
FileSystem localFileSystem = FileSystem.getLocal(hdfsConfiguration);
Path coreSitePath = new Path(hadoopConfigurationPath+"core-site.xml");
hdfsConfiguration.addResource(coreSitePath);
Path hdfsSitePath = new Path(hadoopConfigurationPath+"hdfs-site.xml");
hdfsConfiguration.addResource(hdfsSitePath);
UserGroupInformation.setConfiguration(hdfsConfiguration);
UserGroupInformation.loginUserFromKeytab("[email protected]", "/home/striim/striim1_client.keytab");
UserGroupInformation ugi =
UserGroupInformation.createProxyUser("joy", UserGroupInformation.getLoginUser());
FileSystem hadoopFileSystem =ugi.doAs(new PrivilegedExceptionAction<FileSystem>() {
public FileSystem run() throws Exception {
return FileSystem.get(hdfsConfiguration);
}
});
FSDataOutputStream fsDataOutputStream = hadoopFileSystem.create(new Path("/user/striim1/hdfsproxy.csv"));
fsDataOutputStream.write("This is niranjan!!! testing this\n".getBytes());
fsDataOutputStream.close();
hadoopFileSystem.close();
}
}
下面这个程序执行用户striim,我试图仿效超级用户striim1谁拥有Kerberos认证和喜悦想这是用户我正试图访问HDFS。
我最终遇到了这个例外。
2017-05-19 02:45:34,843 - WARN main org.apache.hadoop.util.NativeCodeLoader.<clinit> (NativeCodeLoader.java:62) Unable to load native-hadoop library for your platform... using builtin-java classes where applicable
Exception in thread "main" org.apache.hadoop.security.AccessControlException: Permission denied: user=joy, access=WRITE, inode="/user/striim1":striim1:striim1:drwxr-xr-x
at org.apache.hadoop.hdfs.server.namenode.DefaultAuthorizationProvider.checkFsPermission(DefaultAuthorizationProvider.java:281)
at org.apache.hadoop.hdfs.server.namenode.DefaultAuthorizationProvider.check(DefaultAuthorizationProvider.java:262)
at org.apache.hadoop.hdfs.server.namenode.DefaultAuthorizationProvider.check(DefaultAuthorizationProvider.java:242)
at org.apache.hadoop.hdfs.server.namenode.DefaultAuthorizationProvider.checkPermission(DefaultAuthorizationProvider.java:169)
at org.apache.sentry.hdfs.SentryAuthorizationProvider.checkPermission(SentryAuthorizationProvider.java:178)
at org.apache.hadoop.hdfs.server.namenode.FSPermissionChecker.checkPermission(FSPermissionChecker.java:152)
at org.apache.hadoop.hdfs.server.namenode.FSDirectory.checkPermission(FSDirectory.java:3560)
at org.apache.hadoop.hdfs.server.namenode.FSDirectory.checkPermission(FSDirectory.java:3543)
at org.apache.hadoop.hdfs.server.namenode.FSDirectory.checkAncestorAccess(FSDirectory.java:3525)
at org.apache.hadoop.hdfs.server.namenode.FSNamesystem.checkAncestorAccess(FSNamesystem.java:6592)
at org.apache.hadoop.hdfs.server.namenode.FSNamesystem.startFileInternal(FSNamesystem.java:2821)
at org.apache.hadoop.hdfs.server.namenode.FSNamesystem.startFileInt(FSNamesystem.java:2739)
at org.apache.hadoop.hdfs.server.namenode.FSNamesystem.startFile(FSNamesystem.java:2624)
at org.apache.hadoop.hdfs.server.namenode.NameNodeRpcServer.create(NameNodeRpcServer.java:599)
at org.apache.hadoop.hdfs.server.namenode.AuthorizationProviderProxyClientProtocol.create(AuthorizationProviderProxyClientProtocol.java:112)
at org.apache.hadoop.hdfs.protocolPB.ClientNamenodeProtocolServerSideTranslatorPB.create(ClientNamenodeProtocolServerSideTranslatorPB.java:401)
at org.apache.hadoop.hdfs.protocol.proto.ClientNamenodeProtocolProtos$ClientNamenodeProtocol$2.callBlockingMethod(ClientNamenodeProtocolProtos.java)
at org.apache.hadoop.ipc.ProtobufRpcEngine$Server$ProtoBufRpcInvoker.call(ProtobufRpcEngine.java:617)
at org.apache.hadoop.ipc.RPC$Server.call(RPC.java:1073)
at org.apache.hadoop.ipc.Server$Handler$1.run(Server.java:2141)
at org.apache.hadoop.ipc.Server$Handler$1.run(Server.java:2137)
at java.security.AccessController.doPrivileged(Native Method)
at javax.security.auth.Subject.doAs(Subject.java:422)
at org.apache.hadoop.security.UserGroupInformation.doAs(UserGroupInformation.java:1714)
at org.apache.hadoop.ipc.Server$Handler.run(Server.java:2135)
这是我的核心-site.xml中配置
<property>
<name>hadoop.proxyuser.striim1.hosts</name>
<value>*</value>
</property>
<property>
<name>hadoop.proxyuser.striim1.groups</name>
<value>*</value>
</property>
这是文件夹的权限设置,我试图访问
drwxr-xr-x - striim1 striim1 0 2017-05-19 02:50 /user/striim1
此异常导致我的以下问题
1)即使我将超级用户的UGI传递给代理用户喜悦。为什么客户端试图在用户喜悦的背景下创建文件?
2)在我的集群部署中,“striim1”只是具有Kerberos凭据的用户,并不是根据此definition确实是超级用户。仅当“striim1”是超级用户还是添加到超级用户组时,模拟才会起作用?
3)我试图模仿的用户的名字应该是一个有效的操作系统用户?如果不是会发生什么,在这方面做了什么验证?
4)我试图用这个模拟用户编写的目录的权限设置应该是什么?应该是它拥有的某个位置还是超级用户组的一部分?
5)应该在我的应用程序中明确调用UGI.createProxyUser?假设我从要使用超级用户模拟的用户执行我的应用程序,并将代理用户配置(基本上是通过core-site.xm)传递给我的应用程序?这足够吗? (我期待像createProxyUser这样的内容,通过将当前应用程序执行用户作为用户作为模拟来调用)。
在此先感谢。
问候,
NIRANJAN
这是一个很好的解释。我只是有这些后续问题 1)在一个不安全的环境中,除了具有模仿权限以外,真实用户还有什么作用? 5)在我想从一个应用程序代理多个用户的情况下,我必须明确调用UGI.createProxyUser()。 –
在5)我试着设置这个环境变量设置HADOOP_PROXY_USER =欢乐跑我的程序(注释掉这些行 /* UGI UGI = UGI.createProxyUser( “欢乐”,UGI.getLoginUser()); 文件系统HFS = UGI .doAs(新的PrivilegedExceptionAction(){ 公共文件系统的run(){ 回报FileSystem.get(CONF);} }); */ 但文件是使用用户创建striim1 -RW-R - R-- 3 striim1 striim1 33 2017-05-30 02:29 /user/striim1/hdfsproxynew.csv而不是快乐我在这里错过了什么吗? –
@NiranjanSubramanian,1)在一个不安全的环境中,真正的用户仍然被认为是成为认证用户。只是认证方法很薄弱,基本上只是通过纯文本识别用户名。 5)是的,这是正确的。只有当整个过程需要代理一个用户时,使用'HADOOP_PROXY_USER'才有用。尝试删除'UserGroupInformation#loginUserFromKeytab'调用,而不是在启动应用程序之前使用'kinit -kt'。如果仍然无法正常工作,请考虑跟踪我刚刚在解决问题答案底部关联的代码。 –