在Linux上使用窗口身份验证的Sqoop和MSSQL失败

时间:2014-10-20 12:42:03

标签: sql-server linux apache sqoop

我使用apache sqoop使用窗口身份验证连接mSSQL服务器但是 我跑的时候无法登录:

sqoop list-databases --connect jdbc:sqlserver://192.168.xx.xx:1433;username=xxxxx;password=xxxxxx;database=xxxxx; 

我得到例外:

java.lang.RuntimeException: com.microsoft.sqlserver.jdbc.SQLServerException: Login failed for user 'username'. ClientConnectionId:a593dc10-2d06-4b8b-b53b-e743fb133d0e
        at org.apache.sqoop.manager.CatalogQueryManager.listDatabases(CatalogQueryManager.java:73)
        at org.apache.sqoop.tool.ListDatabasesTool.run(ListDatabasesTool.java:49)
        at org.apache.sqoop.Sqoop.run(Sqoop.java:147)
        at org.apache.hadoop.util.ToolRunner.run(ToolRunner.java:70)
        at org.apache.sqoop.Sqoop.runSqoop(Sqoop.java:183)
        at org.apache.sqoop.Sqoop.runTool(Sqoop.java:222)
        at org.apache.sqoop.Sqoop.runTool(Sqoop.java:231)
        at org.apache.sqoop.Sqoop.main(Sqoop.java:240)
Caused by: com.microsoft.sqlserver.jdbc.SQLServerException: Login failed for user 'username'. ClientConnectionId:a593dc10-2d06-4b8b-b53b-e743fb133d0e
        at com.microsoft.sqlserver.jdbc.SQLServerException.makeFromDatabaseError(SQLServerException.java:216)
        at com.microsoft.sqlserver.jdbc.TDSTokenHandler.onEOF(tdsparser.java:254)
        at com.microsoft.sqlserver.jdbc.TDSParser.parse(tdsparser.java:84)
        at com.microsoft.sqlserver.jdbc.SQLServerConnection.sendLogon(SQLServerConnection.java:2908)
        at com.microsoft.sqlserver.jdbc.SQLServerConnection.logon(SQLServerConnection.java:2234)
        at com.microsoft.sqlserver.jdbc.SQLServerConnection.access$000(SQLServerConnection.java:41)
        at com.microsoft.sqlserver.jdbc.SQLServerConnection$LogonCommand.doExecute(SQLServerConnection.java:2220)
        at com.microsoft.sqlserver.jdbc.TDSCommand.execute(IOBuffer.java:5696)
        at com.microsoft.sqlserver.jdbc.SQLServerConnection.executeCommand(SQLServerConnection.java:1715)
        at com.microsoft.sqlserver.jdbc.SQLServerConnection.connectHelper(SQLServerConnection.java:1326)
        at com.microsoft.sqlserver.jdbc.SQLServerConnection.login(SQLServerConnection.java:991)
        at com.microsoft.sqlserver.jdbc.SQLServerConnection.connect(SQLServerConnection.java:827)
        at com.microsoft.sqlserver.jdbc.SQLServerDriver.connect(SQLServerDriver.java:1012)
        at java.sql.DriverManager.getConnection(DriverManager.java:571)
        at java.sql.DriverManager.getConnection(DriverManager.java:233)
        at org.apache.sqoop.manager.SqlManager.makeConnection(SqlManager.java:824)
        at org.apache.sqoop.manager.GenericJdbcManager.getConnection(GenericJdbcManager.java:52)
        at org.apache.sqoop.manager.CatalogQueryManager.listDatabases(CatalogQueryManager.java:57)
        ... 7 more

7 个答案:

答案 0 :(得分:2)

我很遗憾地说,但目前的答案是Sqoop不支持任何数据库的集成身份验证(Kerberos)。

https://community.hortonworks.com/questions/20719/sqoop-to-sql-server-with-integrated-security.html#answer-82516

我花了好几个月的时间,并且被Cloudera告知,这是不可能的。当映射器生成时(因为YARN将作业转换为其内部安全子系统),kerberos令牌会丢失。

我认为这是必须添加到Sqoop本身的东西,就像HBase mapreduce作业必须将作业配置传递给代码Sqoop能够做同样的映射器。

我花了几周时间尝试不同的事情,做了网络跟踪(我的所有服务器都与Centrify绑定了AD,分机),观看了令牌丢失,最后找到了一篇由雅虎撰写的关于YARN的文章,解释了它使用的内部令牌子系统(在使用Kerberos外部验证某人为了提高性能而移动到不同的基于令牌的子系统之后)。

答案 1 :(得分:0)

使用"集成安全性=真或#34;用于Windows身份验证而不是用户名和密码。

您的sqoop语句应如下所示

sqoop list-databases --connect 'jdbc:sqlserver://192.168.xx.xx:1433;integratedSecurity=true;database=xxxxx;'

答案 2 :(得分:0)

如果您来自Linux机器,并且想要利用直接身份验证,则需要做一些事情。

首先,您的Linux系统需要通过Kerberos与Active Directory集成(大量文章)。

其次,您需要更改连接字符串: DBC:SQLSERVER://; SERVERNAME = $ fqdnOfDatabaseHost;数据库= $的databaseName; integratedSecurity = TRUE; authenticationScheme = JavaKerberos“

将$变量替换为适合您环境的变量。

此处有更多相关信息:

http://blogs.msdn.com/b/psssql/archive/2015/01/09/jdbc-this-driver-is-not-configured-for-integrated-authentication.aspx

使用Kerberos集成身份验证连接到SQL Server https://msdn.microsoft.com/en-us/library/gg558122(v=sql.110).aspx

作为次要选项,如果您不想通过Kerberos将Linux集成到AD的麻烦,那么您可以购买的第三方支付的驱动程序可以避免这种情况。

数据直接提供一个,我无法链接,因为我没有足够的代表(创建帐户来回复此)。

答案 3 :(得分:0)

您可以按照以下步骤使用jtds进行sqoop sql和windows身份验证:

1)从https://sourceforge.net/projects/jtds/files/下载jtds驱动程序(在http://jtds.sourceforge.net/faq.html找到有关jtds的常见问题解答) 2)将jtds文件复制到sqoop lib 3)使用以下连接字符串模板根据您的环境进行修改并连接: jdbc:jtds:sqlserver:// db_server:1433 / DB_NAME; domain = NT_DOMAIN_NAME; integratedSecurity = true; authenticationScheme = JavaKerberos

答案 4 :(得分:0)

我找到了其他用户在此提供的解决方案:https://community.hortonworks.com/questions/20719/sqoop-to-sql-server-with-integrated-security.html

基本上,如果你切换到你可以在这里下载的jtds驱动程序:http://jtds.sourceforge.net/

Per Rajendra Manjunath

"

Sqoop SQL Server数据导入到HDFS使用SQL Server JDBC驱动程序上的附加参数进行手动参数化身份验证(使用Windows凭证),因为由于Kerberos身份验证,SQL驱动程序现在不支持集成安全性(在运行MR作业时,委托的令牌通过集群分发。)

因此,我们需要使用密码和集成安全性禁用模式传递Windows身份验证,以将数据导入系统。由于普通的SQL服务器驱动程序不支持,所以我使用了jtds.jar和不同的驱动程序类将数据提取到Hadoop Lake。

示例命令我在服务器上尝试了如下,

sqoop import --table Table1 --connect" jdbc:jtds:sqlserver:// :; useNTLMv2 = true; domain =; databaseName = XXXXXXXXXXXXX" \

- connection-manager org.apache.sqoop.manager.SQLServerManager --driver net.sourceforge.jtds.jdbc.Driver --username XXXXX --password' XXXXXXX' \

- 详细--target-dir / tmp / 33 -m 1 - --schema dbo

"

以下是一些对我有用的例子:

列出数据库

sqoop list-databases --connect" jdbc:jtds:sqlserver://databasehostname.yourdomain.com:1433; useNTLMv2 = true; domain = myactivedirectorydomain.com" --connection-manager org.apache.sqoop.manager.SQLServerManager --driver net.sourceforge.jtds.jdbc.Driver --username XXXXX -P

列表

sqoop list-tables --connect" jdbc:jtds:sqlserver://databasehostname.yourdomain.com:1433; useNTLMv2 = true; domain = myactivedirectorydomain.com; databaseName = DATABASENAMEHERE" --connection-manager org.apache.sqoop.manager.SQLServerManager --driver net.sourceforge.jtds.jdbc.Driver --username jmiller.admin -P

拉数据示例

sqoop import --table TABLENAMEHERE --connect" jdbc:jtds:sqlserver://databasehostname.yourdomain.com:1433; useNTLMv2 = true; domain = myactivedirectorydomain.com; databaseName = DATABASENAMEHERE" --connection-manager org.apache.sqoop.manager.SQLServerManager --driver net.sourceforge.jtds.jdbc.Driver --username XXXXX -P --fields-terminated-by' \ 001' --target-dir / user / XXXXX / 20170313 -m 1 - --schema dbo

注意*在上面的示例中,您需要将用户名和数据库名称更改为列表表中的用户名或拉到您需要的用户名(注意您使用的AD帐户需要访问数据)。

答案 5 :(得分:0)

集成身份验证不适用于具有 AD 集成的安全集群中的 MS SQLServer JDBC 驱动程序,因为容器将没有上下文,因为在映射器生成时 Kerberos 令牌丢失(因为 YARN 将作业转换到其内部安全子系统).

这是我的存储库,用作获取 Kerberos/AD 身份验证的解决方法 https://github.com/chandanbalu/mssql-jdbc-krb5,解决方案实现了一个驱动程序,该驱动程序覆盖了最新的 MS SQL JDBC 驱动程序 (mssql-jdbc-9.2.1.jre8.jar) 的连接方法,并将获得密钥表文件/主体的票证,并提供此连接回来了。

您可以从发布文件夹 here

获取此自定义驱动程序的最新版本

Sqoop 命令

export HADOOP_CLASSPATH=/efs/home/c795701/mssql-jdbc-krb5/target/scala-2.10/mssql-jdbc-krb5_2.10-1.0.jar:/efs/home/c795701/.ivy2/jars/scala-library-2.11.1.jar

sqoop import -libjars "/efs/home/c795701/mssql-jdbc-krb5/target/scala-2.10/mssql-jdbc-krb5_2.10-1.0.jar,/efs/home/c795701/.ivy2/jars/scala-library-2.11.1.jar" \
-files "/efs/home/c795701/c795701.keytab" \
--connection-manager org.apache.sqoop.manager.SQLServerManager \
--driver hadoop.sqlserver.jdbc.krb5.SQLServerDriver \
--connect "jdbc:krb5ss://<SERVER_NAME>:1433;databasename=<DATABASE_NAME>;integratedSecurity=true;authenticationScheme=JavaKerberos;krb5Principal=c795701@NA.DOMAIN.COM;krb5Keytab=/efs/home/c795701/c795701.keytab" \
--query "SELECT TOP 1000 * FROM <TABLE_NAME> WHERE \$CONDITIONS" \
--delete-target-dir \
--target-dir "/dev/product/sandbox/<table_name>" \
--num-mappers 1 \
--verbose \
-- --schema "dbo"

答案 6 :(得分:-1)

对于Windows身份验证并直接导入Hive,这对我有用:

HADOOP_CLASSPATH=/apps/lib/java/jdbc/jtds-1.3.1-patched/jtds-1.3.1.jar \
sqoop import --table XXXXX --connect "jdbc:jtds:sqlserver://XXXX:1433;useNTLMv2=true;domain=XXXX;databaseName=XXXXXX" \
--split-by XXXXX --num-mappers 10 --hive-import --hive-table test --hive-overwrite \
--connection-manager org.apache.sqoop.manager.SQLServerManager --driver net.sourceforge.jtds.jdbc.Driver --username XXXX -P \
--verbose --target-dir /apps/hive/warehouse/XXXX/XXX-$(uuidgen) \
-- --schema XXXXX