适用于: SQL Server 2016 (13.x) 及更高版本 - 仅限 Windows
若要排查将 PolyBase 与 Kerberos 保护的 Hadoop 群集配合使用时遇到的身份验证问题,请使用 PolyBase 中内置的交互式诊断。
本文旨在指导您使用这些内置诊断逐步解决此类问题的调试过程。
提示
在 Kerberos 安全 HDFS 集群中创建外部表时,如果 HDFS Kerberos 失败,则可选择运行 HDFS Kerberos Tester 来排除针对 PolyBase 的 HDFS Kerberos 连接故障,而无需遵循本指南中的步骤。
此工具有助于排除非 SQL Server 问题,帮助你专注于解决 HDFS Kerberos 设置问题,即识别用户名/密码配置问题,以及群集 Kerberos 设置配置错误。
此工具独立于 SQL Server。 它作为 Jupyter Notebook 提供,需要 Azure Data Studio。
先决条件
安装了 PolyBase 的 SQL Server 2016 (13.x) RTM CU6 / SQL Server 2016 (13.x) SP1 CU3 / SQL Server 2017 (14.x) 或更高版本
受 Kerberos(Active Directory 或 MIT)保护的 Hadoop 群集(Cloudera 或 Hortonworks)
简介
这有助于先了解高级别的 Kerberos 协议。 涉及三个参与者:
- Kerberos 客户端 (SQL Server)
- 受保护的资源(HDFS、MR2、YARN、作业历史记录等)
- 密钥发行中心(在 Active Directory 中称为域控制器)
在 Hadoop 群集上配置 Kerberos 时,请使用唯一的服务主体名称(SPN)在密钥分发中心(KDC)中注册每个 Hadoop 安全资源。 客户端需要获取临时用户票证(称为票证授予票证(TGT),以便它可以从 KDC 请求另一个临时票证(称为服务票证(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 环境变量。 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。 引用 Transact-SQL 中的 CREATE EXTERNAL DATA SOURCE “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.security.auth_to_local 属性根据 Hadoop 群集的适当规则添加到 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 |
身份验证成功,但指定的位置不存在。 首先检查路径或测试根 / 。 |
调试提示
MIT KDC (麻省理工学院密钥分发中心)
可以通过在 KDC 主机或任何配置的 KDC 客户端上运行 kadmin.local> (管理员帐户) >listprincs 来查看向 KDC 注册的所有 SPN,包括管理员。 如果在 Hadoop 群集上正确配置 Kerberos,则群集中可用的每个服务应有一个 SPN(例如:nn、、dnrm、yarn,spnego等等)。 默认情况下,可以在 /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 用户和计算机来查看 SPN,然后转到 <MyRealm> 并选择 <MyOrganizationalUnit>。 如果在 Hadoop 群集上正确配置 Kerberos,则群集中可用的每个服务都有一个 SPN(例如:nn、、dnrm、yarn,spnego等等)。
常规调试提示
拥有一些 Java 经验对于查看日志和调试 Kerberos 问题是有帮助的,这些问题与 SQL Server PolyBase 功能无关。
如果在访问 Kerberos 时遇到问题,请执行以下步骤进行调试:
确保可从外部 SQL 服务器访问 Kerberos HDFS 数据。 可以:
编写自己的 Java 程序,或使用
HdfsBridgePolyBase 安装文件夹中的类。 例如:-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 时使用相同的用户帐户。
对于活动目录 Kerberos,请确保可在 Windows 上使用
klist命令查看缓存的票证。连接到 PolyBase 计算机并运行
klist并在klist tgt命令提示符中查看 KDC、用户名和加密类型是否正确。如果 KDC 只能支持 AES-256,请确保已安装 JCE 策略文件 。