作业故障排除
此文档介绍如何排查待处理的 Kubernetes 作业,但大多数思路可以推断到其他 受支持的作业类型。
请参阅 Kueue 概述,以了解协作运行作业的组件。
在此文档中,假设你的作业名为 my-job
,位于 my-namespace
命名空间中。
识别作业的工作负载
对于每个作业,Kueue 会创建一个 工作负载 对象来保存有关作业准入的详细信息,无论是否准入。
要查找作业的工作负载,可以使用以下任何步骤
可以通过运行以下命令从作业事件中获取工作负载名称
kubectl describe job -n my-namespace my-job
相关的事件将如下所示
Normal CreatedWorkload 24s batch/job-kueue-controller Created Workload: my-namespace/job-my-job-19797
Kueue 在标签
kueue.x-k8s.io/job-uid
中包含源作业的 UID。可以使用以下命令获取工作负载名称JOB_UID=$(kubectl get job -n my-namespace my-job -o jsonpath='{.metadata.uid}') kubectl get workloads -n my-namespace -l "kueue.x-k8s.io/job-uid=$JOB_UID"
输出如下所示
NAME QUEUE RESERVED IN ADMITTED AGE job-my-job-19797 user-queue cluster-queue True 9m45s
可以列出作业所在命名空间中的所有工作负载,并识别与格式
<api-name>-<job-name>-<hash>
匹配的工作负载。可以运行如下命令kubectl get workloads -n my-namespace | grep job-my-job
输出如下所示
NAME QUEUE RESERVED IN ADMITTED AGE job-my-job-19797 user-queue cluster-queue True 9m45s
识别出工作负载的名称后,可以通过运行以下命令获取所有详细信息
kubectl describe workload -n my-namespace job-my-job-19797
我的作业是否已暂停?
要了解作业是否已暂停,请通过运行以下命令查找 .spec.suspend
字段的值
kubectl get job -n my-namespace my-job -o jsonpath='{.spec.suspend}'
当作业暂停时,Kubernetes 不会为作业创建任何 Pod。如果作业已经运行 Pod,Kubernetes 会终止并删除这些 Pod。
当 Kueue 尚未准入作业或当作业被抢占以容纳另一个作业时,作业将被暂停。要了解作业暂停的原因,请检查相应的 Workload 对象。
我的作业是否已准入?
如果作业未运行,请检查 Kueue 是否已准入工作负载。
了解作业是否已准入、正在处理还是尚未尝试准入的起点是查看工作负载状态。
运行以下命令以获取工作负载的完整状态
kubectl get workload -n my-namespace my-workload -o yaml
已准许的工作负载
如果你的作业已准许,工作负载应具有类似于以下内容的状态
apiVersion: kueue.x-k8s.io/v1beta1
kind: Workload
...
status:
admission:
clusterQueue: cluster-queue
podSetAssignments:
- count: 3
flavors:
cpu: default-flavor
memory: default-flavor
name: main
resourceUsage:
cpu: "3"
memory: 600Mi
conditions:
- lastTransitionTime: "2024-03-19T20:49:17Z"
message: Quota reserved in ClusterQueue cluster-queue
reason: QuotaReserved
status: "True"
type: QuotaReserved
- lastTransitionTime: "2024-03-19T20:49:17Z"
message: The workload is admitted
reason: Admitted
status: "True"
type: Admitted
待处理的工作负载
如果 Kueue 已尝试准许工作负载,但由于配额不足而失败,则工作负载应具有类似于以下内容的状态
status:
conditions:
- lastTransitionTime: "2024-03-21T13:43:00Z"
message: 'couldn''t assign flavors to pod set main: insufficient quota for cpu
in flavor default-flavor in ClusterQueue'
reason: Pending
status: "False"
type: QuotaReserved
我的 ClusterQueue 是否具有作业所需的资源请求?
当你提交具有资源请求的作业时,例如
$ kubectl get jobs job-0-9-size-6 -o json | jq -r .spec.template.spec.containers[0].resources
{
"limits": {
"cpu": "2"
},
"requests": {
"cpu": "2"
}
}
如果你的 ClusterQueue 没有 requests
的定义,Kueue 无法准许该作业。对于上述作业,你应在 resourceGroups
下定义 cpu
配额。定义 cpu
配额的 ClusterQueue 如下所示
apiVersion: kueue.x-k8s.io/v1beta1
kind: ClusterQueue
metadata:
name: "cluster-queue"
spec:
namespaceSelector: {}
resourceGroups:
- coveredResources: ["cpu"]
flavors:
- name: "default-flavor"
resources:
- name: "cpu"
nominalQuota: 40
有关更多信息,请参阅 资源组。
待处理准许检查
当 ClusterQueue 配置了 准许检查,例如 ProvisioningRequest 或 MultiKueue 时,工作负载可能保持类似于以下内容的状态,直到准许检查通过
status:
admission:
clusterQueue: dws-cluster-queue
podSetAssignments:
...
admissionChecks:
- lastTransitionTime: "2024-05-03T20:01:59Z"
message: ""
name: dws-prov
state: Pending
conditions:
- lastTransitionTime: "2024-05-03T20:01:59Z"
message: Quota reserved in ClusterQueue dws-cluster-queue
reason: QuotaReserved
status: "True"
type: QuotaReserved
未尝试的工作负载
当使用具有 StrictFIFO
queueingStrategy
的 ClusterQueue 时,Kueue 仅尝试允许每个 ClusterQueue 的头部。因此,如果 Kueue 未尝试允许工作负载,则工作负载状态可能不包含任何条件。
配置错误的 LocalQueues 或 ClusterQueues
如果你的作业引用了不存在的 LocalQueue,或者它引用的 LocalQueue 或 ClusterQueue 配置错误,则工作负载状态将如下所示
status:
conditions:
- lastTransitionTime: "2024-03-21T13:55:21Z"
message: LocalQueue user-queue doesn't exist
reason: Inadmissible
status: "False"
type: QuotaReserved
请参阅 排查队列问题 以了解 ClusterQueue 或 LocalQueue 为何处于非活动状态。
我的作业是否被抢占?
如果你的作业未运行,并且你的 ClusterQueues 已启用 抢占,则你应检查 Kueue 是否抢占了工作负载。
status:
conditions:
- lastTransitionTime: "2024-03-21T15:49:56Z"
message: 'couldn''t assign flavors to pod set main: insufficient unused quota
for cpu in flavor default-flavor, 9 more needed'
reason: Pending
status: "False"
type: QuotaReserved
- lastTransitionTime: "2024-03-21T15:49:55Z"
message: Preempted to accommodate a higher priority Workload
reason: Preempted
status: "True"
type: Evicted
- lastTransitionTime: "2024-03-21T15:49:56Z"
message: The workload has no reservation
reason: NoReservation
status: "False"
type: Admitted
Evicted
条件表明工作负载已被抢占,而 QuotaReserved
条件(status: "True"
)表明 Kueue 已尝试再次允许它,但在此情况下未成功。
我的作业的 Pod 是否正在运行?
当作业未暂停时,Kubernetes 会为该作业创建 Pod。要检查其中有多少 Pod 已调度并正在运行,请检查作业状态。
运行以下命令以获取作业的完整状态
kubectl get job -n my-namespace my-job -o yaml
输出将类似于以下内容
...
status:
active: 5
ready: 4
succeeded: 1
...
active
字段显示作业中有多少 Pod,而 ready
字段显示其中有多少正在运行。
要列出作业的所有 Pod,请运行以下命令
kubectl get pods -n my-namespace -l batch.kubernetes.io/job-name=my-job
输出将类似于以下内容
NAME READY STATUS RESTARTS AGE
my-job-0-nxmpx 1/1 Running 0 3m20s
my-job-1-vgms2 1/1 Running 0 3m20s
my-job-2-74gw7 1/1 Running 0 3m20s
my-job-3-d4559 1/1 Running 0 3m20s
my-job-4-pg75n 0/1 Pending 0 3m20s
如果 Pod 或 Pod 卡在 Pending
状态,请通过运行以下命令检查为 Pod 发出的最新事件
kubectl describe pod -n my-namespace my-job-0-pg75n
如果 Pod 无法调度,输出将类似于以下内容
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Warning FailedScheduling 13s (x2 over 15s) default-scheduler 0/9 nodes are available: 9 node(s) didn't match Pod's node affinity/selector. preemption: 0/9 nodes are available: 9 Preemption is not helpful for scheduling.
Normal NotTriggerScaleUp 13s cluster-autoscaler pod didn't trigger scale-up: