本文通過訪問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。
- 執行如下命令,進入Kerberos的admin工具。
- EMR-3.30.0及後續版本和EMR-4.5.1及後續版本:
sh /usr/lib/has-current/bin/admin-local.sh /etc/ecm/has-conf -k /etc/ecm/has-conf/admin.keytab - EMR-3.30.0之前版本和EMR-4.5.1之前版本:
sh /usr/lib/has-current/bin/hadmin-local.sh /etc/ecm/has-conf -k /etc/ecm/has-conf/admin.keytab
- EMR-3.30.0及後續版本和EMR-4.5.1及後續版本:
- 執行如下命令,添加test的Principal。
本樣本密碼設定為123456。
addprinc -pw 123456 test - 執行如下命令,匯出keytab檔案。
ktadd -k /root/test.keytab test
- 執行如下命令,進入Kerberos的admin工具。
- 擷取Ticket。 在待執行HDFS命令的用戶端機器上執行命令,本文以Gateway節點為例介紹。
- 添加Linux帳號test。
useradd test - 安裝MIT Kerberos用戶端工具。
您可以使用MITKerberos工具進行相關操作(例如,kinit和klist),詳情請參見MIT Kerberos。
yum install krb5-libs krb5-workstation -y - 切到test帳號執行kinit。
su test- 如果沒有keytab檔案,則執行
kinit,斷行符號後輸入test的密碼123456。 - 如果有keytab檔案,則執行如下命令。
#使用指定Keytab檔案中的指定Principal進行認證。 kinit -kt test.keytab test #查看ticket的生命週期。 klist執行klist,斷行符號後輸入test的密碼123456。返回類似如下資訊:Valid starting Expires Service principal 03/30/2021 10:48:47 03/31/2021 10:48:47 krbtgt/EMR.209749.COM@EMR.209749.COM renew until 03/31/2021 10:48:47
- 如果沒有keytab檔案,則執行
- 可選:如果需要設定ticket的生命週期,您可以執行如下操作:
- 設定ticket的生命週期。
kinit -l 5d - 執行
klist命令,查看ticket的生命週期。Valid starting Expires Service principal 03/30/2021 10:50:51 04/04/2021 10:50:51 krbtgt/EMR.209749.COM@EMR.209749.COM renew until 04/01/2021 10:50:51
- 設定ticket的生命週期。
- 添加Linux帳號test。
- 在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版本。