【问题标题】:Schedule pod on specific node without modifying PodSpec在特定节点上调度 pod,无需修改 PodSpec
【发布时间】:2018-04-03 12:55:06
【问题描述】:

作为 k8s 集群管理员,我想指定将在哪些节点(使用标签)上调度 Pod,但不修改任何 PodSpec 部分。

因此,nodeSelector、affinity 和 taints 不能是选项。 还有其他解决办法吗?

PS:我无法修改 PodSpec 的原因是部署的应用程序可以作为 Helm 图表使用,而我没有这些文件。此外,如果我更改 PodSpec,它将在下一次版本升级时丢失。

【问题讨论】:

  • helm 图表/模板是否意味着在部署时使用--value 或--set, 修饰符进行修改?如果您可以触发相同的命令(仅更改要升级的原始图表的版本),为什么升级会成为问题?
  • 很遗憾没有。否则我会使用 values.yaml 中的定义。感谢您对两年前的 SO btw 的考虑;)

标签: kubernetes


【解决方案1】:

您可以为此使用PodNodeSelector 准入控制器:

此准入控制器具有以下行为:

  1. 如果命名空间有一个带有键 scheduler.kubernetes.io/nodeSelector 的注释,则使用它的值作为节点选择器。
  2. 如果命名空间缺少这样的注解,请使用 PodNodeSelector 插件配置文件中定义的clusterDefaultNodeSelector 作为节点选择器。
  3. 根据命名空间节点选择器评估 pod 的节点选择器是否存在冲突。冲突会导致拒绝。
  4. 根据插件配置文件定义的命名空间特定白名单评估 pod 的节点选择器。冲突会导致拒绝。

首先您需要enable this admission controller。启用方式取决于您的环境,但通过参数kube-apiserver --enable-admission-plugins=PodNodeSelector 完成。

然后创建一个命名空间并使用您希望该命名空间中的所有 Pod 具有的任何节点标签对其进行注释:

kubectl create ns node-selector-test
kubectl annotate ns node-selector-test \
    scheduler.alpha.kubernetes.io/node-selector=mynodelabel=mynodelabelvalue

要对其进行测试,您可以执行以下操作:

kubectl run busybox \
    -n node-selector-test -it --restart=Never --attach=false --image=busybox

kubectl get pod busybox -n node-selector-test -o yaml

它应该输出如下内容:

apiVersion: v1
kind: Pod 
metadata:
  name: busybox
  ....
spec:
  ...
  nodeSelector:
    mynodelabel: mynodelabelvalue

现在,除非该标签存在于某些节点上,否则此 Pod 将永远不会被调度,因此将此标签放在节点上以查看它的调度:

kubectl label node myfavoritenode mynodelabel=mynodelabelvalue

【讨论】:

  • 对他有什么帮助?是的,他可以使用准入控制器,但唯一的结果是在选定节点上的命名空间中调度所有 pod。他不想更改规范并希望通过 Helm 创建新的部署,但是使用您的解决方案,他无论如何都需要它,至少将所有图表拆分为不同的命名空间。但是,如果您无论如何都需要重新创建版本,那么使用只能部分解决问题的解决方案的原因是什么?此外,如果您需要在一个版本中在不同节点上运行 pod,这也无济于事。
  • 我不同意,安东。他可以helm install --namespace=node-selector-test,这比更改所有Pod模板要容易得多。
  • 但是该命令将创建一个新的部署,至少您需要以某种方式在 2 个不同的命名空间中同时管理 2 个应用程序副本。这可能会导致大问题。此外,如果你无论如何都要创建一个新的部署,为什么不在 pod 中使用选择器而不是准入控制器呢?
  • 嗨!很抱歉我的问题不是很积极。我喜欢在 PodSpec 上使用准入控制器的方式,因为它解耦了 pod 必须如何运行和必须在何处运行。但是,您在命名空间上的解决方案对我没有多大帮助,因为我将所有 pod 部署在默认命名空间中(我按环境使用了多个 GCP 项目和 GKE 集群)。将尝试根据 pod 标签/注释搜索节点选择器。
【解决方案2】:

不,没有其他方法可以指定将在哪些节点上调度 pod,只有标签和选择器。

我认为 Helm 的问题与 issue 有关。

目前,您唯一的方法是更改​​规范、删除版本并部署具有更新规范的新版本。

UPD

@Janos Lenart 提供了一种管理每个命名空间调度的方法。如果您的版本已经在命名空间之间拆分,并且您不想在单个版本中在不同节点上生成不同的 pod,那么这是一个好主意。否则,您将不得不在新命名空间中创建新版本,在这种情况下,我强烈建议您使用 Pods 规范中的选择器。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-10-14
    • 2018-09-29
    • 1970-01-01
    • 2020-04-10
    • 2020-12-14
    • 1970-01-01
    • 2016-03-10
    相关资源
    最近更新 更多