PodMigrationJob

Koordinator定义了一个基于 CRD 的 Pod 迁移 API,称为 PodMigrationJob,通过此 API,重调度器(descheduler)或其他自动故障恢复组件可以更安全地将 Pod 驱逐或删除。

介绍

迁移 Pods 是许多组件(如descheduler)依赖的重要能力,可用于优化调度或帮助解决工作负载运行时质量问题。我们认为,Pod 迁移是一个复杂的过程,涉及诸如审计(auditing)、资源分配和应用程序启动等步骤,并与应用程序升级、伸缩等场景以及集群管理员的资源操作和维护操作混合在一起。因此,如何管理此过程的稳定性风险,以确保应用程序不会因为 Pod 迁移而失败,是必须解决的关键的问题。

基于 PodMigrationJob CRD 的最终状态导向迁移能力,我们可以跟踪迁移过程中每个过程的状态,感知应用程序升级和扩展等场景,以确保工作负载的稳定性。

设置

前置条件

  • Kubernetes >= 1.18
  • Koordinator >= 0.6

Installation

请确保Koordinator组件已正确安装在您的集群中。如果未安装,请参考安装.

Configurations

PodMigrationJob 已默认启用。您可以在koord-descheduler配置中无需任何修改即可使用它。

使用 PodMigrationJob

快速开始

  1. 使用下面的YAML文件创建一个名为pod-demo的Deployment
  1. apiVersion: apps/v1
  2. kind: Deployment
  3. metadata:
  4. name: pod-demo
  5. namespace: default
  6. spec:
  7. progressDeadlineSeconds: 600
  8. replicas: 1
  9. revisionHistoryLimit: 10
  10. selector:
  11. matchLabels:
  12. app: pod-demo
  13. strategy:
  14. rollingUpdate:
  15. maxSurge: 25%
  16. maxUnavailable: 25%
  17. type: RollingUpdate
  18. template:
  19. metadata:
  20. creationTimestamp: null
  21. labels:
  22. app: pod-demo
  23. name: stress
  24. spec:
  25. containers:
  26. - args:
  27. - -c
  28. - "1"
  29. command:
  30. - stress
  31. image: polinux/stress
  32. imagePullPolicy: Always
  33. name: stress
  34. resources:
  35. limits:
  36. cpu: "2"
  37. memory: 4Gi
  38. requests:
  39. cpu: 200m
  40. memory: 400Mi
  41. restartPolicy: Always
  42. schedulerName: koord-scheduler
  1. $ kubectl create -f pod-demo.yaml
  2. deployment.apps/pod-demo created
  1. 检查Pod pod-demo-0 的调度结果
  1. $ kubectl get pod -o wide
  2. NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
  3. pod-demo-5f9b977566-c7lvk 1/1 Running 0 41s 10.17.0.9 node-0 <none> <none>

pod-demo-5f9b977566-c7lvk 被调度在节点 node-0

  1. 使用下面的YAML文件创建一个 PodMigrationJob 来迁移 pod-demo-0
  1. apiVersion: scheduling.koordinator.sh/v1alpha1
  2. kind: PodMigrationJob
  3. metadata:
  4. name: migrationjob-demo
  5. spec:
  6. paused: false
  7. ttl: 5m
  8. mode: ReservationFirst
  9. podRef:
  10. namespace: default
  11. name: pod-demo-5f9b977566-c7lvk
  12. status:
  13. phase: Pending
  1. $ kubectl create -f migrationjob-demo.yaml
  2. podmigrationjob.scheduling.koordinator.sh/migrationjob-demo created
  1. 查看迁移状态
  1. $ kubectl get podmigrationjob migrationjob-demo
  2. NAME PHASE STATUS AGE NODE RESERVATION PODNAMESPACE POD NEWPOD TTL
  3. migrationjob-demo Succeed Complete 37s node-1 d56659ab-ba16-47a2-821d-22d6ba49258e default pod-demo-5f9b977566-c7lvk pod-demo-5f9b977566-nxjdf 5m0s

从上述结果可以观察到:

  • PHASESucceed, STATUSComplete, 表明迁移成功;
  • NODE node-1 表示迁移后新Pod所调度的节点;
  • RESERVATION d56659ab-ba16-47a2-821d-22d6ba49258e 是在迁移期间创建的 Reservation。PodMigrationJob Controller 将在开始驱逐 Pod 之前尝试为 Reservation 创建预留资源。在成功预留资源后,将启动驱逐操作,这可以确保新 Pod 必须被驱逐,因为已有资源可用;
  • PODNAMESPACE default 表示待迁移 Pod 所在的命名空间;
  • POD pod-demo-5f9b977566-c7lvk 表示待迁移的 Pod;
  • NEWPOD pod-demo-5f9b977566-nxjdf 表示迁移后新创建的 Pod;
  • TTL 表示当前作业的 TTL 周期。
  1. 查看迁移事件

PodMigrationJob Controller 将在迁移过程的重要步骤中创建事件,以帮助用户诊断迁移问题

  1. $ kubectl describe podmigrationjob migrationjob-demo
  2. ...
  3. Events:
  4. Type Reason Age From Message
  5. ---- ------ ---- ---- -------
  6. Normal ReservationCreated 8m33s koord-descheduler Successfully create Reservation "d56659ab-ba16-47a2-821d-22d6ba49258e"
  7. Normal ReservationScheduled 8m33s koord-descheduler Assigned Reservation "d56659ab-ba16-47a2-821d-22d6ba49258e" to node "node-1"
  8. Normal Evicting 8m33s koord-descheduler Try to evict Pod "default/pod-demo-5f9b977566-c7lvk"
  9. Normal EvictComplete 8m koord-descheduler Pod "default/pod-demo-5f9b977566-c7lvk" has been evicted
  10. Normal Complete 8m koord-descheduler Bind Pod "default/pod-demo-5f9b977566-nxjdf" in Reservation "d56659ab-ba16-47a2-821d-22d6ba49258e"

高级配置

最新的API可以查看pod_migration_job_types.go.

示例: 手动确认是否允许迁移

驱逐或迁移操作会带来稳定性风险,因此希望在启动迁移操作之前手动检查和确认没有错误,然后再启动迁移。

因此,在创建 PodMigrationJob 时,将 spec.paused 设置为 true,手动确认允许执行后再将 spec.paused 设置为 false。如果拒绝执行,则可以更新 status.phase=Failed 立即终止PodMigrationJob 的执行,或者等待 PodMigrationJob 自动过期。

  1. apiVersion: scheduling.koordinator.sh/v1alpha1
  2. kind: PodMigrationJob
  3. metadata:
  4. name: migrationjob-demo
  5. spec:
  6. # paused indicates whether the PodMigrationJob should to work or not.
  7. paused: true
  8. # ttl controls the PodMigrationJob timeout duration.
  9. ttl: 5m
  10. mode: ReservationFirst
  11. podRef:
  12. namespace: default
  13. name: pod-demo-5f9b977566-c7lvk
  14. status:
  15. phase: Pending

示例: 只想驱逐 Pods, 无需预留资源

PodMigrationJob 提供两种迁移模式:

  • EvictDirectly 直接驱逐 Pod,无需预留资源,
  • ReservationFirst 先预留资源,以确保在开始驱逐之前可以分配资源。

如果你只想驱逐 Pod,只需将 spec.mode 设置为 EvictDirectly

  1. apiVersion: scheduling.koordinator.sh/v1alpha1
  2. kind: PodMigrationJob
  3. metadata:
  4. name: migrationjob-demo
  5. spec:
  6. paused: false
  7. ttl: 5m
  8. mode: EvictDirectly
  9. podRef:
  10. namespace: default
  11. name: pod-demo-5f9b977566-c7lvk
  12. status:
  13. phase: Pending

示例: 在迁移中使用预留资源

在某些情况下,首先预留资源,然后在成功后创建一个 PodMigrationJob,以重复使用 PodMigrationJob Controller 提供的仲裁机制(在v0.7中实现)以确保工作负载的稳定性。

  1. apiVersion: scheduling.koordinator.sh/v1alpha1
  2. kind: PodMigrationJob
  3. metadata:
  4. name: migrationjob-demo
  5. spec:
  6. paused: false
  7. ttl: 5m
  8. mode: ReservationFirst
  9. podRef:
  10. namespace: default
  11. name: pod-demo-5f9b977566-c7lvk
  12. reservationOptions:
  13. # the reservation-0 created before creating PodMigrationJob
  14. reservationRef:
  15. name: reservation-0
  16. status:
  17. phase: Pending

示例: 优雅驱逐 Pods

PodMigrationJob 支持 Pod 的优雅驱逐。

  1. apiVersion: scheduling.koordinator.sh/v1alpha1
  2. kind: PodMigrationJob
  3. metadata:
  4. name: migrationjob-demo
  5. spec:
  6. paused: true
  7. ttl: 5m
  8. mode: ReservationFirst
  9. podRef:
  10. namespace: default
  11. name: pod-demo-5f9b977566-c7lvk
  12. deleteOptions:
  13. # The duration in seconds before the object should be deleted. Value must be non-negative integer.
  14. # The value zero indicates delete immediately. If this value is nil, the default grace period for the
  15. # specified type will be used.
  16. # Defaults to a per object value if not specified. zero means delete immediately.
  17. gracePeriodSeconds: 60
  18. status:
  19. phase: Pending

已知问题