优先级和抢占#

SkyPilot 支持基于优先级的调度、抢占以及在 Kubernetes 上运行的作业的重新排队。您可以通过利用 Kubernetes 原生的优先级类来实现这一点。

提示

带有优先级和抢占功能的作业仅在 Kubernetes 上受支持。

设置作业优先级

  1. 在您的 Kubernetes 集群中创建优先级类

  2. 通过设置 config.kubernetes.pod_config.spec.priorityClassName在 SkyPilot 作业中设置优先级类

  3. 使用sky jobs launch来启动您的作业。

通过此设置,当资源受限时,您可以运行高优先级作业来抢占低优先级作业。

工作示例#

下面我们展示一个包含两个优先级类(high-prioritylow-priority)的示例运行。

步骤 1:创建优先级类#

在您的 Kubernetes 集群中创建两个优先级类

# priorities.yaml
apiVersion: scheduling.k8s.io/v1
kind: PriorityClass
metadata:
  name: high-priority
value: 200
globalDefault: false
description: "High priority class for critical jobs"
---
apiVersion: scheduling.k8s.io/v1
kind: PriorityClass
metadata:
  name: low-priority
value: 100
globalDefault: true
description: "Low priority class for background jobs"

值越大表示优先级越高。您可以创建任意数量的优先级类。

将这些优先级类应用于您的集群

$ kubectl apply -f priorities.yaml

步骤 2:在 SkyPilot 作业中设置优先级#

要为您的 SkyPilot 作业分配优先级,请在 SkyPilot YAML 中使用 config.kubernetes.pod_config 字段。

在此示例中,我们使用两个简单的计数器作业

# high-priority-job.yaml
resources:
  cloud: kubernetes
  cpus: 4

run: |
  python -c '
  import time
  for i in range(1000):
      print(f"High priority counter: {i}")
      time.sleep(1)
  '

config:
  kubernetes:
    pod_config:
      spec:
        priorityClassName: high-priority
# low-priority-job.yaml
resources:
  cloud: kubernetes
  cpus: 4

run: |
  python -c '
  import time
  for i in range(1000):
      print(f"Low priority counter: {i}")
      time.sleep(1)
  '

config:
  kubernetes:
    pod_config:
        spec:
          priorityClassName: low-priority

提示

要查看抢占行为,请务必设置 resources.cpu 字段,以便在一个作业运行后,集群中没有剩余 CPU 可用于其他作业。

您可以使用 kubectl get nodes 来检查集群中的 CPU 总数。

步骤 3:启动您的作业#

使用 sky jobs launch 将您的作业作为托管作业启动。首先,我们启动低优先级作业

$ sky jobs launch low-priority-job.yaml

然后启动高优先级作业

$ sky jobs launch high-priority-job.yaml

使用 sky jobs queue 来查看您的作业状态。您将看到高优先级作业立即开始运行,并且低优先级作业被抢占。

低优先级作业将处于 RECOVERING 状态。当资源可用时,SkyPilot 将自动重启低优先级作业。

$ sky jobs queue
Fetching managed job statuses...
Managed jobs
In progress tasks: 1 RECOVERING, 1 RUNNING
ID  NAME             RESOURCES  SUBMITTED   TOT. DURATION  #RECOVERIES  STATUS
2   sky-0232-romilb  1x[CPU:4]  5 mins ago  5m 35s         0            RUNNING
1   sky-0d6f-romilb  1x[CPU:4]  7 mins ago  7m 13s         1            RECOVERING

一旦高优先级作业完成,低优先级作业将再次开始运行。

$ sky jobs queue
Fetching managed job statuses...
Managed jobs
No in-progress managed jobs.
ID  NAME             RESOURCES  SUBMITTED    TOT. DURATION  #RECOVERIES  STATUS
2   sky-0232-romilb  1x[CPU:4]  23 mins ago  17m 22s        0            SUCCEEDED
1   sky-0d6f-romilb  1x[CPU:4]  25 mins ago  23m 47s        1            RUNNING

优先级和抢占的工作原理#

当集群没有足够的资源来运行所有作业时,高优先级作业将抢占低优先级作业。这意味着低优先级作业的 pod 将被终止,以便为高优先级作业腾出空间。

当资源再次可用时,被抢占的作业将由 SkyPilot 自动重新调度。您可以在代码中设置检查点和恢复以减少浪费的工作。

具有相同优先级级别的作业遵循 SkyPilot 的默认调度行为

提示

您还可以将优先级类应用于非托管的 SkyPilot 集群。但是,当非托管集群被抢占时,它们不会自动重新启动。

限制#

  1. 优先级设置仅适用于 Kubernetes 集群内。

  2. 抢占行为取决于您的集群配置,并且可能会抢占集群中的其他 pod。

更多信息请参考Kubernetes 关于 Pod 优先级和抢占的文档