AWS EKS K8s 服务和 CronJob/Jon 同一节点 nodeSelectornodeAffinity

问题描述

我有一个 k8s 部署,它由一个 cron 作业(每小时运行一次)、服务(运行 http 服务)和一个存储类(pvc 来存储数据,使用 gp2)组成。

我看到的问题是 gp2 只能读写一次。

我注意到当 cron 作业创建一个作业并且它与它可以正常安装它的服务位于同一节点上时。

我可以在服务、部署或 cron 作业 yaml 中做些什么来确保 cron 作业和服务始终位于同一节点上?它可以是任何节点,但只要 cron 作业与服务去往同一个节点即可。

这在我的较低环境中不是问题,因为我们的节点很少,但在我们有更多节点的生产环境中,这是一个问题。

简而言之,我想获得我的 cron 作业,它会创建一个作业,然后创建一个 pod,以便在我的服务 pod 所在的同一节点上运行该 pod。

我知道这不是最佳实践,但我们的网络服务从 pvc 读取数据并提供它。 cron 作业从其他来源提取新数据并将其留给网络服务器。

为其他想法/方式感到高兴。

谢谢

解决方法

只关注部分:

如何在一组特定的 Pod 上安排工作负载(JobCronjobNodes

您可以通过以下方式生成您的 Cronjob/Job

  • nodeSelector
  • nodeAffinity

nodeSelector

nodeSelector 是最简单的推荐形式的节点选择约束。 nodeSelector 是 PodSpec 的一个字段。它指定键值对的映射。要使 pod 有资格在节点上运行,该节点必须将每个指定的键值对作为标签(它也可以有其他标签)。最常见的用法是一对键值对。

-- Kubernetes.io: Docs: Concepts: Scheduling eviction: Assign pod node: Node selector

示例如下(假设您的节点具有在 .spec.jobTemplate.spec.template.spec.nodeSelector 中引用的特定标签):

apiVersion: batch/v1beta1
kind: CronJob
metadata:
  name: hello
spec:
  schedule: "*/1 * * * *"
  jobTemplate:
    spec:
      template:
        spec:
          nodeSelector: # <-- IMPORTANT
            schedule: "here" # <-- IMPORTANT
          containers:
          - name: hello
            image: busybox
            imagePullPolicy: IfNotPresent
            command:
            - /bin/sh
            - -c
            - date; echo Hello from the Kubernetes cluster
          restartPolicy: OnFailure

在清单上方运行将在具有 Pod 标签的节点上安排您的 Cronjob (schedule=here):

  • $ kubectl get pods -o wide
NAME                     READY   STATUS      RESTARTS   AGE     IP          NODE                                   NOMINATED NODE   READINESS GATES
hello-1616323740-mqdmq   0/1     Completed   0          2m33s   10.4.2.67   node-ffb5                              <none>           <none>
hello-1616323800-wv98r   0/1     Completed   0          93s     10.4.2.68   node-ffb5                              <none>           <none>
hello-1616323860-66vfj   0/1     Completed   0          32s     10.4.2.69   node-ffb5                              <none>           <none>

nodeAffinity

节点亲缘关系在概念上类似于 nodeSelector - 它允许您根据节点上的标签限制您的 pod 有资格在哪些节点上进行调度。

目前有两种类型的节点亲缘关系,称为 requiredDuringSchedulingIgnoredDuringExecutionpreferredDuringSchedulingIgnoredDuringExecution。您可以将它们分别视为“硬”和“软”,因为前者指定了将 pod 调度到节点上必须满足的规则(就像 nodeSelector 但使用更具表现力的语法),而后者指定调度程序将尝试强制执行但不会保证的首选项。

-- Kubernetes.io: Docs: Concepts: Scheduling eviction: Assign pod node: Node affinity

示例如下(假设您的节点具有在 .spec.jobTemplate.spec.template.spec.nodeSelector 中引用的特定标签):

apiVersion: batch/v1beta1
kind: CronJob
metadata:
  name: hello
spec:
  schedule: "*/1 * * * *"
  jobTemplate:
    spec:
      template:
        spec:
          # --- nodeAffinity part
          affinity:
            nodeAffinity:
              requiredDuringSchedulingIgnoredDuringExecution:
                nodeSelectorTerms:
                - matchExpressions:
                  - key: schedule
                    operator: In
                    values:
                    - here
          # --- nodeAffinity part
          containers:
          - name: hello
            image: busybox
            imagePullPolicy: IfNotPresent
            command:
            - /bin/sh
            - -c
            - date; echo Hello from the Kubernetes cluster
          restartPolicy: OnFailure
  • $ kubectl get pods
NAME                     READY   STATUS      RESTARTS   AGE     IP           NODE                                   NOMINATED NODE   READINESS GATES
hello-1616325840-5zkbk   0/1     Completed   0          2m14s   10.4.2.102   node-ffb5                              <none>           <none>
hello-1616325900-lwndf   0/1     Completed   0          74s     10.4.2.103   node-ffb5                              <none>           <none>
hello-1616325960-j9kz9   0/1     Completed   0          14s     10.4.2.104   node-ffb5                              <none>           <none>

其他资源:

我想你也可以看看这个 StackOverflow 的答案:

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...