本文通過訪問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版本。