-
Notifications
You must be signed in to change notification settings - Fork 29k
[SPARK-37809][K8S] Add YuniKorn Feature Step
#35663
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
f6ed84e
e872fb7
d7205a1
568a97a
6fc3e79
ed3e21e
9089179
5b686db
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -426,6 +426,11 @@ object SparkBuild extends PomBuild { | |
| enable(Volcano.settings)(kubernetesIntegrationTests) | ||
| } | ||
|
|
||
| if (!profiles.contains("yunikorn")) { | ||
| enable(YuniKorn.settings)(kubernetes) | ||
| enable(YuniKorn.settings)(kubernetesIntegrationTests) | ||
| } | ||
|
|
||
| enable(KubernetesIntegrationTests.settings)(kubernetesIntegrationTests) | ||
|
|
||
| enable(YARN.settings)(yarn) | ||
|
|
@@ -973,6 +978,13 @@ object Volcano { | |
| ) | ||
| } | ||
|
|
||
| object YuniKorn { | ||
| // Exclude all yunikorn file for Compile and Test | ||
| lazy val settings = Seq( | ||
| unmanagedSources / excludeFilter ~= { _ || "*YuniKorn*.scala" } | ||
|
||
| ) | ||
| } | ||
|
|
||
| object Unidoc { | ||
|
|
||
| import BuildCommons._ | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,49 @@ | ||
| /* | ||
| * Licensed to the Apache Software Foundation (ASF) under one or more | ||
| * contributor license agreements. See the NOTICE file distributed with | ||
| * this work for additional information regarding copyright ownership. | ||
| * The ASF licenses this file to You under the Apache License, Version 2.0 | ||
| * (the "License"); you may not use this file except in compliance with | ||
| * the License. You may obtain a copy of the License at | ||
| * | ||
| * http://www.apache.org/licenses/LICENSE-2.0 | ||
| * | ||
| * Unless required by applicable law or agreed to in writing, software | ||
| * distributed under the License is distributed on an "AS IS" BASIS, | ||
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| * See the License for the specific language governing permissions and | ||
| * limitations under the License. | ||
| */ | ||
| package org.apache.spark.deploy.k8s.features | ||
|
|
||
| import io.fabric8.kubernetes.api.model._ | ||
|
|
||
| import org.apache.spark.deploy.k8s.{KubernetesConf, KubernetesDriverConf, KubernetesExecutorConf, SparkPod} | ||
|
|
||
| private[spark] class YuniKornFeatureStep extends KubernetesDriverCustomFeatureConfigStep | ||
| with KubernetesExecutorCustomFeatureConfigStep { | ||
|
|
||
| private var kubernetesConf: KubernetesConf = _ | ||
|
|
||
| override def init(config: KubernetesDriverConf): Unit = { | ||
| kubernetesConf = config | ||
| } | ||
|
|
||
| override def init(config: KubernetesExecutorConf): Unit = { | ||
| kubernetesConf = config | ||
| } | ||
|
|
||
| override def configurePod(pod: SparkPod): SparkPod = { | ||
| val k8sPodBuilder = new PodBuilder(pod.pod) | ||
| .editMetadata() | ||
| .addToAnnotations(YuniKornFeatureStep.AppIdAnnotationKey, kubernetesConf.appId) | ||
|
||
| .endMetadata() | ||
| val k8sPod = k8sPodBuilder.build() | ||
| SparkPod(k8sPod, pod.container) | ||
| } | ||
| } | ||
|
|
||
| object YuniKornFeatureStep { | ||
| val AppIdAnnotationKey = "yunikorn.apache.org/app-id" | ||
| val SchedulerName = "yunikorn" | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Apache Spark naming scheme use all CAPITAL for constants.
- val AppIdAnnotationKey = "yunikorn.apache.org/app-id"
- val SchedulerName = "yunikorn"
+ val APP_ID_ANNOTATION_KEY = "yunikorn.apache.org/app-id"
+ val SCHEDULER_NAME = "yunikorn"BTW, you are already using this style in this PR in the following. private[spark] object YuniKornTestsSuite extends SparkFunSuite {
val YUNIKORN_FEATURE_STEP = classOf[YuniKornFeatureStep].getName
} |
||
| } | ||
| Original file line number | Diff line number | Diff line change | ||||||
|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,43 @@ | ||||||||
| /* | ||||||||
| * Licensed to the Apache Software Foundation (ASF) under one or more | ||||||||
| * contributor license agreements. See the NOTICE file distributed with | ||||||||
| * this work for additional information regarding copyright ownership. | ||||||||
| * The ASF licenses this file to You under the Apache License, Version 2.0 | ||||||||
| * (the "License"); you may not use this file except in compliance with | ||||||||
| * the License. You may obtain a copy of the License at | ||||||||
| * | ||||||||
| * http://www.apache.org/licenses/LICENSE-2.0 | ||||||||
| * | ||||||||
| * Unless required by applicable law or agreed to in writing, software | ||||||||
| * distributed under the License is distributed on an "AS IS" BASIS, | ||||||||
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||||||
| * See the License for the specific language governing permissions and | ||||||||
| * limitations under the License. | ||||||||
| */ | ||||||||
| package org.apache.spark.deploy.k8s.features | ||||||||
|
|
||||||||
| import org.apache.spark.{SparkConf, SparkFunSuite} | ||||||||
| import org.apache.spark.deploy.k8s._ | ||||||||
|
|
||||||||
| class YuniKornFeatureStepSuite extends SparkFunSuite { | ||||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This PR seems to duplicate the existing test coverage. Could you remove this test suite? Line 41 in 74deefb
Line 85 in 74deefb
Line 92 in 74deefb
|
||||||||
|
|
||||||||
| test("SPARK-37809: Driver Pod with YuniKorn annotations") { | ||||||||
|
||||||||
| val sparkConf = new SparkConf() | ||||||||
| val kubernetesConf = KubernetesTestConf.createDriverConf(sparkConf) | ||||||||
| val step = new YuniKornFeatureStep() | ||||||||
| step.init(kubernetesConf) | ||||||||
| val configuredPod = step.configurePod(SparkPod.initialPod()) | ||||||||
| val annotations = configuredPod.pod.getMetadata.getAnnotations | ||||||||
| assert(annotations.get(YuniKornFeatureStep.AppIdAnnotationKey) === kubernetesConf.appId) | ||||||||
| } | ||||||||
|
|
||||||||
| test("SPARK-37809: Executor Pod with YuniKorn annotations") { | ||||||||
| val sparkConf = new SparkConf() | ||||||||
| val kubernetesConf = KubernetesTestConf.createExecutorConf(sparkConf) | ||||||||
| val step = new YuniKornFeatureStep() | ||||||||
| step.init(kubernetesConf) | ||||||||
| val configuredPod = step.configurePod(SparkPod.initialPod()) | ||||||||
| val annotations = configuredPod.pod.getMetadata.getAnnotations | ||||||||
| assert(annotations.get(YuniKornFeatureStep.AppIdAnnotationKey) === kubernetesConf.appId) | ||||||||
| } | ||||||||
| } | ||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,34 @@ | ||
| /* | ||
| * Licensed to the Apache Software Foundation (ASF) under one or more | ||
| * contributor license agreements. See the NOTICE file distributed with | ||
| * this work for additional information regarding copyright ownership. | ||
| * The ASF licenses this file to You under the Apache License, Version 2.0 | ||
| * (the "License"); you may not use this file except in compliance with | ||
| * the License. You may obtain a copy of the License at | ||
| * | ||
| * http://www.apache.org/licenses/LICENSE-2.0 | ||
| * | ||
| * Unless required by applicable law or agreed to in writing, software | ||
| * distributed under the License is distributed on an "AS IS" BASIS, | ||
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| * See the License for the specific language governing permissions and | ||
| * limitations under the License. | ||
| */ | ||
| package org.apache.spark.deploy.k8s.integrationtest | ||
|
|
||
| import org.scalatest.Tag | ||
|
|
||
| import org.apache.spark.deploy.k8s.features.YuniKornFeatureStep | ||
|
|
||
| class YuniKornSuite extends KubernetesSuite with YuniKornTestsSuite { | ||
|
|
||
| override protected def setUpTest(): Unit = { | ||
| super.setUpTest() | ||
| sparkAppConf | ||
| .set("spark.kubernetes.scheduler.name", YuniKornFeatureStep.SchedulerName) | ||
| } | ||
| } | ||
|
|
||
| private[spark] object YuniKornSuite { | ||
| val yunikornTag = Tag("yunikorn") | ||
| } |
| Original file line number | Diff line number | Diff line change | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,60 @@ | ||||||||||||
| /* | ||||||||||||
| * Licensed to the Apache Software Foundation (ASF) under one or more | ||||||||||||
| * contributor license agreements. See the NOTICE file distributed with | ||||||||||||
| * this work for additional information regarding copyright ownership. | ||||||||||||
| * The ASF licenses this file to You under the Apache License, Version 2.0 | ||||||||||||
| * (the "License"); you may not use this file except in compliance with | ||||||||||||
| * the License. You may obtain a copy of the License at | ||||||||||||
| * | ||||||||||||
| * http://www.apache.org/licenses/LICENSE-2.0 | ||||||||||||
| * | ||||||||||||
| * Unless required by applicable law or agreed to in writing, software | ||||||||||||
| * distributed under the License is distributed on an "AS IS" BASIS, | ||||||||||||
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||||||||||
| * See the License for the specific language governing permissions and | ||||||||||||
| * limitations under the License. | ||||||||||||
| */ | ||||||||||||
| package org.apache.spark.deploy.k8s.integrationtest | ||||||||||||
|
|
||||||||||||
| import io.fabric8.kubernetes.api.model.Pod | ||||||||||||
|
|
||||||||||||
| import org.apache.spark.SparkFunSuite | ||||||||||||
| import org.apache.spark.deploy.k8s.features.YuniKornFeatureStep | ||||||||||||
| import org.apache.spark.deploy.k8s.integrationtest.KubernetesSuite.k8sTestTag | ||||||||||||
| import org.apache.spark.deploy.k8s.integrationtest.YuniKornSuite.yunikornTag | ||||||||||||
|
|
||||||||||||
| private[spark] trait YuniKornTestsSuite { k8sSuite: KubernetesSuite => | ||||||||||||
| import YuniKornTestsSuite._ | ||||||||||||
|
|
||||||||||||
| protected def checkScheduler(pod: Pod): Unit = { | ||||||||||||
| assert(pod.getSpec.getSchedulerName === YuniKornFeatureStep.SchedulerName) | ||||||||||||
| } | ||||||||||||
|
|
||||||||||||
| protected def checkAnnotations(pod: Pod): Unit = { | ||||||||||||
| val appId = pod.getMetadata.getLabels.get("spark-app-selector") | ||||||||||||
| val annotations = pod.getMetadata.getAnnotations | ||||||||||||
| assert(annotations.get(YuniKornFeatureStep.AppIdAnnotationKey) === appId) | ||||||||||||
| } | ||||||||||||
|
|
||||||||||||
| test("Run SparkPi with yunikorn scheduler", k8sTestTag, yunikornTag) { | ||||||||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We need the actual YuniKorn feature test coverage here. Otherwise, we cannot prevent the future regression. Technically, I don't think Line 304 in 74deefb
Line 321 in 74deefb
Line 338 in 74deefb
Line 360 in 74deefb
Line 380 in 74deefb
|
||||||||||||
| sparkAppConf | ||||||||||||
| .set("spark.kubernetes.driver.pod.featureSteps", YUNIKORN_FEATURE_STEP) | ||||||||||||
| .set("spark.kubernetes.executor.pod.featureSteps", YUNIKORN_FEATURE_STEP) | ||||||||||||
| runSparkPiAndVerifyCompletion( | ||||||||||||
| driverPodChecker = (driverPod: Pod) => { | ||||||||||||
| doBasicDriverPodCheck(driverPod) | ||||||||||||
| checkScheduler(driverPod) | ||||||||||||
| checkAnnotations(driverPod) | ||||||||||||
| }, | ||||||||||||
| executorPodChecker = (executorPod: Pod) => { | ||||||||||||
| doBasicExecutorPodCheck(executorPod) | ||||||||||||
| checkScheduler(executorPod) | ||||||||||||
| checkAnnotations(executorPod) | ||||||||||||
| } | ||||||||||||
| ) | ||||||||||||
| } | ||||||||||||
| } | ||||||||||||
|
|
||||||||||||
| private[spark] object YuniKornTestsSuite extends SparkFunSuite { | ||||||||||||
| val YUNIKORN_FEATURE_STEP = classOf[YuniKornFeatureStep].getName | ||||||||||||
| } | ||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit.
file->files. Last time, we missed this atVolcanoPR.