UnitedDeployment

这个控制器提供了一个新模式来通过多个 workload 管理多个区域下的 Pod。 这篇 博客文章 提供了对 UnitedDeployment 一个高层面的描述。

在一个 Kubernetes 集群中可能存在不同的 node 类型,比如多个可用区、或不同的节点技术(比如 Virtual kueblet)等,这些不同类型的 node 上有 label/taint 标识。 UnitedDeployment 控制器可以提供一个模板来定义应用,并通过管理多个 workload 来匹配下面不同的区域。 每个 UnitedDeployment 下每个区域的 workload 被称为 subset,有一个期望的 replicas Pod 数量。 目前 subset 支持使用 StatefulSetAdvanced StatefulSetCloneSetDeployment

API 定义: https://github.com/openkruise/kruise/blob/master/apis/apps/v1alpha1/uniteddeployment_types.go

下面用一个简单例子来演示如何定义一个 UnitedDeployment 来管理下面三个区域的 StatefulSet,所有区域的 Pod 总数为 6。

  1. apiVersion: apps.kruise.io/v1alpha1
  2. kind: UnitedDeployment
  3. metadata:
  4. name: sample-ud
  5. spec:
  6. replicas: 6
  7. revisionHistoryLimit: 10
  8. selector:
  9. matchLabels:
  10. app: sample
  11. template:
  12. # statefulSetTemplate or advancedStatefulSetTemplate or cloneSetTemplate or deploymentTemplate
  13. statefulSetTemplate:
  14. metadata:
  15. labels:
  16. app: sample
  17. spec:
  18. selector:
  19. matchLabels:
  20. app: sample
  21. template:
  22. metadata:
  23. labels:
  24. app: sample
  25. spec:
  26. containers:
  27. - image: nginx:alpine
  28. name: nginx
  29. topology:
  30. subsets:
  31. - name: subset-a
  32. nodeSelectorTerm:
  33. matchExpressions:
  34. - key: node
  35. operator: In
  36. values:
  37. - zone-a
  38. replicas: 1
  39. - name: subset-b
  40. nodeSelectorTerm:
  41. matchExpressions:
  42. - key: node
  43. operator: In
  44. values:
  45. - zone-b
  46. replicas: 50%
  47. - name: subset-c
  48. nodeSelectorTerm:
  49. matchExpressions:
  50. - key: node
  51. operator: In
  52. values:
  53. - zone-c
  54. updateStrategy:
  55. manualUpdate:
  56. partitions:
  57. subset-a: 0
  58. subset-b: 0
  59. subset-c: 0
  60. type: Manual
  61. ...

支持 Customize 不同 subset 的 Pod Template

FEATURE STATE: Kruise v1.5.0

从 kruise v1.5.0版本开始,你可以 customize 任意 pod.spec 字段,比如:env、resources。

Note: 建议不要在 subset 中 customize image 字段,它可能会导致发布的异常。

  1. apiVersion: apps.kruise.io/v1alpha1
  2. kind: UnitedDeployment
  3. metadata:
  4. name: sample-ud
  5. spec:
  6. replicas: 6
  7. revisionHistoryLimit: 10
  8. selector:
  9. matchLabels:
  10. app: sample
  11. template:
  12. # statefulSetTemplate or advancedStatefulSetTemplate or cloneSetTemplate or deploymentTemplate
  13. statefulSetTemplate:
  14. ...
  15. topology:
  16. subsets:
  17. - name: subset-a
  18. ...
  19. # patch container resources, env:
  20. patch:
  21. spec:
  22. containers:
  23. - name: main
  24. resources:
  25. limits:
  26. cpu: "2"
  27. memory: 800Mi
  28. env:
  29. - name: subset
  30. value: subset-a
  31. - name: subset-b
  32. ...
  33. # patch container resources, env:
  34. patch:
  35. spec:
  36. containers:
  37. - name: main
  38. resources:
  39. limits:
  40. cpu: "2"
  41. memory: 800Mi
  42. image: subset-b/nginx:alpine
  43. env:
  44. - name: subset
  45. value: subset-b

HPA UnitedDeployment

FEATURE STATE: Kruise v1.5.0

Horizontal Pod Autoscaler 能够支持包含 scale subresource 的自定义工作负载. 从 kruise v1.5.0版本开始,你可以直接 HPA UnitedDeployment,如下:

  1. apiVersion: autoscaling/v2beta1
  2. kind: HorizontalPodAutoscaler
  3. metadata:
  4. name: example-hpa
  5. namespace: default
  6. spec:
  7. minReplicas: 1
  8. maxReplicas: 3
  9. metrics:
  10. - resource:
  11. name: cpu
  12. targetAverageUtilization: 2
  13. type: Resource
  14. scaleTargetRef:
  15. apiVersion: apps.kruise.io/v1alpha1
  16. kind: UnitedDeployment
  17. name: sample-ud

Pod 分发管理

上述例子中可以看到,spec.topology 中可以定义 Pod 分发的规则:

  1. // Topology defines the spread detail of each subset under UnitedDeployment.
  2. // A UnitedDeployment manages multiple homogeneous workloads which are called subset.
  3. // Each of subsets under the UnitedDeployment is described in Topology.
  4. type Topology struct {
  5. // Contains the details of each subset. Each element in this array represents one subset
  6. // which will be provisioned and managed by UnitedDeployment.
  7. // +optional
  8. Subsets []Subset `json:"subsets,omitempty"`
  9. }
  10. // Subset defines the detail of a subset.
  11. type Subset struct {
  12. // Indicates subset name as a DNS_LABEL, which will be used to generate
  13. // subset workload name prefix in the format '<deployment-name>-<subset-name>-'.
  14. // Name should be unique between all of the subsets under one UnitedDeployment.
  15. Name string `json:"name"`
  16. // Indicates the node selector to form the subset. Depending on the node selector,
  17. // pods provisioned could be distributed across multiple groups of nodes.
  18. // A subset's nodeSelectorTerm is not allowed to be updated.
  19. // +optional
  20. NodeSelectorTerm corev1.NodeSelectorTerm `json:"nodeSelectorTerm,omitempty"`
  21. // Indicates the tolerations the pods under this subset have.
  22. // A subset's tolerations is not allowed to be updated.
  23. // +optional
  24. Tolerations []corev1.Toleration `json:"tolerations,omitempty"`
  25. // Indicates the number of the pod to be created under this subset. Replicas could also be
  26. // percentage like '10%', which means 10% of UnitedDeployment replicas of pods will be distributed
  27. // under this subset. If nil, the number of replicas in this subset is determined by controller.
  28. // Controller will try to keep all the subsets with nil replicas have average pods.
  29. // +optional
  30. Replicas *intstr.IntOrString `json:"replicas,omitempty"`
  31. }

topology.subsets 里面我们指定了多个 subset 组,每个 subset 其实对应了一个下属的 workload。 当一个 subset 从这个列表里增加或去除时,UnitedDeployment 控制器会创建或删除相应的 subset workload。

  • 每个 subset workload 有一个独立的名字,前缀是 <UnitedDeployment-name>-<Subset-name>-

  • subset workload 是根据 UnitedDeployment 的 spec.template 做基础来创建,同时将 subset 中定义的一些特殊配置(如 nodeSelector, replicas)合并进去成为一个完整的 workload。

    • subset.replicas 可以设置绝对值百分比。其中,百分比会根据 UnitedDeployment 的 replicas 总数计算出来 subset 需要的数量;而如果不设置这个 subset.replicas,控制器会根据总数划分给每个 subset 对应的数量。
    • subset.nodeSelector 会合并到 subset workload 的 spec.template 下面,因此这个 workload 创建出来的 Pod 都带有对应的调度规则。

Pod 更新管理

如果用户修改了 spec.template 下面的字段,相当于触发了升级流程。 控制器会把新的 template 更新到各个 subset workload 里面,来触发 subset 控制器升级 Pod。

同时,如果 subset workload 支持 partition 策略(目前可用的 AdvancedStatefulSet, StatefulSet 都是支持的),还可以使用 manual 升级策略。

  1. // UnitedDeploymentUpdateStrategy defines the update performance
  2. // when template of UnitedDeployment is changed.
  3. type UnitedDeploymentUpdateStrategy struct {
  4. // Type of UnitedDeployment update strategy.
  5. // Default is Manual.
  6. // +optional
  7. Type UpdateStrategyType `json:"type,omitempty"`
  8. // Includes all of the parameters a Manual update strategy needs.
  9. // +optional
  10. ManualUpdate *ManualUpdate `json:"manualUpdate,omitempty"`
  11. }
  12. // ManualUpdate is a update strategy which allows users to control the update progress
  13. // by providing the partition of each subset.
  14. type ManualUpdate struct {
  15. // Indicates number of subset partition.
  16. // +optional
  17. Partitions map[string]int32 `json:"partitions,omitempty"`
  18. }

通过 manual 升级策略,用户可以指定 UnitedDeployment 下面每个 subset workload 的灰度升级数量,控制器会把不同的 partition 数值同步给对应的 subset workload 里面。