本文通过访问HDFS服务为您介绍如何使用HAS Kerberos认证。
前提条件
已创建EMR-3.40及之前版本,EMR-4.10.1及之前版本的Hadoop集群,详情请参见创建集群。
通过hadoop命令访问HDFS
以test用户访问HDFS服务为例介绍。
- 在Gateway节点配置krb5.conf文件。
scp root@emr-header-1:/etc/krb5.conf /etc/
- 配置hadoop.security.authentication.use.has的值为false。
- 添加Principal。
- 获取Ticket。 在待执行HDFS命令的客户端机器上执行命令,本文以Gateway节点为例介绍。
- 在Gateway节点上执行以下命令,导入环境变量。
export HADOOP_CONF_DIR=/etc/has/hadoop-conf
- 执行HDFS命令。
hadoop fs -ls /
返回如下类似信息。Found 6 items drwxr-xr-x - hadoop hadoop 0 2021-03-29 11:16 /apps drwxrwxrwx - flowagent hadoop 0 2021-03-29 11:18 /emr-flow drwxr-x--- - has hadoop 0 2021-03-29 11:16 /emr-sparksql-udf drwxrwxrwt - hadoop hadoop 0 2021-03-29 11:17 /spark-history drwxr-x--- - hadoop hadoop 0 2021-03-29 11:16 /tmp drwxrwxrwt - hadoop hadoop 0 2021-03-29 11:17 /user
通过Java代码访问HDFS
- 使用本地ticket cache 说明 需要提前执行kinit获取ticket,且ticket过期后程序会访问异常。
public static void main(String[] args) throws IOException { Configuration conf = new Configuration(); //加载hdfs的配置,需要从EMR集群上复制hdfs的配置。 conf.addResource(new Path("/etc/ecm/hadoop-conf/hdfs-site.xml")); conf.addResource(new Path("/etc/ecm/hadoop-conf/core-site.xml")); //需要在Linux账号下,提前通过kinit获取ticket。 UserGroupInformation.setConfiguration(conf); UserGroupInformation.loginUserFromSubject(null); FileSystem fs = FileSystem.get(conf); FileStatus[] fsStatus = fs.listStatus(new Path("/")); for(int i = 0; i < fsStatus.length; i++){ System.out.println(fsStatus[i].getPath().toString()); } }
- 使用keytab文件(推荐) 说明 keytab长期有效,跟本地ticket无关。
public static void main(String[] args) throws IOException { String keytab = args[0]; String principal = args[1]; Configuration conf = new Configuration(); //加载hdfs的配置,需要从EMR集群上复制hdfs的配置。 conf.addResource(new Path("/etc/ecm/hadoop-conf/hdfs-site.xml")); conf.addResource(new Path("/etc/ecm/hadoop-conf/core-site.xml")); //直接使用keytab文件,该文件从EMR集群emr-header-1上执行相关命令获取。 UserGroupInformation.setConfiguration(conf); UserGroupInformation.loginUserFromKeytab(principal, keytab); FileSystem fs = FileSystem.get(conf); FileStatus[] fsStatus = fs.listStatus(new Path("/")); for(int i = 0; i < fsStatus.length; i++){ System.out.println(fsStatus[i].getPath().toString()); } }
pom依赖如下所示。<dependencies> <dependency> <groupId>org.apache.hadoop</groupId> <artifactId>hadoop-common</artifactId> <version>x.x.x</version> </dependency> <dependency> <groupId>org.apache.hadoop</groupId> <artifactId>hadoop-hdfs</artifactId> <version>x.x.x</version> </dependency> </dependencies>
说明x.x.x
为您集群的hadoop版本。