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
快速开始
- 使用下面的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
- 检查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上
- 使用下面的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. $ 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
从上述结果可以观察到:
- PHASE 为
Succeed, STATUS 为Complete, 表明迁移成功; - 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 周期。
-
查看迁移事件
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
已知问题
- 当前不支持Arbitration mechanism,v0.6版本仅实现了基于资源预留的迁移能力。
- 目前不支持Basic Migration API 。
