全部產品
Search
文件中心

E-MapReduce:HAS Kerberos認證使用方法

更新時間:Jul 01, 2024

本文通過訪問HDFS服務為您介紹如何使用HAS Kerberos認證。

前提條件

已建立EMR-3.40及之前版本,EMR-4.10.1及之前版本的Hadoop叢集,詳情請參見建立叢集

通過hadoop命令訪問HDFS

以test使用者訪問HDFS服務為例介紹。

  1. 在Gateway節點配置krb5.conf檔案。
    scp root@emr-header-1:/etc/krb5.conf /etc/
  2. 配置hadoop.security.authentication.use.has的值為false
    1. 登入叢集的emr-header-1節點。
      說明 HA叢集也需要登入emr-header-1節點。

      登入詳情請參見登入叢集

    2. 執行以下命令,編輯core-site.xml檔案。
      vim /etc/ecm/hadoop-conf/core-site.xml
    3. 查看hadoop.security.authentication.use.has的值。
      • 如果值為true,修改hadoop.security.authentication.use.has的值為false
      • 如果值為false,直接執行步驟3
  3. 添加Principal。
    1. 執行如下命令,進入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
    2. 執行如下命令,添加test的Principal。

      本樣本密碼設定為123456。

      addprinc -pw 123456 test
    3. 執行如下命令,匯出keytab檔案。
      ktadd -k /root/test.keytab test
  4. 擷取Ticket。
    在待執行HDFS命令的用戶端機器上執行命令,本文以Gateway節點為例介紹。
    1. 添加Linux帳號test。
      useradd test
    2. 安裝MIT Kerberos用戶端工具。

      您可以使用MITKerberos工具進行相關操作(例如,kinit和klist),詳情請參見MIT Kerberos

      yum install krb5-libs krb5-workstation -y
    3. 切到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
    4. 可選:如果需要設定ticket的生命週期,您可以執行如下操作:
      1. 設定ticket的生命週期。
        kinit -l 5d
      2. 執行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
  5. 在Gateway節點上執行以下命令,匯入環境變數。
    export HADOOP_CONF_DIR=/etc/has/hadoop-conf
  6. 執行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版本。