Skip to content

[FEATURE] Support starting SparkSQLEngine with an external delegation token file to reduce unnecessary delegation token creation. #7188

@Z1Wu

Description

@Z1Wu

Code of Conduct

Search before asking

  • I have searched in the issues and found no similar issues.

Describe the feature

  • Support starting SparkSQLEngine with an external delegation token file to reduce unnecessary delegation token creation.
  • Add YarnRMDelegationTokenProvider to get Yarn RM delegation token which is required when submitting spark yarn application without tgt or keytabs.

Motivation

Spark applications launched in the proxy-user + cluster mode will automatically request delegation tokens in spark-submit.

// org.apache.spark.scheduler.cluster.CoarseGrainedSchedulerBackend#start
override def start(): Unit = {
    if (UserGroupInformation.isSecurityEnabled()) {
      delegationTokenManager = createTokenManager()
      delegationTokenManager.foreach { dtm =>
        val ugi = UserGroupInformation.getCurrentUser()
        val tokens = if (dtm.renewalEnabled) {
          dtm.start()
        } else {
          val creds = ugi.getCredentials()
          // fetch all related delegation tokens
          dtm.obtainDelegationTokens(creds)
          if (creds.numberOfTokens() > 0 || creds.numberOfSecretKeys() > 0) {
            SparkHadoopUtil.get.serialize(creds)
          } else {
            null
          }
        }
        if (tokens != null) {
          updateDelegationTokens(tokens)
        }
      }
    }
  }

However, when SparkSQLEngine starts, these tokens will be overwritten (without canceling) by the tokens configured in spark-conf by Kyuubi Server . As we can see in the code below :

// org.apache.kyuubi.engine.spark.SparkSQLEngine#createSpark
def createSpark(): SparkSession = {
    val engineCredentials = kyuubiConf.getOption(KyuubiReservedKeys.KYUUBI_ENGINE_CREDENTIALS_KEY)
    kyuubiConf.unset(KyuubiReservedKeys.KYUUBI_ENGINE_CREDENTIALS_KEY)
    _sparkConf.set(s"spark.${KyuubiReservedKeys.KYUUBI_ENGINE_CREDENTIALS_KEY}", "")

    val session = SparkSession.builder.config(_sparkConf).getOrCreate

    engineCredentials.filter(_.nonEmpty).foreach { credentials =>
       // reset all delegation token
       SparkTBinaryFrontendService.renewDelegationToken(session.sparkContext, credentials)
    }
    ....
  }

In our production environment, more than 100000 SparkSQLEngine are launched every day through kyuubi, which creates lots of unnecessary delegation tokens in shared delegation token storage.

Image

Describe the solution

Spark natively supports passing tokens through an external Delegation Token File. As we can see in this doc https://github.com/apache/spark/blob/master/core/src/main/scala/org/apache/spark/deploy/security/README.md

We can submit spark application with external delegation token file to avoid unnecessary token creation in spark-submit and let kyuubi server manage all delegation tokens for SparkSQLEngine.

Additional context

No response

Are you willing to submit PR?

  • Yes. I would be willing to submit a PR with guidance from the Kyuubi community to improve.
  • No. I cannot submit a PR at this time.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions