相容MIT Kerberos的身份認證方式

EMR叢集中Kerberos服務端啟動在master節點,涉及一些管理操作需在master節點(emr-header-1)的root帳號執行。

下面以test使用者訪問HDFS服務為例介紹相關流程。

  • Gateway上執行hadoop fs -ls /
    • 配置krb5.conf
      Gateway上面使用root帳號
       scp root@emr-header-1:/etc/krb5.conf /etc/
    • 添加principal
      • 登入叢集emr-header-1節點,切到root帳號。
      • 進入Kerberos的admin工具。
      •   sh /usr/lib/has-current/bin/hadmin-local.sh /etc/ecm/has-conf -k /etc/ecm/has-conf/admin.keytab
          HadminLocalTool.local: #直接按斷行符號可以看到一些命令的用法
          HadminLocalTool.local: addprinc #輸入命令按斷行符號可以看到具體命令的用法
          HadminLocalTool.local: addprinc -pw 123456 test #添加test的princippal,密碼設定為123456
    • 匯出keytab檔案

      使用Kerberos的admin工具可以匯出principal對應的keytab檔案。

      HadminLocalTool.local: ktadd -k /root/test.keytab test #匯出keytab檔案,後續可使用該檔案
    • kinit擷取Ticket

      在執行hdfs命令的用戶端機器上面,如Gateway。

      • 添加linux帳號test
        useradd test
      • 安裝MITKerberos 用戶端工具。

        可以使用MITKerberos tools進行相關操作(如kinit/klist等),詳細使用方式參考MITKerberos文檔

        yum install krb5-libs krb5-workstation -y
      • 切到test帳號執行kinit
              su test
              #如果沒有keytab檔案,則執行
              kinit #直接斷行符號
              Password for test: 123456 #即可
              #如有有keytab檔案,也可執行
              kinit -kt test.keytab test    
              #查看ticket
              klist
        说明 MITKerberos工具使用執行個體
    • 執行hdfs命令

      擷取到Ticket後,就可以正常執行hdfs命令了。

      hadoop fs -ls /
            Found 5 items
           drwxr-xr-x     - hadoop hadoop          0 2017-11-12 14:23 /apps
           drwx------      - hbase  hadoop           0 2017-11-15 19:40 /hbase
           drwxrwx--t+   - hadoop hadoop         0 2017-11-15 17:51 /spark-history
           drwxrwxrwt   - hadoop hadoop          0 2017-11-13 23:25 /tmp
           drwxr-x--t      - hadoop hadoop          0 2017-11-13 16:12 /user
      说明 跑yarn作業,需要提前在叢集中所有節點添加對應的linux帳號(詳見下文中[EMR叢集添加test帳號]。
  • java代碼訪問HDFS
    • 使用本地ticket cache
      说明 需要提前執行kinit擷取ticket,且ticket到期後程式會訪問異常。
      public static void main(String[] args) throws IOException {
         Configuration conf = new Configuration();
         //載入hdfs的配置,配置從emr叢集上複製一份
         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叢集上複製一份
        conf.addResource(new Path("/etc/ecm/hadoop-conf/hdfs-site.xml"));
        conf.addResource(new Path("/etc/ecm/hadoop-conf/core-site.xml"));
        //直接使用keytab檔案,該檔案從emr叢集master-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>2.7.2</version>
                  </dependency>
                  <dependency>
                      <groupId>org.apache.hadoop</groupId>
                      <artifactId>hadoop-hdfs</artifactId>
                      <version>2.7.2</version>
                  </dependency>
              </dependencies>