From 4e78248238d2eca40b57875b30c5e596906dc495 Mon Sep 17 00:00:00 2001 From: Aaron Wang Date: Fri, 26 May 2023 09:21:23 +0800 Subject: [PATCH] [Feature][K8S Task] support node selector (#14126) * feat: support K8S node selector * fix CI --- docs/docs/en/guide/task/kubernetes.md | 21 ++-- docs/docs/zh/guide/task/kubernetes.md | 21 ++-- .../task/api/k8s/K8sTaskMainParameters.java | 3 + .../task/api/k8s/impl/K8sTaskExecutor.java | 12 ++ .../api/model/NodeSelectorExpression.java | 45 +++++++ .../api/parameters/K8sTaskParameters.java | 2 + .../task/api/k8s/K8sTaskExecutorTest.java | 8 ++ .../plugin/task/k8s/K8sTask.java | 28 ++++- .../plugin/task/k8s/K8sParametersTest.java | 5 + .../plugin/task/k8s/K8sTaskTest.java | 8 +- .../src/components/form/fields/get-field.ts | 2 +- .../src/locales/en_US/project.ts | 3 + .../src/locales/zh_CN/project.ts | 3 + .../task/components/node/fields/index.ts | 1 + .../task/components/node/fields/use-k8s.ts | 5 +- .../node/fields/use-node-selectors.ts | 117 ++++++++++++++++++ .../task/components/node/format-data.ts | 1 + .../task/components/node/tasks/use-k8s.ts | 1 + .../projects/task/components/node/types.ts | 11 +- 19 files changed, 267 insertions(+), 30 deletions(-) create mode 100644 dolphinscheduler-task-plugin/dolphinscheduler-task-api/src/main/java/org/apache/dolphinscheduler/plugin/task/api/model/NodeSelectorExpression.java create mode 100644 dolphinscheduler-ui/src/views/projects/task/components/node/fields/use-node-selectors.ts diff --git a/docs/docs/en/guide/task/kubernetes.md b/docs/docs/en/guide/task/kubernetes.md index aa0660c423..f5b06d3bc8 100644 --- a/docs/docs/en/guide/task/kubernetes.md +++ b/docs/docs/en/guide/task/kubernetes.md @@ -16,16 +16,17 @@ K8S task type used to execute a batch task. In this task, the worker submits the - Please refer to [DolphinScheduler Task Parameters Appendix](appendix.md) `Default Task Parameters` section for default parameters. -| **Parameter** | **Description** | -|------------------|------------------------------------------------------------------------------------------------------------------| -| Namespace | The namespace for running k8s task. | -| Min CPU | Minimum CPU requirement for running k8s task. | -| Min Memory | Minimum memory requirement for running k8s task. | -| Image | The registry url for image. | -| Command | The container execution command (yaml-style array), for example: ["printenv"] | -| Args | The args of execution command (yaml-style array), for example: ["HOSTNAME", "KUBERNETES_PORT"] | -| Custom label | The customized labels for k8s Job. | -| Custom parameter | It is a local user-defined parameter for K8S task, these params will pass to container as environment variables. | +| **Parameter** | **Description** | +|------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| Namespace | The namespace for running k8s task. | +| Min CPU | Minimum CPU requirement for running k8s task. | +| Min Memory | Minimum memory requirement for running k8s task. | +| Image | The registry url for image. | +| Command | The container execution command (yaml-style array), for example: ["printenv"] | +| Args | The args of execution command (yaml-style array), for example: ["HOSTNAME", "KUBERNETES_PORT"] | +| Custom label | The customized labels for k8s Job. | +| Node selector | The label selectors for running k8s pod. Different value in value set should be seperated by command, for example: `value1,value2`. You can refer to https://kubernetes.io/docs/reference/kubernetes-api/common-definitions/node-selector-requirement/ for configuration of different operators. | +| Custom parameter | It is a local user-defined parameter for K8S task, these params will pass to container as environment variables. | ## Task Example diff --git a/docs/docs/zh/guide/task/kubernetes.md b/docs/docs/zh/guide/task/kubernetes.md index bc5959c093..0409f116eb 100644 --- a/docs/docs/zh/guide/task/kubernetes.md +++ b/docs/docs/zh/guide/task/kubernetes.md @@ -16,16 +16,17 @@ kubernetes任务类型,用于在kubernetes上执行一个短时和批处理的 - 默认参数说明请参考[DolphinScheduler任务参数附录](appendix.md)`默认任务参数`一栏。 -| **任务参数** | **描述** | -|----------|-----------------------------------------------------------------| -| 命名空间 | 选择kubernetes集群上存在的命名空间 | -| 最小CPU | 任务在kubernetes上运行所需的最小CPU | -| 最小内存 | 任务在kubernetes上运行所需的最小内存 | -| 镜像 | 镜像地址 | -| 容器执行命令 | 容器执行命令(yaml格式数组),例如:["printenv"] | -| 执行命令参数 | 执行命令参数(yaml格式数组),例如:["HOSTNAME", "KUBERNETES_PORT"] | -| 自定义标签 | 作业自定义标签 | -| 自定义参数 | kubernetes任务局部的用户自定义参数,自定义参数最终会通过环境变量形式存在于容器中,提供给kubernetes任务使用 | +| **任务参数** | **描述** | +|----------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| 命名空间 | 选择kubernetes集群上存在的命名空间 | +| 最小CPU | 任务在kubernetes上运行所需的最小CPU | +| 最小内存 | 任务在kubernetes上运行所需的最小内存 | +| 镜像 | 镜像地址 | +| 容器执行命令 | 容器执行命令(yaml格式数组),例如:["printenv"] | +| 执行命令参数 | 执行命令参数(yaml格式数组),例如:["HOSTNAME", "KUBERNETES_PORT"] | +| 自定义标签 | 作业自定义标签 | +| 节点选择器 | 定义Pod在kubernetes集群上运行的标签选择器,值集中不同表达式值使用逗号分割,例如:`value1,value2`,不同操作符配置方式可参考:https://kubernetes.io/zh-cn/docs/reference/kubernetes-api/common-definitions/node-selector-requirement/ | +| 自定义参数 | kubernetes任务局部的用户自定义参数,自定义参数最终会通过环境变量形式存在于容器中,提供给kubernetes任务使用 | ## 任务样例 diff --git a/dolphinscheduler-task-plugin/dolphinscheduler-task-api/src/main/java/org/apache/dolphinscheduler/plugin/task/api/k8s/K8sTaskMainParameters.java b/dolphinscheduler-task-plugin/dolphinscheduler-task-api/src/main/java/org/apache/dolphinscheduler/plugin/task/api/k8s/K8sTaskMainParameters.java index 43d7e4278f..ec2b1cab38 100644 --- a/dolphinscheduler-task-plugin/dolphinscheduler-task-api/src/main/java/org/apache/dolphinscheduler/plugin/task/api/k8s/K8sTaskMainParameters.java +++ b/dolphinscheduler-task-plugin/dolphinscheduler-task-api/src/main/java/org/apache/dolphinscheduler/plugin/task/api/k8s/K8sTaskMainParameters.java @@ -17,9 +17,11 @@ package org.apache.dolphinscheduler.plugin.task.api.k8s; +import java.util.List; import java.util.Map; import lombok.Data; +import io.fabric8.kubernetes.api.model.NodeSelectorRequirement; /** * k8s task parameters @@ -36,4 +38,5 @@ public class K8sTaskMainParameters { private double minMemorySpace; private Map paramsMap; private Map labelMap; + private List nodeSelectorRequirements; } diff --git a/dolphinscheduler-task-plugin/dolphinscheduler-task-api/src/main/java/org/apache/dolphinscheduler/plugin/task/api/k8s/impl/K8sTaskExecutor.java b/dolphinscheduler-task-plugin/dolphinscheduler-task-api/src/main/java/org/apache/dolphinscheduler/plugin/task/api/k8s/impl/K8sTaskExecutor.java index ea15cdb5f8..109304675e 100644 --- a/dolphinscheduler-task-plugin/dolphinscheduler-task-api/src/main/java/org/apache/dolphinscheduler/plugin/task/api/k8s/impl/K8sTaskExecutor.java +++ b/dolphinscheduler-task-plugin/dolphinscheduler-task-api/src/main/java/org/apache/dolphinscheduler/plugin/task/api/k8s/impl/K8sTaskExecutor.java @@ -57,6 +57,7 @@ import java.util.concurrent.TimeUnit; import org.slf4j.Logger; import io.fabric8.kubernetes.api.model.EnvVar; +import io.fabric8.kubernetes.api.model.NodeSelectorTerm; import io.fabric8.kubernetes.api.model.Quantity; import io.fabric8.kubernetes.api.model.ResourceRequirements; import io.fabric8.kubernetes.api.model.batch.v1.Job; @@ -125,6 +126,9 @@ public class K8sTaskExecutor extends AbstractK8sTaskExecutor { throw new TaskException("Parse yaml-like commands and args failed", e); } + NodeSelectorTerm nodeSelectorTerm = new NodeSelectorTerm(); + nodeSelectorTerm.setMatchExpressions(k8STaskMainParameters.getNodeSelectorRequirements()); + return new JobBuilder() .withApiVersion(API_VERSION) .withNewMetadata() @@ -146,6 +150,14 @@ public class K8sTaskExecutor extends AbstractK8sTaskExecutor { .withEnv(envVars) .endContainer() .withRestartPolicy(RESTART_POLICY) + .withNewAffinity() + .withNewNodeAffinity() + .withNewRequiredDuringSchedulingIgnoredDuringExecution() + .addNewNodeSelectorTermLike(nodeSelectorTerm) + .endNodeSelectorTerm() + .endRequiredDuringSchedulingIgnoredDuringExecution() + .endNodeAffinity() + .endAffinity() .endSpec() .endTemplate() .withBackoffLimit(retryNum) diff --git a/dolphinscheduler-task-plugin/dolphinscheduler-task-api/src/main/java/org/apache/dolphinscheduler/plugin/task/api/model/NodeSelectorExpression.java b/dolphinscheduler-task-plugin/dolphinscheduler-task-api/src/main/java/org/apache/dolphinscheduler/plugin/task/api/model/NodeSelectorExpression.java new file mode 100644 index 0000000000..b4c4f6dc7e --- /dev/null +++ b/dolphinscheduler-task-plugin/dolphinscheduler-task-api/src/main/java/org/apache/dolphinscheduler/plugin/task/api/model/NodeSelectorExpression.java @@ -0,0 +1,45 @@ +/* + * 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.dolphinscheduler.plugin.task.api.model; + +import java.io.Serializable; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@NoArgsConstructor +@AllArgsConstructor +public class NodeSelectorExpression implements Serializable { + + /** + * selector key + */ + private String key; + + /** + * selector operator + */ + private String operator; + + /** + * selector value + */ + private String values; +} diff --git a/dolphinscheduler-task-plugin/dolphinscheduler-task-api/src/main/java/org/apache/dolphinscheduler/plugin/task/api/parameters/K8sTaskParameters.java b/dolphinscheduler-task-plugin/dolphinscheduler-task-api/src/main/java/org/apache/dolphinscheduler/plugin/task/api/parameters/K8sTaskParameters.java index d11cc381ab..be1c5d0c62 100644 --- a/dolphinscheduler-task-plugin/dolphinscheduler-task-api/src/main/java/org/apache/dolphinscheduler/plugin/task/api/parameters/K8sTaskParameters.java +++ b/dolphinscheduler-task-plugin/dolphinscheduler-task-api/src/main/java/org/apache/dolphinscheduler/plugin/task/api/parameters/K8sTaskParameters.java @@ -18,6 +18,7 @@ package org.apache.dolphinscheduler.plugin.task.api.parameters; import org.apache.dolphinscheduler.plugin.task.api.model.Label; +import org.apache.dolphinscheduler.plugin.task.api.model.NodeSelectorExpression; import org.apache.dolphinscheduler.plugin.task.api.model.ResourceInfo; import org.apache.commons.lang3.StringUtils; @@ -37,6 +38,7 @@ public class K8sTaskParameters extends AbstractParameters { private String namespace; private String command; private List