You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spark通过Kerberos连接MSSQL报错:无法找到Kerberos TGT

Spark连接MSSQL Kerberos认证失败问题排查与解决

问题场景

已通过keytab和principal在简单Java项目中成功建立MSSQL的Kerberos认证连接,但集成到Spark后出现认证失败,报错如下:

Caused by: java.security.PrivilegedActionException: GSSException: No valid credentials provided (Mechanism level: Failed to find any Kerberos tgt)
        at java.security.AccessController.doPrivileged(Native Method)
        at javax.security.auth.Subject.doAs(Subject.java:422)
        at com.microsoft.sqlserver.jdbc.KerbAuthentication.getClientCredential(KerbAuthentication.java:179)
        at com.microsoft.sqlserver.jdbc.KerbAuthentication.initAuthInit(KerbAuthentication.java:139)
        ... 47 more
Caused by: GSSException: No valid credentials provided (Mechanism level: Failed to find any Kerberos tgt)

现有配置与代码

jaas.conf配置

SQLJDBCDriver {
    com.sun.security.auth.module.Krb5LoginModule required
    useKeyTab=true
    keyTab="/home/spark/apacheservacc.keytab"
    storeKey=true
    useTicketCache=false
    principal="apacheservacc/xxx:1433@xxx"
    debug=true;
};

spark-submit提交命令

spark-submit   --driver-class-path /home/spark/mssql-jdbc-12.8.1.jre8.jar   --jars /home/spark/mssql-jdbc-12.8.1.jre8.jar --conf "spark.driver.extraJavaOptions=-Djava.security.auth.login.config=/etc/jaas.conf" --conf "spark.executor.extraJavaOptions=-Djava.security.auth.login.config=/etc/jaas.conf" spark_kerberos_v2.py

PySpark代码

SparkSession创建

def create_spark_session():
    spark = SparkSession.builder \
    .appName("MSSQL Kerberos Connection") \
    .master("yarn") \
    .config("spark.submit.deployMode", "client") \
    .config("spark.executor.instances", 4) \
    .config("spark.default.parallelism", 8) \
    .config("spark.jars", "/home/spark/mssql-jdbc-12.8.1.jre8.jar") \
    .config("spark.executor.extraJavaOptions",
            "-Djava.security.auth.login.config=/etc/jaas.conf "
            "-Djava.security.krb5.conf=/etc/krb5.conf "
            "-Dsun.security.krb5.debug=true") \
    .config("spark.driver.extraJavaOptions",
            "-Djava.security.auth.login.config=/etc/jaas.conf "
            "-Djava.security.krb5.conf=/etc/krb5.conf "
            "-Dsun.security.krb5.debug=true") \
    .getOrCreate()

MSSQL连接函数

def connect_mssql_with_spark(spark, server, database, keytab_path, principal):
    jdbc_url = f"jdbc:sqlserver://{server}:1433;databaseName={database};encrypt=false;integratedSecurity=true;authenticationScheme=JavaKerberos"
    # Connection properties
    connection_properties = {
        "driver": "com.microsoft.sqlserver.jdbc.SQLServerDriver",
        "keytab": "/home/spark/apacheservacc.keytab",
        "principal": "apacheservacc/xxx:1433@xxx"
    }

    print(jdbc_url)

问题原因分析

  1. JAAS配置条目不匹配:MSSQL JDBC驱动默认使用的JAAS配置条目为com.sun.security.jgss.krb5.initiate,当前配置的SQLJDBCDriver无法被驱动识别,导致无法加载正确的登录凭证。
  2. 配置重复与分发问题:SparkSession和spark-submit命令重复配置Java参数,可能引发冲突;同时未将JAAS、krb5配置文件分发到所有executor节点,导致executor无法读取配置。
  3. Principal格式错误:客户端principal不应携带端口,端口是MSSQL服务端SPN(MSSQLSvc/[server]:1433@REALM)的组成部分,当前格式会导致凭证无法匹配服务端。
  4. Keytab文件可用性问题:executor节点上的keytab文件可能不存在或权限不足,导致无法读取凭证。

解决方案

1. 修正JAAS配置文件

将配置条目改为驱动默认的名称,同时修正客户端principal格式:

com.sun.security.jgss.krb5.initiate {
    com.sun.security.auth.module.Krb5LoginModule required
    useKeyTab=true
    keyTab="/home/spark/apacheservacc.keytab"
    storeKey=true
    useTicketCache=false
    principal="apacheservacc@xxx"
    debug=true;
};

2. 统一Spark配置并分发文件

移除SparkSession代码中的Java参数配置,在spark-submit命令中统一指定,并添加文件分发配置:

spark-submit \
--driver-class-path /home/spark/mssql-jdbc-12.8.1.jre8.jar \
--jars /home/spark/mssql-jdbc-12.8.1.jre8.jar \
--conf "spark.driver.extraJavaOptions=-Djava.security.auth.login.config=/etc/jaas.conf -Djava.security.krb5.conf=/etc/krb5.conf -Dsun.security.krb5.debug=true" \
--conf "spark.executor.extraJavaOptions=-Djava.security.auth.login.config=/etc/jaas.conf -Djava.security.krb5.conf=/etc/krb5.conf -Dsun.security.krb5.debug=true" \
--conf "spark.yarn.dist.files=/etc/jaas.conf,/etc/krb5.conf,/home/spark/apacheservacc.keytab" \
spark_kerberos_v2.py

spark.yarn.dist.files会将指定文件分发到所有executor节点的工作目录,此时代码中路径需改为相对路径,或使用Spark提供的分布式路径变量。

3. 修正JDBC连接配置

移除URL中冗余参数,同时不再重复指定keytab和principal(由JAAS配置自动加载):

def connect_mssql_with_spark(spark, server, database):
    jdbc_url = f"jdbc:sqlserver://{server}:1433;databaseName={database};encrypt=false;authenticationScheme=JavaKerberos"
    connection_properties = {
        "driver": "com.microsoft.sqlserver.jdbc.SQLServerDriver"
    }
    # 执行读取示例
    df = spark.read.jdbc(url=jdbc_url, table="your_target_table", properties=connection_properties)
    df.show()

4. 验证Kerberos基础环境

在Spark节点执行以下命令,确保凭证能正常获取:

# 使用keytab获取TGT
kinit -kt /home/spark/apacheservacc.keytab apacheservacc@xxx
# 查看凭证
klist

内容的提问来源于stack exchange,提问作者Bilge Kaan Gençdoğan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 22:26:00