You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@spark.apache.org by do...@apache.org on 2022/06/27 08:33:36 UTC
[spark] branch branch-3.3 updated: [SPARK-39614][K8S] K8s pod name follows `DNS Subdomain Names` rule
This is an automated email from the ASF dual-hosted git repository.
dongjoon pushed a commit to branch branch-3.3
in repository https://gitbox.apache.org/repos/asf/spark.git
The following commit(s) were added to refs/heads/branch-3.3 by this push:
new 972338ae771 [SPARK-39614][K8S] K8s pod name follows `DNS Subdomain Names` rule
972338ae771 is described below
commit 972338ae771c99fc63acb5f75fdfa2f6d2c0ffab
Author: Dongjoon Hyun <do...@apache.org>
AuthorDate: Mon Jun 27 01:29:57 2022 -0700
[SPARK-39614][K8S] K8s pod name follows `DNS Subdomain Names` rule
This PR aims to fix a regression at Apache Spark 3.3.0 which doesn't allow long pod name prefix whose length is greater than 63.
Although Pod's `hostname` follows [DNS Label Names](https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#dns-label-names), Pod name itself follows [DNS Subdomain Names](https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#dns-subdomain-names) whose maximum length is 253.
Yes, this fixes a regression.
Pass the CIs with the updated unit tests.
Closes #36999 from dongjoon-hyun/SPARK-39614.
Authored-by: Dongjoon Hyun <do...@apache.org>
Signed-off-by: Dongjoon Hyun <do...@apache.org>
(cherry picked from commit c15508f0d6a49738db5edf7eb139cc1d438af9a9)
Signed-off-by: Dongjoon Hyun <do...@apache.org>
---
.../src/main/scala/org/apache/spark/deploy/k8s/Config.scala | 11 ++++++-----
.../scala/org/apache/spark/deploy/k8s/KubernetesConf.scala | 2 +-
.../spark/deploy/k8s/features/BasicExecutorFeatureStep.scala | 4 ++--
.../spark/deploy/k8s/features/DriverServiceFeatureStep.scala | 4 ++--
.../spark/deploy/k8s/submit/KubernetesClientUtils.scala | 6 +++---
.../deploy/k8s/features/BasicExecutorFeatureStepSuite.scala | 8 ++++----
6 files changed, 18 insertions(+), 17 deletions(-)
diff --git a/resource-managers/kubernetes/core/src/main/scala/org/apache/spark/deploy/k8s/Config.scala b/resource-managers/kubernetes/core/src/main/scala/org/apache/spark/deploy/k8s/Config.scala
index 7930cd0ce15..e3067bc3a7d 100644
--- a/resource-managers/kubernetes/core/src/main/scala/org/apache/spark/deploy/k8s/Config.scala
+++ b/resource-managers/kubernetes/core/src/main/scala/org/apache/spark/deploy/k8s/Config.scala
@@ -323,7 +323,7 @@ private[spark] object Config extends Logging {
private def isValidExecutorPodNamePrefix(prefix: String): Boolean = {
// 6 is length of '-exec-'
val reservedLen = Int.MaxValue.toString.length + 6
- val validLength = prefix.length + reservedLen <= KUBERNETES_DNSNAME_MAX_LENGTH
+ val validLength = prefix.length + reservedLen <= KUBERNETES_DNS_SUBDOMAIN_NAME_MAX_LENGTH
validLength && podConfValidator.matcher(prefix).matches()
}
@@ -331,15 +331,15 @@ private[spark] object Config extends Logging {
ConfigBuilder("spark.kubernetes.executor.podNamePrefix")
.doc("Prefix to use in front of the executor pod names. It must conform the rules defined " +
"by the Kubernetes <a href=\"https://kubernetes.io/docs/concepts/overview/" +
- "working-with-objects/names/#dns-label-names\">DNS Label Names</a>. " +
+ "working-with-objects/names/#dns-subdomain-names\">DNS Subdomain Names</a>. " +
"The prefix will be used to generate executor pod names in the form of " +
"<code>$podNamePrefix-exec-$id</code>, where the `id` is a positive int value, " +
- "so the length of the `podNamePrefix` needs to be <= 47(= 63 - 10 - 6).")
+ "so the length of the `podNamePrefix` needs to be <= 237(= 253 - 10 - 6).")
.version("2.3.0")
.stringConf
.checkValue(isValidExecutorPodNamePrefix,
"must conform https://kubernetes.io/docs/concepts/overview/working-with-objects" +
- "/names/#dns-label-names and the value length <= 47")
+ "/names/#dns-subdomain-names and the value length <= 237")
.createOptional
val KUBERNETES_EXECUTOR_DISABLE_CONFIGMAP =
@@ -713,5 +713,6 @@ private[spark] object Config extends Logging {
val KUBERNETES_DRIVER_ENV_PREFIX = "spark.kubernetes.driverEnv."
- val KUBERNETES_DNSNAME_MAX_LENGTH = 63
+ val KUBERNETES_DNS_SUBDOMAIN_NAME_MAX_LENGTH = 253
+ val KUBERNETES_DNS_LABEL_NAME_MAX_LENGTH = 63
}
diff --git a/resource-managers/kubernetes/core/src/main/scala/org/apache/spark/deploy/k8s/KubernetesConf.scala b/resource-managers/kubernetes/core/src/main/scala/org/apache/spark/deploy/k8s/KubernetesConf.scala
index 8a985c31b17..510609537cf 100644
--- a/resource-managers/kubernetes/core/src/main/scala/org/apache/spark/deploy/k8s/KubernetesConf.scala
+++ b/resource-managers/kubernetes/core/src/main/scala/org/apache/spark/deploy/k8s/KubernetesConf.scala
@@ -270,7 +270,7 @@ private[spark] object KubernetesConf {
.replaceAll("[^a-z0-9\\-]", "-")
.replaceAll("-+", "-"),
"",
- KUBERNETES_DNSNAME_MAX_LENGTH
+ KUBERNETES_DNS_LABEL_NAME_MAX_LENGTH
).stripPrefix("-").stripSuffix("-")
}
diff --git a/resource-managers/kubernetes/core/src/main/scala/org/apache/spark/deploy/k8s/features/BasicExecutorFeatureStep.scala b/resource-managers/kubernetes/core/src/main/scala/org/apache/spark/deploy/k8s/features/BasicExecutorFeatureStep.scala
index 15c69ad487f..8102ca84aff 100644
--- a/resource-managers/kubernetes/core/src/main/scala/org/apache/spark/deploy/k8s/features/BasicExecutorFeatureStep.scala
+++ b/resource-managers/kubernetes/core/src/main/scala/org/apache/spark/deploy/k8s/features/BasicExecutorFeatureStep.scala
@@ -106,10 +106,10 @@ private[spark] class BasicExecutorFeatureStep(
val keyToPaths = KubernetesClientUtils.buildKeyToPathObjects(confFilesMap)
// According to
// https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#dns-label-names,
- // hostname must be no longer than `KUBERNETES_DNSNAME_MAX_LENGTH`(63) characters,
+ // hostname must be no longer than `KUBERNETES_DNS_LABEL_NAME_MAX_LENGTH`(63) characters,
// so take the last 63 characters of the pod name as the hostname.
// This preserves uniqueness since the end of name contains executorId
- val hostname = name.substring(Math.max(0, name.length - KUBERNETES_DNSNAME_MAX_LENGTH))
+ val hostname = name.substring(Math.max(0, name.length - KUBERNETES_DNS_LABEL_NAME_MAX_LENGTH))
// Remove non-word characters from the start of the hostname
.replaceAll("^[^\\w]+", "")
// Replace dangerous characters in the remaining string with a safe alternative.
diff --git a/resource-managers/kubernetes/core/src/main/scala/org/apache/spark/deploy/k8s/features/DriverServiceFeatureStep.scala b/resource-managers/kubernetes/core/src/main/scala/org/apache/spark/deploy/k8s/features/DriverServiceFeatureStep.scala
index 75c40584a64..bc180488762 100644
--- a/resource-managers/kubernetes/core/src/main/scala/org/apache/spark/deploy/k8s/features/DriverServiceFeatureStep.scala
+++ b/resource-managers/kubernetes/core/src/main/scala/org/apache/spark/deploy/k8s/features/DriverServiceFeatureStep.scala
@@ -21,7 +21,7 @@ import scala.collection.JavaConverters._
import io.fabric8.kubernetes.api.model.{HasMetadata, ServiceBuilder}
import org.apache.spark.deploy.k8s.{KubernetesDriverConf, KubernetesUtils, SparkPod}
-import org.apache.spark.deploy.k8s.Config.KUBERNETES_DNSNAME_MAX_LENGTH
+import org.apache.spark.deploy.k8s.Config.KUBERNETES_DNS_LABEL_NAME_MAX_LENGTH
import org.apache.spark.deploy.k8s.Constants._
import org.apache.spark.internal.{config, Logging}
import org.apache.spark.util.{Clock, SystemClock}
@@ -101,5 +101,5 @@ private[spark] object DriverServiceFeatureStep {
val DRIVER_BIND_ADDRESS_KEY = config.DRIVER_BIND_ADDRESS.key
val DRIVER_HOST_KEY = config.DRIVER_HOST_ADDRESS.key
val DRIVER_SVC_POSTFIX = "-driver-svc"
- val MAX_SERVICE_NAME_LENGTH = KUBERNETES_DNSNAME_MAX_LENGTH
+ val MAX_SERVICE_NAME_LENGTH = KUBERNETES_DNS_LABEL_NAME_MAX_LENGTH
}
diff --git a/resource-managers/kubernetes/core/src/main/scala/org/apache/spark/deploy/k8s/submit/KubernetesClientUtils.scala b/resource-managers/kubernetes/core/src/main/scala/org/apache/spark/deploy/k8s/submit/KubernetesClientUtils.scala
index a26a7638a64..dc52babc5f3 100644
--- a/resource-managers/kubernetes/core/src/main/scala/org/apache/spark/deploy/k8s/submit/KubernetesClientUtils.scala
+++ b/resource-managers/kubernetes/core/src/main/scala/org/apache/spark/deploy/k8s/submit/KubernetesClientUtils.scala
@@ -29,16 +29,16 @@ import io.fabric8.kubernetes.api.model.{ConfigMap, ConfigMapBuilder, KeyToPath}
import org.apache.spark.SparkConf
import org.apache.spark.deploy.k8s.{Config, Constants, KubernetesUtils}
-import org.apache.spark.deploy.k8s.Config.{KUBERNETES_DNSNAME_MAX_LENGTH, KUBERNETES_NAMESPACE}
+import org.apache.spark.deploy.k8s.Config.{KUBERNETES_DNS_SUBDOMAIN_NAME_MAX_LENGTH, KUBERNETES_NAMESPACE}
import org.apache.spark.deploy.k8s.Constants.ENV_SPARK_CONF_DIR
import org.apache.spark.internal.Logging
private[spark] object KubernetesClientUtils extends Logging {
- // Config map name can be 63 chars at max.
+ // Config map name can be KUBERNETES_DNS_SUBDOMAIN_NAME_MAX_LENGTH chars at max.
def configMapName(prefix: String): String = {
val suffix = "-conf-map"
- s"${prefix.take(KUBERNETES_DNSNAME_MAX_LENGTH - suffix.length)}$suffix"
+ s"${prefix.take(KUBERNETES_DNS_SUBDOMAIN_NAME_MAX_LENGTH - suffix.length)}$suffix"
}
val configMapNameExecutor: String = configMapName(s"spark-exec-${KubernetesUtils.uniqueID()}")
diff --git a/resource-managers/kubernetes/core/src/test/scala/org/apache/spark/deploy/k8s/features/BasicExecutorFeatureStepSuite.scala b/resource-managers/kubernetes/core/src/test/scala/org/apache/spark/deploy/k8s/features/BasicExecutorFeatureStepSuite.scala
index 731a9b77d20..84c4f3b8ba3 100644
--- a/resource-managers/kubernetes/core/src/test/scala/org/apache/spark/deploy/k8s/features/BasicExecutorFeatureStepSuite.scala
+++ b/resource-managers/kubernetes/core/src/test/scala/org/apache/spark/deploy/k8s/features/BasicExecutorFeatureStepSuite.scala
@@ -199,18 +199,18 @@ class BasicExecutorFeatureStepSuite extends SparkFunSuite with BeforeAndAfter {
val step = new BasicExecutorFeatureStep(newExecutorConf(), new SecurityManager(baseConf),
defaultProfile)
assert(step.configurePod(SparkPod.initialPod()).pod.getSpec.getHostname.length ===
- KUBERNETES_DNSNAME_MAX_LENGTH)
+ KUBERNETES_DNS_LABEL_NAME_MAX_LENGTH)
}
}
test("SPARK-35460: invalid PodNamePrefixes") {
withPodNamePrefix {
- Seq("_123", "spark_exec", "spark@", "a" * 48).foreach { invalid =>
+ Seq("_123", "spark_exec", "spark@", "a" * 238).foreach { invalid =>
baseConf.set(KUBERNETES_EXECUTOR_POD_NAME_PREFIX, invalid)
val e = intercept[IllegalArgumentException](newExecutorConf())
assert(e.getMessage === s"'$invalid' in spark.kubernetes.executor.podNamePrefix is" +
s" invalid. must conform https://kubernetes.io/docs/concepts/overview/" +
- "working-with-objects/names/#dns-label-names and the value length <= 47")
+ "working-with-objects/names/#dns-subdomain-names and the value length <= 237")
}
}
}
@@ -224,7 +224,7 @@ class BasicExecutorFeatureStepSuite extends SparkFunSuite with BeforeAndAfter {
val step = new BasicExecutorFeatureStep(newExecutorConf(), new SecurityManager(baseConf),
defaultProfile)
val hostname = step.configurePod(SparkPod.initialPod()).pod.getSpec().getHostname()
- assert(hostname.length <= KUBERNETES_DNSNAME_MAX_LENGTH)
+ assert(hostname.length <= KUBERNETES_DNS_LABEL_NAME_MAX_LENGTH)
assert(InternetDomainName.isValid(hostname))
}
}
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@spark.apache.org
For additional commands, e-mail: commits-help@spark.apache.org