適用於: Windows 上的 SQL Server 2016(13.x)及更新版本
若要在使用 PolyBase 搭配 Kerberos 保護的 Hadoop 叢集時,排除認證問題,請使用 PolyBase 內建的互動式診斷功能。
本文提供指南,協助你透過這些內建診斷工具,逐步了解此類問題的除錯流程。
提示
當在 Kerberos 保護的 HDFS 叢集中建立外部表格時遇到 HDFS Kerberos 失敗,除了遵循本指南中的步驟外,您也可以選擇執行 HDFS Kerberos 測試器,以針對 PolyBase 的 HDFS Kerberos 連線進行疑難排解。
此工具有助於排除非 SQL Server 問題,幫助你專注於解決 HDFS Kerberos 設定問題,特別是識別使用者名稱/密碼錯誤設定問題,以及叢集 Kerberos 設定錯誤問題。
此工具獨立於 SQL Server。 它以 Jupyter Notebook 的形式提供,需要 Azure Data Studio。
必要條件
SQL Server 2016 (13.x) RTM CU6/SQL Server 2016 (13.x) SP1 CU3/SQL Server 2017 (14.x) 或更新版本,且已安裝 PolyBase
受 Kerberos (Active Directory 或 MIT) 保護的 Hadoop 叢集 (Cloudera 或 Hortonworks)
簡介
這會協助您初步了解 Kerberos 通訊協定的概要。 涉及三位演員:
- Kerberos 用戶端 (SQL Server)
- 受保護的資源 (HDFS、MR2、YARN 以及作業記錄等等)
- 金鑰發佈中心 (在 Active Directory 中稱為網域控制站)
當你在 Hadoop 叢集上設定 Kerberos 時,你會在金鑰分發中心(KDC)註冊每個 Hadoop 安全資源,並以獨特的服務主體名稱(SPN)註冊。 客戶端需要取得一份臨時使用者票證,稱為票證簽發票證(TGT),以便向金鑰發行中心(KDC)申請另一張臨時票證,稱為服務票證(Service Ticket, ST),以便訪問其想要存取的特定服務主體名稱(SPN)。
在 PolyBase 中,當你請求對任何 Kerberos 保護的資源進行認證時,會進行以下四次往返握手:
SQL Server 連接到 KDC,並為使用者取得 TGT。 KDC 私鑰會加密 TGT。
SQL Server 呼叫 Hadoop 的受保護資源 (HDFS),並判斷出需要 ST 的 SPN。
SQL Server 回到 KDC,並傳回 TGT,然後要求 ST 以存取該特定的受保護資源。 安全服務的私鑰會加密 ST。
SQL Server 將 ST 轉送至 Hadoop,並完成驗證以對該服務建立工作階段。
認證問題屬於前述步驟之一或多項。 為了加快除錯速度,PolyBase 提供整合診斷工具,協助找出故障點。
疑難排解
PolyBase 使用以下設定 XML 檔案來儲存 Hadoop 叢集的屬性:
core-site.xmlhdfs-site.xmlhive-site.xmljaas.confmapred-site.xmlyarn-site.xml
您可以在以下路徑中找到這些檔案:
[System Drive]:{install path}{MSSQL##.INSTANCENAME}\MSSQL\Binn\PolyBase\Hadoop\conf
例如,SQL Server 2016(13.x)的預設路徑是 C:\Program Files\Microsoft SQL Server\MSSQL13.MSSQLSERVER\MSSQL\Binn\PolyBase\Hadoop\conf。
編輯 core-site.xml 並新增這些屬性。 根據你的環境設定數值:
<property>
<name>polybase.kerberos.realm</name>
<value>CONTOSO.COM</value>
</property>
<property>
<name>polybase.kerberos.kdchost</name>
<value>kerberos.contoso.com</value>
</property>
<property>
<name>hadoop.security.authentication</name>
<value>KERBEROS</value>
</property>
注意
屬性值 polybase.kerberos.realm 必須全部大寫。
如果你想啟用推下操作,就需要更新其他 XML 檔案。 你只要設定好這個檔案,就能存取 HDFS 檔案系統。
這個工具獨立於 SQL Server 執行,所以不需要持續執行。 如果你更新設定的 XML 檔案,其實不需要重啟它。 若要執行此工具,請在安裝 SQL Server 的主機上執行下列命令:
cd C:\Program Files\Microsoft SQL Server\MSSQL13.MSSQLSERVER\MSSQL\Binn\PolyBase
java -classpath ".\Hadoop\conf;.\Hadoop\*;.\Hadoop\HDP2_2\*" com.microsoft.polybase.client.HdfsBridge {Name Node Address} {Name Node Port} {Service Principal} {Filepath containing Service Principal's Password} {Remote HDFS file path (optional)}
在 SQL Server 2019(15.x)及之後版本中,安裝 PolyBase 功能時,你可以參考現有的 Java 執行環境,或安裝 AZUL-OpenJDK-JRE。 如果你選擇 AZUL-OpenJDK-JRE, java.exe 它不屬於 $PATH 環境變數,可能會遇到錯誤
'java' isn't recognized as an internal or external command, operable program or batch file.
如果發生這個錯誤,你需要將路徑 加入 java.exe$PATH session 環境變數。 Java 執行檔的預設安裝路徑為 C:\Program Files\Microsoft SQL Server\MSSQL15.<instance name>\AZUL-OpenJDK-JRE\bin。 如果是那條路徑,那麼你需要先執行以下指令,再執行 java 指令來運行 Kerberos 連線故障排除工具。
set PATH=%PATH%;C:\Program Files\Microsoft SQL Server\MSSQL15.{instance name}\AZUL-OpenJDK-JRE\bin
引數
| Argument | 描述 |
|---|---|
| 名稱節點位址 | 名稱節點的 IP 或 FQDN。 它指的是你 CREATE EXTERNAL DATA SOURCE Transact-SQL 中的「LOCATION」參數。
注意:SQL Server 2019 版本的工具必須 hdfs:// 置於 IP 或 FQDN 之前。 |
| 名稱節點埠 | 名稱節點的連接埠。 這會參考 CREATE EXTERNAL DATA SOURCE T-SQL 中的 "LOCATION" 引數。 例如,8020。 |
| 服務主體 | KDC 的管理服務主體。 這會與 CREATE DATABASE SCOPED CREDENTIAL T-SQL 中的 "IDENTITY" 引數相符。 |
| 服務密碼 | 將密碼儲存在檔案中,並將檔案路徑傳遞至此處,而不在主控台鍵入密碼。 檔案內容應該要與您在 CREATE DATABASE SCOPED CREDENTIAL T-SQL 之 "SECRET" 引數中使用的值相符。 |
| 遠端 HDFS 檔案路徑 (選擇性) | 所要存取之現有檔案的路徑。 若未指定,則使用根資料夾(/)。 |
範例
java -classpath ".\Hadoop\conf;.\Hadoop\*;.\Hadoop\HDP2_2\*" com.microsoft.polybase.client.HdfsBridge 10.193.27.232 8020 admin_user C:\temp\kerberos_pass.txt
輸出內容冗長,方便除錯,但無論你用的是 MIT 還是 AD,只有四個主要檢查點需要注意。 它們對應於前面提到的四個步驟。
下列摘要來自 MIT KDC。 請參閱本文相關 內容末尾 MIT 與 AD 的完整範例輸出。
檢查點 1
應該要有 Server Principal = krbtgt/MYREALM.COM@MYREALM.COM 的票證十六進位傾印。 這表示 SQL Server 已成功對 KDC 進行驗證,並已收到 TGT。 如果沒有,表示問題僅發生在 SQL Server 與 KDC 之間,而非 Hadoop。
PolyBase 不支援 AD 與 MIT 之間的信任關係,且必須與 Hadoop 叢集相同的 KDC 進行配置。 在此類環境中,手動建立該 KDC 的服務帳號,並用來進行驗證。
>>> KrbAsReq creating message
>>> KrbKdcReq send: kdc=kerberos.contoso.com UDP:88, timeout=30000, number of retries =3, #bytes=143
>>> KDCCommunication: kdc=kerberos.contoso.com UDP:88, timeout=30000,Attempt =1, #bytes=143
>>> KrbKdcReq send: #bytes read=646
>>> KdcAccessibility: remove kerberos.contoso.com
>>> EType: sun.security.krb5.internal.crypto.Des3CbcHmacSha1KdEType
>>> KrbAsRep cons in KrbAsReq.getReply myuser
[2017-04-25 21:34:33,548] INFO 687[main] - com.microsoft.polybase.client.KerberosSecureLogin.secureLogin(KerberosSecureLogin.java:97) - Subject:
Principal: admin_user@CONTOSO.COM
Private Credential: Ticket (hex) =
0000: 61 82 01 48 30 82 01 44 A0 03 02 01 05 A1 0E 1B a..H0..D........
0010: 0C 41 50 53 48 44 50 4D 53 2E 43 4F 4D A2 21 30 .CONTOSO.COM.!0
0020: 1F A0 03 02 01 02 A1 18 30 16 1B 06 6B 72 62 74 ........0...krbt
0030: 67 74 1B 0C 41 50 53 48 44 50 4D 53 2E 43 4F 4D gt..CONTOSO.COM
0040: A3 82 01 08 30 82 01 04 A0 03 02 01 10 A1 03 02 ....0...........
*[...Condensed...]*
0140: 67 6D F6 41 6C EB E0 C3 3A B2 BD B1 gm.Al...:...
Client Principal = admin_user@CONTOSO.COM
Server Principal = krbtgt/CONTOSO.COM@CONTOSO.COM
*[...Condensed...]*
[2017-04-25 21:34:34,500] INFO 1639[main] - com.microsoft.polybase.client.HdfsBridge.main(HdfsBridge.java:1579) - Successfully authenticated against KDC server.
檢查點 2
PolyBase 嘗試存取 HDFS 但因請求未包含必要的服務票而失敗。
[2017-04-25 21:34:34,501] INFO 1640[main] - com.microsoft.polybase.client.HdfsBridge.main(HdfsBridge.java:1584) - Attempting to access external filesystem at URI: hdfs://10.193.27.232:8020
Found ticket for admin_user@CONTOSO.COM to go to krbtgt/CONTOSO.COM@CONTOSO.COM expiring on Wed Apr 26 21:34:33 UTC 2017
Entered Krb5Context.initSecContext with state=STATE_NEW
Found ticket for admin_user@CONTOSO.COM to go to krbtgt/CONTOSO.COM@CONTOSO.COM expiring on Wed Apr 26 21:34:33 UTC 2017
Service ticket not found in the subject
檢查點 3
第二個十六進位傾印顯示 SQL Server 成功使用 TGT,並從 KDC 取得名稱節點 SPN 的正確服務票。
>>> KrbKdcReq send: kdc=kerberos.contoso.com UDP:88, timeout=30000, number of retries =3, #bytes=664
>>> KDCCommunication: kdc=kerberos.contoso.com UDP:88, timeout=30000,Attempt =1, #bytes=664
>>> KrbKdcReq send: #bytes read=669
>>> KdcAccessibility: remove kerberos.contoso.com
>>> EType: sun.security.krb5.internal.crypto.Des3CbcHmacSha1KdEType
>>> KrbApReq: APOptions are 00100000 00000000 00000000 00000000
>>> EType: sun.security.krb5.internal.crypto.Des3CbcHmacSha1KdEType
Krb5Context setting mySeqNumber to: 1033039363
Created InitSecContextToken:
0000: 01 00 6E 82 02 4B 30 82 02 47 A0 03 02 01 05 A1 ..n..K0..G......
0010: 03 02 01 0E A2 07 03 05 00 20 00 00 00 A3 82 01 ......... ......
0020: 63 61 82 01 5F 30 82 01 5B A0 03 02 01 05 A1 0E ca.._0..[.......
0030: 1B 0C 41 50 53 48 44 50 4D 53 2E 43 4F 4D A2 26 ..CONTOSO.COM.&
0040: 30 24 A0 03 02 01 00 A1 1D 30 1B 1B 02 6E 6E 1B 0$.......0...nn.
0050: 15 73 68 61 73 74 61 2D 68 64 70 32 35 2D 30 30 .hadoop-hdp25-00
0060: 2E 6C 6F 63 61 6C A3 82 01 1A 30 82 01 16 A0 03 .local....0.....
0070: 02 01 10 A1 03 02 01 01 A2 82 01 08 04 82 01 04 ................
*[...Condensed...]*
0240: 03 E3 68 72 C4 D2 8D C2 8A 63 52 1F AE 26 B6 88 ..hr.....cR..&..
0250: C4 .
檢查點 4
最後,會列印目標路徑的檔案屬性及確認訊息。 檔案屬性確認 SQL Server 透過 Hadoop 透過 ST 進行認證,並授權會話存取受保護的資源。
達到此點可確認:(i) 三位行為者正確通訊,(ii) core-site.xml 與 jaas.conf 正確,(iii) 你的 KDC 識別你的憑證。
[2017-04-25 21:34:35,096] INFO 2235[main] - com.microsoft.polybase.client.HdfsBridge.main(HdfsBridge.java:1586) - File properties for "/": FileStatus{path=hdfs://10.193.27.232:8020/; isDirectory=true; modification_time=1492028259862; access_time=0; owner=hdfs; group=hdfs; permission=rwxr-xr-x; isSymlink=false}
[2017-04-25 21:34:35,098] INFO 2237[main] - com.microsoft.polybase.client.HdfsBridge.main(HdfsBridge.java:1587) - Successfully accessed the external file system.
常見錯誤
如果你執行工具,但目標路徑的檔案屬性 沒有列印 (檢查點 4),中途應該會拋出例外。 請檢閱例外狀況,並細想在這四個步驟的流程中,是哪個環節的內容出了問題。 請依序考慮以下常見問題:
| 例外狀況及訊息 | 原因 |
|---|---|
org.apache.hadoop.security.AccessControlExceptionSIMPLE authentication is not enabled. Available:[TOKEN, KERBEROS] |
檔案 core-site.xml 不會將屬性設 hadoop.security.authentication 為 KERBEROS。 |
javax.security.auth.login.LoginExceptionClient not found in Kerberos database (6) - CLIENT_NOT_FOUND |
指定領域中的管理員服務主體在core-site.xml中不存在。 |
javax.security.auth.login.LoginExceptionChecksum failed |
管理服務主體存在,但是密碼不正確。 |
Native config name: C:\Windows\krb5.iniLoaded from native config |
此訊息表示 JAVA 的 krb5LoginModule 在您的電腦上偵測到自訂用戶端設定。 檢查你的自訂客戶端設定,因為可能是問題所在。 |
javax.security.auth.login.LoginExceptionjava.lang.IllegalArgumentExceptionIllegal principal name <admin_user@CONTOSO.COM>: org.apache.hadoop.security.authentication.util.KerberosName$NoMatchingRule: No rules applied to <admin_user@CONTOSO.COM> |
依據 Hadoop 叢集的適當規則,將 hadoop.security.auth_to_local 屬性新增至 core-site.xml。 |
java.net.ConnectExceptionAttempting to access external filesystem at URI: hdfs://10.193.27.230:8020Call From IAAS16981207/10.107.0.245 to 10.193.27.230:8020 failed on connection exception |
針對 KDC 的認證成功,但無法存取 Hadoop 名稱節點。 請檢查名稱節點 IP 及連接埠。 請驗證已在 Hadoop 上停用防火牆。 |
java.io.FileNotFoundExceptionFile does not exist: /test/data.csv |
認證成功了,但指定的位置不存在。 先檢查路徑或用根測試 / 。 |
偵錯秘訣
麻省理工學院 KDC
你可以透過在 KDC 主機或任何已設定的 KDC 用戶端上執行 kadmin.local> (管理員帳號) >listprincs 來查看所有註冊在 KDC 的 SPN,包括管理員。 如果你在 Hadoop 叢集上正確配置 Kerberos,叢集中每個可用服務應該都有一個 SPN(例如 nn、 dnrmyarnspnego等等)。 你可以在預設的 /etc/security/keytabs下看到它們對應的 keytab 檔案(密碼替換)。 KDC 私鑰會加密這些檔案。
若要在本地驗證 KDC 的管理員憑證,請使用 kinit。 例如,你可以執行 kinit identity@MYREALM.COM。 如果有這個身份,系統會提示你輸入密碼。
KDC 日誌預設在 /var/log/krb5kdc.log中提供。 日誌包含所有工單請求,包括提出請求的客戶端 IP。 在你執行工具的 SQL Server 機器的 IP 應該會發出兩個請求:首先是來自認證伺服器的 TGT AS_REQ,接下來是從票證授權伺服器的 ST TGS_REQ。
[root@MY-KDC log]# tail -2 /var/log/krb5kdc.log
May 09 09:48:26 MY-KDC.local krb5kdc[2547](info): **AS_REQ** (3 etypes {17 16 23}) 10.107.0.245: ISSUE: authtime 1494348506, etypes {rep=16 tkt=16 ses=16}, admin_user@CONTOSO.COM for **krbtgt/CONTOSO.COM@CONTOSO.COM**
May 09 09:48:29 MY-KDC.local krb5kdc[2547](info): **TGS_REQ** (3 etypes {17 16 23}) 10.107.0.245: ISSUE: authtime 1494348506, etypes {rep=16 tkt=16 ses=16}, admin_user@CONTOSO.COM for **nn/hadoop-hdp25-00.local@CONTOSO.COM**
Active Directory
在 Active Directory 中,你可以透過切換到控制面板>的Active Directory 使用者與電腦,然後點選 <MyRealm><MyOrganizationalUnit>來查看 SPN。 如果你在 Hadoop 叢集上正確配置 Kerberos,叢集中每個服務都有一個 SPN(例如 nn, dnrmyarnspnego等等)。
一般偵錯提示
有一些 Java 經驗很有幫助,可以查看日誌並除錯 Kerberos 的問題,這些問題與 SQL Server PolyBase 功能無關。
如果你仍然無法存取 Kerberos,請依照以下步驟除錯:
確定您可以從 SQL Server 外部存取 Kerberos HDFS 資料。 您可以:
你可以自己寫 Java 程式,或是用
HdfsBridgePolyBase 安裝資料夾裡的 class。 例如:-classpath ".\Hadoop\conf;.\Hadoop\*;.\Hadoop\HDP2_2\*" com.microsoft.polybase.client.HdfsBridge 10.193.27.232 8020 admin_user C:\temp\kerberos_pass.txt
在前一個例子中,只
admin_user包含使用者名稱,沒有任何網域部分。如果您無法從 PolyBase 外部存取 Kerberos HDFS 資料:
Kerberos 驗證有兩種類型:Active Directory Kerberos 驗證和 MIT Kerberos 驗證。
確定使用者存在於網域帳戶,並使用相同的使用者帳戶來嘗試存取 HDFS。
針對 Active Directory Kerberos,確定您可以在 Windows 上使用
klist命令來查看快取的票證。連接到 PolyBase 機器,在命令提示字元中執行
klist和klist tgt,看看 KDC、使用者名稱和加密類型是否正確。如果 KDC 只能支援 AES-256,請確保安裝了 JCE 的政策檔 。