This commit is contained in:
Kent Yao 2020-11-16 19:42:06 +08:00
parent 7fd225b098
commit 15820a2b09
7 changed files with 78 additions and 67 deletions

View File

@ -34,8 +34,6 @@ jobs:
uses: actions/setup-java@v1
with:
java-version: '1.8'
- uses: olegtarasov/get-tag@v2
id: tagName
- name: Make Distribution
run: ./build/dist --tgz
- name: Create Release
@ -45,7 +43,7 @@ jobs:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
tag_name: ${{ github.ref }}
release_name: Release Kyuubi-${{ steps.tagName.outputs.tag }}
release_name: Release Kyuubi-${{ github.ref }}
draft: false
prerelease: false
- name: Upload Release Asset
@ -53,4 +51,4 @@ jobs:
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
asset_paths: '["./kyuubi-*tgz"]'
asset_paths: '["./kyuubi-*tar.gz"]'

2
.gitignore vendored
View File

@ -49,3 +49,5 @@ embedded_zookeeper/
/externals/kyuubi-spark-sql-engine/spark-warehouse/
/work/
/docs/_build/
/kyuubi-common/metrics/
kyuubi-common/kyuubi_operation_logs/

View File

@ -115,6 +115,13 @@ kyuubi\.delegation<br>\.token\.gc\.interval|<div style='width: 80pt;word-wrap: b
kyuubi\.delegation<br>\.token\.max\.lifetime|<div style='width: 80pt;word-wrap: break-word;white-space: normal'>PT168H</div>|<div style='width: 200pt;word-wrap: break-word;white-space: normal'>unused yet</div>|<div style='width: 20pt'>1.0.0</div>
kyuubi\.delegation<br>\.token\.renew\.interval|<div style='width: 80pt;word-wrap: break-word;white-space: normal'>PT168H</div>|<div style='width: 200pt;word-wrap: break-word;white-space: normal'>unused yet</div>|<div style='width: 20pt'>1.0.0</div>
### Engine
Key | Default | Meaning | Since
--- | --- | --- | ---
kyuubi\.engine\.check<br>\.interval|<div style='width: 80pt;word-wrap: break-word;white-space: normal'>PT10M</div>|<div style='width: 200pt;word-wrap: break-word;white-space: normal'>The check interval for engine timeout</div>|<div style='width: 20pt'>1.0.0</div>
kyuubi\.engine\.idle<br>\.timeout|<div style='width: 80pt;word-wrap: break-word;white-space: normal'>PT30M</div>|<div style='width: 200pt;word-wrap: break-word;white-space: normal'>engine timeout, it will be closed when it's not accessed for this duration</div>|<div style='width: 20pt'>1.0.0</div>
### Frontend
Key | Default | Meaning | Since
@ -161,11 +168,11 @@ kyuubi\.operation\.idle<br>\.timeout|<div style='width: 80pt;word-wrap: break-wo
Key | Default | Meaning | Since
--- | --- | --- | ---
kyuubi\.session\.check<br>\.interval|<div style='width: 80pt;word-wrap: break-word;white-space: normal'>PT5M</div>|<div style='width: 200pt;word-wrap: break-word;white-space: normal'>The check interval for session timeout.</div>|<div style='width: 20pt'></div>
kyuubi\.session\.check<br>\.interval|<div style='width: 80pt;word-wrap: break-word;white-space: normal'>PT5M</div>|<div style='width: 200pt;word-wrap: break-word;white-space: normal'>The check interval for session timeout.</div>|<div style='width: 20pt'>1.0.0</div>
kyuubi\.session\.engine<br>\.initialize\.timeout|<div style='width: 80pt;word-wrap: break-word;white-space: normal'>PT1M</div>|<div style='width: 200pt;word-wrap: break-word;white-space: normal'>Timeout for starting the background engine, e.g. SparkSQLEngine.</div>|<div style='width: 20pt'>1.0.0</div>
kyuubi\.session\.engine<br>\.login\.timeout|<div style='width: 80pt;word-wrap: break-word;white-space: normal'>PT15S</div>|<div style='width: 200pt;word-wrap: break-word;white-space: normal'>The timeout(ms) of creating the connection to remote sql query engine</div>|<div style='width: 20pt'>1.0.0</div>
kyuubi\.session\.engine<br>\.spark\.main\.resource|<div style='width: 80pt;word-wrap: break-word;white-space: normal'>&lt;undefined&gt;</div>|<div style='width: 200pt;word-wrap: break-word;white-space: normal'>The package used to create Spark SQL engine remote application. If it is undefined, Kyuubi will use the default</div>|<div style='width: 20pt'>1.0.0</div>
kyuubi\.session<br>\.timeout|<div style='width: 80pt;word-wrap: break-word;white-space: normal'>PT6H</div>|<div style='width: 200pt;word-wrap: break-word;white-space: normal'>session timeout, it will be closed when it's not accessed for this duration</div>|<div style='width: 20pt'></div>
kyuubi\.session<br>\.timeout|<div style='width: 80pt;word-wrap: break-word;white-space: normal'>PT6H</div>|<div style='width: 200pt;word-wrap: break-word;white-space: normal'>session timeout, it will be closed when it's not accessed for this duration</div>|<div style='width: 20pt'>1.0.0</div>
### Zookeeper

View File

@ -351,31 +351,30 @@ object KyuubiConf {
.timeConf
.createWithDefault(Duration.ofSeconds(60).toMillis)
val SESSION_CHECK_INTERVAL: ConfigEntry[Long] =
buildConf("session.check.interval")
.doc("The check interval for session timeout.")
.timeConf
.checkValue(_ > Duration.ofSeconds(3).toMillis, "Minimum 3 seconds")
.createWithDefault(Duration.ofMinutes(5).toMillis)
val SESSION_CHECK_INTERVAL: ConfigEntry[Long] = buildConf("session.check.interval")
.doc("The check interval for session timeout.")
.version("1.0.0")
.timeConf
.checkValue(_ > Duration.ofSeconds(3).toMillis, "Minimum 3 seconds")
.createWithDefault(Duration.ofMinutes(5).toMillis)
val SESSION_TIMEOUT: ConfigEntry[Long] =
buildConf("session.timeout")
.doc("session timeout, it will be closed when it's not accessed for this duration")
.timeConf
.checkValue(_ > Duration.ofSeconds(3).toMillis, "Minimum 3 seconds")
.createWithDefault(Duration.ofHours(6).toMillis)
val SESSION_TIMEOUT: ConfigEntry[Long] = buildConf("session.timeout")
.doc("session timeout, it will be closed when it's not accessed for this duration")
.version("1.0.0")
.timeConf
.checkValue(_ > Duration.ofSeconds(3).toMillis, "Minimum 3 seconds")
.createWithDefault(Duration.ofHours(6).toMillis)
val ENGINE_CHECK_INTERVAL: ConfigEntry[Long] =
buildConf("engine.check.interval")
.doc("The check interval for engine timeout")
.timeConf
.checkValue(_ > Duration.ofSeconds(3).toMillis, "Minimum 3 seconds")
.createWithDefault(Duration.ofMinutes(10).toMillis)
val ENGINE_IDLE_TIMEOUT: ConfigEntry[Long] =
buildConf("engine.idle.timeout")
.doc("engine timeout, it will be closed when it's not accessed for this duration")
.timeConf
.createWithDefault(Duration.ofMinutes(30L).toMillis)
val ENGINE_CHECK_INTERVAL: ConfigEntry[Long] = buildConf("engine.check.interval")
.doc("The check interval for engine timeout")
.version("1.0.0")
.timeConf
.checkValue(_ > Duration.ofSeconds(3).toMillis, "Minimum 3 seconds")
.createWithDefault(Duration.ofMinutes(10).toMillis)
val ENGINE_IDLE_TIMEOUT: ConfigEntry[Long] = buildConf("engine.idle.timeout")
.doc("engine timeout, it will be closed when it's not accessed for this duration")
.version("1.0.0")
.timeConf
.createWithDefault(Duration.ofMinutes(30L).toMillis)
}

View File

@ -224,18 +224,20 @@ object ServiceDiscovery {
*/
@throws[Exception]
def setUpZooKeeperAuth(conf: KyuubiConf): Unit = {
val keyTabFile = conf.get(KyuubiConf.SERVER_KEYTAB)
val maybePrincipal = conf.get(KyuubiConf.SERVER_PRINCIPAL)
val kerberized = maybePrincipal.isDefined && keyTabFile.isDefined
if (UserGroupInformation.isSecurityEnabled && kerberized) {
if (!new File(keyTabFile.get).exists()) {
throw new IOException(s"${KyuubiConf.SERVER_KEYTAB.key} does not exists")
if (conf.get(HA_ZK_ACL_ENABLED)) {
val keyTabFile = conf.get(KyuubiConf.SERVER_KEYTAB)
val maybePrincipal = conf.get(KyuubiConf.SERVER_PRINCIPAL)
val kerberized = maybePrincipal.isDefined && keyTabFile.isDefined
if (UserGroupInformation.isSecurityEnabled && kerberized) {
if (!new File(keyTabFile.get).exists()) {
throw new IOException(s"${KyuubiConf.SERVER_KEYTAB.key} does not exists")
}
System.setProperty("zookeeper.sasl.clientconfig", "KyuubiZooKeeperClient")
var principal = maybePrincipal.get
principal = SecurityUtil.getServerPrincipal(principal, "0.0.0.0")
val jaasConf = new JaasConfiguration("KyuubiZooKeeperClient", principal, keyTabFile.get)
Configuration.setConfiguration(jaasConf)
}
System.setProperty("zookeeper.sasl.clientconfig", "KyuubiZooKeeperClient")
var principal = maybePrincipal.get
principal = SecurityUtil.getServerPrincipal(principal, "0.0.0.0")
val jaasConf = new JaasConfiguration("KyuubiZooKeeperClient", principal, keyTabFile.get)
Configuration.setConfiguration(jaasConf)
}
}
}

View File

@ -27,6 +27,7 @@ import org.apache.zookeeper.ZooDefs
import org.apache.kyuubi.{KerberizedTestHelper, KYUUBI_VERSION}
import org.apache.kyuubi.config.KyuubiConf
import org.apache.kyuubi.ha.HighAvailabilityConf
import org.apache.kyuubi.ha.HighAvailabilityConf._
import org.apache.kyuubi.ha.server.EmbeddedZkServer
import org.apache.kyuubi.service.{NoopServer, Serverable, ServiceState}
@ -50,31 +51,6 @@ class ServiceDiscoverySuite extends KerberizedTestHelper {
super.afterAll()
}
test("set up zookeeper auth") {
tryWithSecurityEnabled {
val keytab = File.createTempFile("kentyao", ".keytab")
val principal = "kentyao/_HOST@apache.org"
conf.set(KyuubiConf.SERVER_KEYTAB, keytab.getCanonicalPath)
conf.set(KyuubiConf.SERVER_PRINCIPAL, principal)
ServiceDiscovery.setUpZooKeeperAuth(conf)
val configuration = Configuration.getConfiguration
val entries = configuration.getAppConfigurationEntry("KyuubiZooKeeperClient")
assert(entries.head.getLoginModuleName === "com.sun.security.auth.module.Krb5LoginModule")
val options = entries.head.getOptions.asScala.toMap
assert(options("principal") ===
s"kentyao/${InetAddress.getLocalHost.getCanonicalHostName}@apache.org")
assert(options("useKeyTab").toString.toBoolean)
conf.set(KyuubiConf.SERVER_KEYTAB, keytab.getName)
val e = intercept[IOException](ServiceDiscovery.setUpZooKeeperAuth(conf))
assert(e.getMessage === s"${KyuubiConf.SERVER_KEYTAB.key} does not exists")
}
}
test("publish instance to embedded zookeeper server") {
conf
@ -126,4 +102,30 @@ class ServiceDiscoverySuite extends KerberizedTestHelper {
expected.addAll(ZooDefs.Ids.CREATOR_ALL_ACL)
assert(acl1 === expected)
}
test("set up zookeeper auth") {
tryWithSecurityEnabled {
val keytab = File.createTempFile("kentyao", ".keytab")
val principal = "kentyao/_HOST@apache.org"
conf.set(KyuubiConf.SERVER_KEYTAB, keytab.getCanonicalPath)
conf.set(KyuubiConf.SERVER_PRINCIPAL, principal)
conf.set(HighAvailabilityConf.HA_ZK_ACL_ENABLED, true)
ServiceDiscovery.setUpZooKeeperAuth(conf)
val configuration = Configuration.getConfiguration
val entries = configuration.getAppConfigurationEntry("KyuubiZooKeeperClient")
assert(entries.head.getLoginModuleName === "com.sun.security.auth.module.Krb5LoginModule")
val options = entries.head.getOptions.asScala.toMap
assert(options("principal") ===
s"kentyao/${InetAddress.getLocalHost.getCanonicalHostName}@apache.org")
assert(options("useKeyTab").toString.toBoolean)
conf.set(KyuubiConf.SERVER_KEYTAB, keytab.getName)
val e = intercept[IOException](ServiceDiscovery.setUpZooKeeperAuth(conf))
assert(e.getMessage === s"${KyuubiConf.SERVER_KEYTAB.key} does not exists")
}
}
}

View File

@ -90,6 +90,7 @@ class KyuubiSessionImpl(
case None =>
val builder = new SparkProcessBuilder(user, sessionConf.toSparkPrefixedConf)
val process = builder.start
info(s"Launching SQL engine: $builder")
var sh = getServerHost
val started = System.currentTimeMillis()
while (sh.isEmpty) {
@ -98,7 +99,7 @@ class KyuubiSessionImpl(
}
if (started + timeout <= System.currentTimeMillis()) {
process.destroyForcibly()
throw KyuubiSQLException(s"Timed out($timeout ms) to launched Spark")
throw KyuubiSQLException(s"Timed out($timeout ms) to launched Spark with $builder")
}
sh = getServerHost
}