WorkloadSpread

FEATURE STATE: Kruise v0.10.0

WorkloadSpread能够将workload的Pod按一定规则分布到不同类型的Node节点上,赋予单一workload多区域部署和弹性部署的能力。

常见的一些规则包括:

  • 水平打散(比如按host、az等维度的平均打散)。
  • 按指定比例打散(比如按比例部署Pod到几个指定的 az 中)。
  • 带优先级的分区管理,比如:
    • 优先部署到ecs,资源不足时部署到eci。
    • 优先部署固定数量个pod到ecs,其余到eci。
  • 定制化分区管理,比如:
    • 控制workload部署不同数量的Pod到不同的cpu架构上。
    • 确保不同的cpu架构上的Pod配有不同的资源配额。

WorkloadSpread与OpenKruise社区的UnitedDeployment功能相似,每一个WorkloadSpread定义多个区域(定义为subset), 每个subset对应一个maxReplicas数量。WorkloadSpread利用Webhook注入subset定义的域信息,同时控制Pod的扩缩容顺序。 与UnitedDeployment不同的是,UnitedDeployment是帮助用户创建并管理多个workload,WorkloadSpread仅作用在单个workload之上,用户提供workload即可。

当前支持的workload类型:CloneSetDeploymentReplicaSetStatefulSet

注:StatefulSet 从 Kruise 1.3.0 版本开始支持。

特别地,WorkloadSpread 对 StatefulSet 只支持扩容管理,缩容仍旧保留 StatefulSet 固有的缩容顺序, 且扩容管理时按照Pod序号进行划分 Subset, 详情可以参照注释

Demo

  1. apiVersion: apps.kruise.io/v1alpha1
  2. kind: WorkloadSpread
  3. metadata:
  4. name: workloadspread-demo
  5. spec:
  6. targetRef:
  7. apiVersion: apps/v1 | apps.kruise.io/v1alpha1
  8. kind: Deployment | CloneSet
  9. name: workload-xxx
  10. subsets:
  11. - name: subset-a
  12. requiredNodeSelectorTerm:
  13. matchExpressions:
  14. - key: topology.kubernetes.io/zone
  15. operator: In
  16. values:
  17. - zone-a
  18. preferredNodeSelectorTerms:
  19. - weight: 1
  20. preference:
  21. matchExpressions:
  22. - key: another-node-label-key
  23. operator: In
  24. values:
  25. - another-node-label-value
  26. maxReplicas: 3
  27. tolertions: []
  28. patch:
  29. metadata:
  30. labels:
  31. xxx-specific-label: xxx
  32. - name: subset-b
  33. requiredNodeSelectorTerm:
  34. matchExpressions:
  35. - key: topology.kubernetes.io/zone
  36. operator: In
  37. values:
  38. - zone-b
  39. scheduleStrategy:
  40. type: Adaptive | Fixed
  41. adaptive:
  42. rescheduleCriticalSeconds: 30

targetRef: 指定WorkloadSpread管理的workload。不可以变更,且一个workload只能对应一个WorkloadSpread。

subsets

subsets定义了多个区域(subset),每个区域配置不同的subset信息

sub-fields

  • name: subset的名称,在同一个WorkloadSpread下name唯一,代表一个topology区域。

  • maxReplicas:该subset所期望调度的最大副本数,需为 >= 0的整数。若设置为空,代表不限制subset的副本数。

    当前版本暂不支持百分比类型。

  • requiredNodeSelectorTerm: 强制匹配到某个zone。

  • preferredNodeSelectorTerms: 尽量匹配到某个zone。

注意:requiredNodeSelectorTerm对应k8s nodeAffinity的requiredDuringSchedulingIgnoredDuringExecution。 preferredNodeSelectorTerms对应nodeAffinity preferredDuringSchedulingIgnoredDuringExecution。

  • tolerations: subsetPod的Node容忍度。
  1. tolerations:
  2. - key: "key1"
  3. operator: "Equal"
  4. value: "value1"
  5. effect: "NoSchedule"
  • patch: 定制subset中的Pod配置,可以是Annotations、Labels、Env等。

例子:

  1. # patch pod with a topology label:
  2. patch:
  3. metadata:
  4. labels:
  5. topology.application.deploy/zone: "zone-a"
  1. # patch pod container resources:
  2. patch:
  3. spec:
  4. containers:
  5. - name: main
  6. resources:
  7. limit:
  8. cpu: "2"
  9. memory: 800Mi
  1. # patch pod container env with a zone name:
  2. patch:
  3. spec:
  4. containers:
  5. - name: main
  6. env:
  7. - name: K8S_AZ_NAME
  8. value: zone-a

调度策略

WorkloadSpread提供了两种调度策略,默认为Fixed:

  1. scheduleStrategy:
  2. type: Adaptive | Fixed
  3. adaptive:
  4. rescheduleCriticalSeconds: 30
  • Fixed:

    workload严格按照subsets定义分布。

  • Adaptive:

    Reschedule:Kruise检查subset中调度失败的Pod,若超过用户定义的时间就将其调度到其他有可用的subset上。

配置要求

WorkloadSpread 功能默认是关闭的,你需要在 安装/升级 Kruise 的时候打开 feature-gate:WorkloadSpread

  1. $ helm install kruise https://... --set featureGates="WorkloadSpread=true"

Pod Webhook

WorkloadSpread 利用 webhook 向Pod注入域规则。

如果PodWebhook feature-gate 被设置为 false,WorkloadSpread 也将不可用。

deletion-cost feature

CloneSet 已经支持该特性。

其他 native workload 需 kubernetes version >= 1.21。且 1.21 版本需要显式开启 PodDeletionCost feature-gate,自 1.22 起默认开启。

扩缩容顺序:

WorkloadSpread所管理的workload会按照subsets中定义的顺序扩缩容,subset的顺序允许改变,即通过改变subset的顺序来调整扩缩容的顺序。

规则如下:

扩容

  • 按照spec.subsetssubset定义的顺序调度Pod,当前subset的active Pod数量达到maxReplicas时再调度到下一个subset

缩容

  • subset的副本数(active)大于定义的maxReplicas时,优先缩容多余的Pod。
  • 依据spec.subsetssubset定义的顺序,后面subset的Pod先于前面的被删除。

例如:

  1. # subset-a subset-b subset-c
  2. # maxReplicas 10 10 nil
  3. # pods number 10 10 10
  4. # deletion order: c -> b -> a
  5. # subset-a subset-b subset-c
  6. # maxReplicas 10 10 nil
  7. # pods number 20 20 20
  8. # deletion order: b -> a -> c

feature-gates

WorkloadSpread 默认是关闭的,如果要开启请通过设置 feature-gates WorkloadSpread.

  1. $ helm install kruise https://... --set featureGates="WorkloadSpread=true"

例子

弹性部署

zone-a(ack)固定100个Pod,zone-b(eci)做弹性区域

  1. 创建WorkloadSpread实例
  1. apiVersion: apps.kruise.io/v1alpha1
  2. kind: WorkloadSpread
  3. metadta:
  4. name: ws-demo
  5. namespace: deploy
  6. spec:
  7. targetRef: # 相同namespace下的workload
  8. apiVersion: apps.kruise.io/v1alpha1
  9. kind: CloneSet
  10. name: cs-demo
  11. subsets:
  12. - name: ack # zone ack,最多100个副本。
  13. requiredNodeSelectorTerm:
  14. matchExpressions:
  15. - key: topology.kubernetes.io/zone
  16. operator: In
  17. values:
  18. - ack
  19. maxReplicas: 100
  20. patch: # 注入label
  21. metadata:
  22. labels:
  23. topology.application.deploy/zone: ack
  24. - name: eci # 弹性区域eci,副本数量不限。
  25. requiredNodeSelectorTerm:
  26. matchExpressions:
  27. - key: topology.kubernetes.io/zone
  28. operator: In
  29. values:
  30. - eci
  31. patch:
  32. metadata:
  33. labels:
  34. topology.application.deploy/zone: eci
  1. 创建workload,副本数可以自由调整。

部署效果

  • 当replicas <= 100 时,Pod被调度到ack上。
  • 当replicas > 100 时,100个在ack,多余的Pod在弹性域eci。
  • 缩容时优先从弹性域eci上缩容。

多域部署

分别部署100个副本的Pod到两个机房(zone-a, zone-b)

  1. 创建WorkloadSpread实例
  1. apiVersion: apps.kruise.io/v1alpha1
  2. kind: WorkloadSpread
  3. metadta:
  4. name: ws-demo
  5. namespace: deploy
  6. spec:
  7. targetRef: # 相同namespace下的workload
  8. apiVersion: apps.kruise.io/v1alpha1
  9. kind: CloneSet
  10. name: cs-demo
  11. subsets:
  12. - name: subset-a # 区域A,100个副本。
  13. requiredNodeSelectorTerm:
  14. matchExpressions:
  15. - key: topology.kubernetes.io/zone
  16. operator: In
  17. values:
  18. - zone-a
  19. maxReplicas: 100
  20. patch:
  21. metadata:
  22. labels:
  23. topology.application.deploy/zone: zone-a
  24. - name: subset-b # 区域B,100个副本。
  25. requiredNodeSelectorTerm:
  26. matchExpressions:
  27. - key: topology.kubernetes.io/zone
  28. operator: In
  29. values:
  30. - zone-b
  31. maxReplicas: 100
  32. patch:
  33. metadata:
  34. labels:
  35. topology.application.deploy/zone: zone-b
  1. 创建一个200副本的新CloneSet,或者对现有的CloneSet执行滚动更新。

  2. subset副本分布需要变动,先调整对应subsetmaxReplicas,再调整workload副本数。