From 7a563e6c6bb704e64a78324319a706e90c34ddbb Mon Sep 17 00:00:00 2001 From: Abhradeep Chakraborty Date: Wed, 3 Apr 2024 14:09:52 +0530 Subject: [PATCH] feat(crd): add memcached port support (#169) --- api/v1alpha1/dragonfly_types.go | 5 + .../crd/bases/dragonflydb.io_dragonflies.yaml | 197 +++++++++++------ internal/resources/resources.go | 9 + manifests/crd.yaml | 202 ++++++++++++------ manifests/dragonfly-operator.yaml | 202 ++++++++++++------ 5 files changed, 432 insertions(+), 183 deletions(-) diff --git a/api/v1alpha1/dragonfly_types.go b/api/v1alpha1/dragonfly_types.go index 2a8b118..ae7bee5 100644 --- a/api/v1alpha1/dragonfly_types.go +++ b/api/v1alpha1/dragonfly_types.go @@ -77,6 +77,11 @@ type DragonflySpec struct { // +kubebuilder:validation:Optional NodeSelector map[string]string `json:"nodeSelector,omitempty"` + // (Optional) Dragonfly memcached port + // +optional + // +kubebuilder:validation:Optional + MemcachedPort int32 `json:"memcachedPort,omitempty"` + // (Optional) Dragonfly pod tolerations // +optional // +kubebuilder:validation:Optional diff --git a/config/crd/bases/dragonflydb.io_dragonflies.yaml b/config/crd/bases/dragonflydb.io_dragonflies.yaml index b272f58..f898efa 100644 --- a/config/crd/bases/dragonflydb.io_dragonflies.yaml +++ b/config/crd/bases/dragonflydb.io_dragonflies.yaml @@ -1054,6 +1054,10 @@ spec: type: string description: (Optional) Labels to add to the Dragonfly pods. type: object + memcachedPort: + description: (Optional) Dragonfly memcached port + format: int32 + type: integer nodeSelector: additionalProperties: type: string @@ -1413,98 +1417,169 @@ spec: topologySpreadConstraints: description: (Optional) Dragonfly pod topologySpreadConstraints items: - description: The pod this TopologySpreadConstraints is attached + description: TopologySpreadConstraint specifies how to spread matching + pods among the given topology. properties: - maxSkew: - description: the degree to which Pods may be unevenly distributed. - You must specify this field and the number must be greater than zero. - Its semantics differ according to the value of whenUnsatisfiable - format: int32 - type: integer - minDomains: - description: (Optional) indicates a minimum number of eligible domains. - This field is optional. A domain is a particular instance of a topology. - An eligible domain is a domain whose nodes match the node selector - format: int32 - type: integer - topologyKey: - description: the key of node labels. Nodes that have a label with this key and - identical values are considered to be in the same topology. We call each - instance of a topology (in other words, a pair) a domain. - The scheduler will try to put a balanced number of pods into each domain. - Also, we define an eligible domain as a domain whose nodes meet the - requirements of nodeAffinityPolicy and nodeTaintsPolicy. - type: string - whenUnsatisfiable: - description: DoNotSchedule (default) tells the scheduler not to schedule it. - ScheduleAnyway tells the scheduler to still schedule it while prioritizing - nodes that minimize the skew. - type: string labelSelector: - description: A label query over a set of resources, - in this case pods. + description: LabelSelector is used to find matching pods. Pods + that match this label selector are counted to determine the + number of pods in their corresponding topology domain. properties: matchExpressions: - description: matchExpressions is a list of label - selector requirements. The requirements are - ANDed. + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. items: - description: A label selector requirement - is a selector that contains values, a key, - and an operator that relates the key and - values. + description: A label selector requirement is a selector + that contains values, a key, and an operator that relates + the key and values. properties: key: - description: key is the label key that - the selector applies to. + description: key is the label key that the selector + applies to. type: string operator: - description: operator represents a key's - relationship to a set of values. Valid - operators are In, NotIn, Exists and - DoesNotExist. + description: operator represents a key's relationship + to a set of values. Valid operators are In, NotIn, + Exists and DoesNotExist. type: string values: - description: values is an array of string - values. If the operator is In or NotIn, - the values array must be non-empty. - If the operator is Exists or DoesNotExist, - the values array must be empty. This - array is replaced during a strategic - merge patch. + description: values is an array of string values. + If the operator is In or NotIn, the values array + must be non-empty. If the operator is Exists or + DoesNotExist, the values array must be empty. This + array is replaced during a strategic merge patch. items: type: string type: array required: - - key - - operator + - key + - operator type: object type: array matchLabels: additionalProperties: type: string - description: matchLabels is a map of {key,value} - pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, - whose key field is "key", the operator is - "In", and the values array contains only "value". - The requirements are ANDed. + description: matchLabels is a map of {key,value} pairs. + A single {key,value} in the matchLabels map is equivalent + to an element of matchExpressions, whose key field is + "key", the operator is "In", and the values array contains + only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic matchLabelKeys: - description: field is a beta-level field and enabled by default in 1.27. - You can disable it by disabling the MatchLabelKeysInPodTopologySpread + description: MatchLabelKeys is a set of pod label keys to select + the pods over which spreading will be calculated. The keys + are used to lookup values from the incoming pod labels, those + key-value labels are ANDed with labelSelector to select the + group of existing pods over which spreading will be calculated + for the incoming pod. Keys that don't exist in the incoming + pod labels will be ignored. A null or empty list means only + match against labelSelector. items: type: string type: array + x-kubernetes-list-type: atomic + maxSkew: + description: 'MaxSkew describes the degree to which pods may + be unevenly distributed. When `whenUnsatisfiable=DoNotSchedule`, + it is the maximum permitted difference between the number + of matching pods in the target topology and the global minimum. + The global minimum is the minimum number of matching pods + in an eligible domain or zero if the number of eligible domains + is less than MinDomains. For example, in a 3-zone cluster, + MaxSkew is set to 1, and pods with the same labelSelector + spread as 2/2/1: In this case, the global minimum is 1. | + zone1 | zone2 | zone3 | | P P | P P | P | - if MaxSkew + is 1, incoming pod can only be scheduled to zone3 to become + 2/2/2; scheduling it onto zone1(zone2) would make the ActualSkew(3-1) + on zone1(zone2) violate MaxSkew(1). - if MaxSkew is 2, incoming + pod can be scheduled onto any zone. When `whenUnsatisfiable=ScheduleAnyway`, + it is used to give higher precedence to topologies that satisfy + it. It''s a required field. Default value is 1 and 0 is not + allowed.' + format: int32 + type: integer + minDomains: + description: "MinDomains indicates a minimum number of eligible + domains. When the number of eligible domains with matching + topology keys is less than minDomains, Pod Topology Spread + treats \"global minimum\" as 0, and then the calculation of + Skew is performed. And when the number of eligible domains + with matching topology keys equals or greater than minDomains, + this value has no effect on scheduling. As a result, when + the number of eligible domains is less than minDomains, scheduler + won't schedule more than maxSkew Pods to those domains. If + value is nil, the constraint behaves as if MinDomains is equal + to 1. Valid values are integers greater than 0. When value + is not nil, WhenUnsatisfiable must be DoNotSchedule. \n For + example, in a 3-zone cluster, MaxSkew is set to 2, MinDomains + is set to 5 and pods with the same labelSelector spread as + 2/2/2: | zone1 | zone2 | zone3 | | P P | P P | P P | + The number of domains is less than 5(MinDomains), so \"global + minimum\" is treated as 0. In this situation, new pod with + the same labelSelector cannot be scheduled, because computed + skew will be 3(3 - 0) if new Pod is scheduled to any of the + three zones, it will violate MaxSkew. \n This is a beta field + and requires the MinDomainsInPodTopologySpread feature gate + to be enabled (enabled by default)." + format: int32 + type: integer nodeAffinityPolicy: - description: indicates how we will treat Pod's nodeAffinity/nodeSelector - when calculating pod topology spread skew. Options are Honor or Ignore + description: "NodeAffinityPolicy indicates how we will treat + Pod's nodeAffinity/nodeSelector when calculating pod topology + spread skew. Options are: - Honor: only nodes matching nodeAffinity/nodeSelector + are included in the calculations. - Ignore: nodeAffinity/nodeSelector + are ignored. All nodes are included in the calculations. \n + If this value is nil, the behavior is equivalent to the Honor + policy. This is a beta-level feature default enabled by the + NodeInclusionPolicyInPodTopologySpread feature flag." type: string nodeTaintsPolicy: - description: indicates how we will treat node taints when calculating pod topology spread skew. Honor or Ignore + description: "NodeTaintsPolicy indicates how we will treat node + taints when calculating pod topology spread skew. Options + are: - Honor: nodes without taints, along with tainted nodes + for which the incoming pod has a toleration, are included. + - Ignore: node taints are ignored. All nodes are included. + \n If this value is nil, the behavior is equivalent to the + Ignore policy. This is a beta-level feature default enabled + by the NodeInclusionPolicyInPodTopologySpread feature flag." + type: string + topologyKey: + description: TopologyKey is the key of node labels. Nodes that + have a label with this key and identical values are considered + to be in the same topology. We consider each + as a "bucket", and try to put balanced number of pods into + each bucket. We define a domain as a particular instance of + a topology. Also, we define an eligible domain as a domain + whose nodes meet the requirements of nodeAffinityPolicy and + nodeTaintsPolicy. e.g. If TopologyKey is "kubernetes.io/hostname", + each Node is a domain of that topology. And, if TopologyKey + is "topology.kubernetes.io/zone", each zone is a domain of + that topology. It's a required field. type: string + whenUnsatisfiable: + description: 'WhenUnsatisfiable indicates how to deal with a + pod if it doesn''t satisfy the spread constraint. - DoNotSchedule + (default) tells the scheduler not to schedule it. - ScheduleAnyway + tells the scheduler to schedule the pod in any location, but + giving higher precedence to topologies that would help reduce + the skew. A constraint is considered "Unsatisfiable" for an + incoming pod if and only if every possible node assignment + for that pod would violate "MaxSkew" on some topology. For + example, in a 3-zone cluster, MaxSkew is set to 1, and pods + with the same labelSelector spread as 3/1/1: | zone1 | zone2 + | zone3 | | P P P | P | P | If WhenUnsatisfiable is + set to DoNotSchedule, incoming pod can only be scheduled to + zone2(zone3) to become 3/2/1(3/1/2) as ActualSkew(2-1) on + zone2(zone3) satisfies MaxSkew(1). In other words, the cluster + can still be imbalanced, but scheduler won''t make it *more* + imbalanced. It''s a required field.' + type: string + required: + - maxSkew + - topologyKey + - whenUnsatisfiable type: object type: array type: object diff --git a/internal/resources/resources.go b/internal/resources/resources.go index 9c1cc32..758a622 100644 --- a/internal/resources/resources.go +++ b/internal/resources/resources.go @@ -168,6 +168,9 @@ func GetDragonflyResources(ctx context.Context, df *resourcesv1.Dragonfly) ([]cl if df.Spec.Args != nil { statefulset.Spec.Template.Spec.Containers[0].Args = append(statefulset.Spec.Template.Spec.Containers[0].Args, df.Spec.Args...) } + if df.Spec.MemcachedPort != 0 { + statefulset.Spec.Template.Spec.Containers[0].Args = append(statefulset.Spec.Template.Spec.Containers[0].Args, fmt.Sprintf("--memcached_port=%d", df.Spec.MemcachedPort)) + } if df.Spec.AclFromSecret != nil { statefulset.Spec.Template.Spec.Volumes = append(statefulset.Spec.Template.Spec.Volumes, corev1.Volume{ @@ -374,6 +377,12 @@ func GetDragonflyResources(ctx context.Context, df *resourcesv1.Dragonfly) ([]cl service.Spec.Type = df.Spec.ServiceSpec.Type service.Annotations = df.Spec.ServiceSpec.Annotations } + if df.Spec.MemcachedPort != 0 { + service.Spec.Ports = append(service.Spec.Ports, corev1.ServicePort{ + Name: "memcached", + Port: df.Spec.MemcachedPort, + }) + } resources = append(resources, &service) diff --git a/manifests/crd.yaml b/manifests/crd.yaml index a3aff0d..5cd05f4 100644 --- a/manifests/crd.yaml +++ b/manifests/crd.yaml @@ -1053,6 +1053,10 @@ spec: type: string description: (Optional) Labels to add to the Dragonfly pods. type: object + memcachedPort: + description: (Optional) Dragonfly memcached port + format: int32 + type: integer nodeSelector: additionalProperties: type: string @@ -1129,6 +1133,11 @@ spec: description: (Optional) Dragonfly Service type type: string type: object + skipFSGroup: + description: (Optional) Skip Assigning FileSystem Group. Required + for platforms such as Openshift that require IDs to not be set, + as it injects a fixed randomized ID per namespace into all pods. + type: boolean snapshot: description: (Optional) Dragonfly Snapshot configuration properties: @@ -1407,98 +1416,169 @@ spec: topologySpreadConstraints: description: (Optional) Dragonfly pod topologySpreadConstraints items: - description: The pod this TopologySpreadConstraints is attached + description: TopologySpreadConstraint specifies how to spread matching + pods among the given topology. properties: - maxSkew: - description: the degree to which Pods may be unevenly distributed. - You must specify this field and the number must be greater than zero. - Its semantics differ according to the value of whenUnsatisfiable - format: int32 - type: integer - minDomains: - description: (Optional) indicates a minimum number of eligible domains. - This field is optional. A domain is a particular instance of a topology. - An eligible domain is a domain whose nodes match the node selector - format: int32 - type: integer - topologyKey: - description: the key of node labels. Nodes that have a label with this key and - identical values are considered to be in the same topology. We call each - instance of a topology (in other words, a pair) a domain. - The scheduler will try to put a balanced number of pods into each domain. - Also, we define an eligible domain as a domain whose nodes meet the - requirements of nodeAffinityPolicy and nodeTaintsPolicy. - type: string - whenUnsatisfiable: - description: DoNotSchedule (default) tells the scheduler not to schedule it. - ScheduleAnyway tells the scheduler to still schedule it while prioritizing - nodes that minimize the skew. - type: string labelSelector: - description: A label query over a set of resources, - in this case pods. + description: LabelSelector is used to find matching pods. Pods + that match this label selector are counted to determine the + number of pods in their corresponding topology domain. properties: matchExpressions: - description: matchExpressions is a list of label - selector requirements. The requirements are - ANDed. + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. items: - description: A label selector requirement - is a selector that contains values, a key, - and an operator that relates the key and - values. + description: A label selector requirement is a selector + that contains values, a key, and an operator that relates + the key and values. properties: key: - description: key is the label key that - the selector applies to. + description: key is the label key that the selector + applies to. type: string operator: - description: operator represents a key's - relationship to a set of values. Valid - operators are In, NotIn, Exists and - DoesNotExist. + description: operator represents a key's relationship + to a set of values. Valid operators are In, NotIn, + Exists and DoesNotExist. type: string values: - description: values is an array of string - values. If the operator is In or NotIn, - the values array must be non-empty. - If the operator is Exists or DoesNotExist, - the values array must be empty. This - array is replaced during a strategic - merge patch. + description: values is an array of string values. + If the operator is In or NotIn, the values array + must be non-empty. If the operator is Exists or + DoesNotExist, the values array must be empty. This + array is replaced during a strategic merge patch. items: type: string type: array required: - - key - - operator + - key + - operator type: object type: array matchLabels: additionalProperties: type: string - description: matchLabels is a map of {key,value} - pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, - whose key field is "key", the operator is - "In", and the values array contains only "value". - The requirements are ANDed. + description: matchLabels is a map of {key,value} pairs. + A single {key,value} in the matchLabels map is equivalent + to an element of matchExpressions, whose key field is + "key", the operator is "In", and the values array contains + only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic matchLabelKeys: - description: field is a beta-level field and enabled by default in 1.27. - You can disable it by disabling the MatchLabelKeysInPodTopologySpread + description: MatchLabelKeys is a set of pod label keys to select + the pods over which spreading will be calculated. The keys + are used to lookup values from the incoming pod labels, those + key-value labels are ANDed with labelSelector to select the + group of existing pods over which spreading will be calculated + for the incoming pod. Keys that don't exist in the incoming + pod labels will be ignored. A null or empty list means only + match against labelSelector. items: type: string type: array + x-kubernetes-list-type: atomic + maxSkew: + description: 'MaxSkew describes the degree to which pods may + be unevenly distributed. When `whenUnsatisfiable=DoNotSchedule`, + it is the maximum permitted difference between the number + of matching pods in the target topology and the global minimum. + The global minimum is the minimum number of matching pods + in an eligible domain or zero if the number of eligible domains + is less than MinDomains. For example, in a 3-zone cluster, + MaxSkew is set to 1, and pods with the same labelSelector + spread as 2/2/1: In this case, the global minimum is 1. | + zone1 | zone2 | zone3 | | P P | P P | P | - if MaxSkew + is 1, incoming pod can only be scheduled to zone3 to become + 2/2/2; scheduling it onto zone1(zone2) would make the ActualSkew(3-1) + on zone1(zone2) violate MaxSkew(1). - if MaxSkew is 2, incoming + pod can be scheduled onto any zone. When `whenUnsatisfiable=ScheduleAnyway`, + it is used to give higher precedence to topologies that satisfy + it. It''s a required field. Default value is 1 and 0 is not + allowed.' + format: int32 + type: integer + minDomains: + description: "MinDomains indicates a minimum number of eligible + domains. When the number of eligible domains with matching + topology keys is less than minDomains, Pod Topology Spread + treats \"global minimum\" as 0, and then the calculation of + Skew is performed. And when the number of eligible domains + with matching topology keys equals or greater than minDomains, + this value has no effect on scheduling. As a result, when + the number of eligible domains is less than minDomains, scheduler + won't schedule more than maxSkew Pods to those domains. If + value is nil, the constraint behaves as if MinDomains is equal + to 1. Valid values are integers greater than 0. When value + is not nil, WhenUnsatisfiable must be DoNotSchedule. \n For + example, in a 3-zone cluster, MaxSkew is set to 2, MinDomains + is set to 5 and pods with the same labelSelector spread as + 2/2/2: | zone1 | zone2 | zone3 | | P P | P P | P P | + The number of domains is less than 5(MinDomains), so \"global + minimum\" is treated as 0. In this situation, new pod with + the same labelSelector cannot be scheduled, because computed + skew will be 3(3 - 0) if new Pod is scheduled to any of the + three zones, it will violate MaxSkew. \n This is a beta field + and requires the MinDomainsInPodTopologySpread feature gate + to be enabled (enabled by default)." + format: int32 + type: integer nodeAffinityPolicy: - description: indicates how we will treat Pod's nodeAffinity/nodeSelector - when calculating pod topology spread skew. Options are Honor or Ignore + description: "NodeAffinityPolicy indicates how we will treat + Pod's nodeAffinity/nodeSelector when calculating pod topology + spread skew. Options are: - Honor: only nodes matching nodeAffinity/nodeSelector + are included in the calculations. - Ignore: nodeAffinity/nodeSelector + are ignored. All nodes are included in the calculations. \n + If this value is nil, the behavior is equivalent to the Honor + policy. This is a beta-level feature default enabled by the + NodeInclusionPolicyInPodTopologySpread feature flag." type: string nodeTaintsPolicy: - description: indicates how we will treat node taints when calculating pod topology spread skew. Honor or Ignore + description: "NodeTaintsPolicy indicates how we will treat node + taints when calculating pod topology spread skew. Options + are: - Honor: nodes without taints, along with tainted nodes + for which the incoming pod has a toleration, are included. + - Ignore: node taints are ignored. All nodes are included. + \n If this value is nil, the behavior is equivalent to the + Ignore policy. This is a beta-level feature default enabled + by the NodeInclusionPolicyInPodTopologySpread feature flag." + type: string + topologyKey: + description: TopologyKey is the key of node labels. Nodes that + have a label with this key and identical values are considered + to be in the same topology. We consider each + as a "bucket", and try to put balanced number of pods into + each bucket. We define a domain as a particular instance of + a topology. Also, we define an eligible domain as a domain + whose nodes meet the requirements of nodeAffinityPolicy and + nodeTaintsPolicy. e.g. If TopologyKey is "kubernetes.io/hostname", + each Node is a domain of that topology. And, if TopologyKey + is "topology.kubernetes.io/zone", each zone is a domain of + that topology. It's a required field. type: string + whenUnsatisfiable: + description: 'WhenUnsatisfiable indicates how to deal with a + pod if it doesn''t satisfy the spread constraint. - DoNotSchedule + (default) tells the scheduler not to schedule it. - ScheduleAnyway + tells the scheduler to schedule the pod in any location, but + giving higher precedence to topologies that would help reduce + the skew. A constraint is considered "Unsatisfiable" for an + incoming pod if and only if every possible node assignment + for that pod would violate "MaxSkew" on some topology. For + example, in a 3-zone cluster, MaxSkew is set to 1, and pods + with the same labelSelector spread as 3/1/1: | zone1 | zone2 + | zone3 | | P P P | P | P | If WhenUnsatisfiable is + set to DoNotSchedule, incoming pod can only be scheduled to + zone2(zone3) to become 3/2/1(3/1/2) as ActualSkew(2-1) on + zone2(zone3) satisfies MaxSkew(1). In other words, the cluster + can still be imbalanced, but scheduler won''t make it *more* + imbalanced. It''s a required field.' + type: string + required: + - maxSkew + - topologyKey + - whenUnsatisfiable type: object type: array type: object diff --git a/manifests/dragonfly-operator.yaml b/manifests/dragonfly-operator.yaml index 90ad7cf..53e8bb1 100644 --- a/manifests/dragonfly-operator.yaml +++ b/manifests/dragonfly-operator.yaml @@ -1066,6 +1066,10 @@ spec: type: string description: (Optional) Labels to add to the Dragonfly pods. type: object + memcachedPort: + description: (Optional) Dragonfly memcached port + format: int32 + type: integer nodeSelector: additionalProperties: type: string @@ -1142,6 +1146,11 @@ spec: description: (Optional) Dragonfly Service type type: string type: object + skipFSGroup: + description: (Optional) Skip Assigning FileSystem Group. Required + for platforms such as Openshift that require IDs to not be set, + as it injects a fixed randomized ID per namespace into all pods. + type: boolean snapshot: description: (Optional) Dragonfly Snapshot configuration properties: @@ -1420,98 +1429,169 @@ spec: topologySpreadConstraints: description: (Optional) Dragonfly pod topologySpreadConstraints items: - description: The pod this TopologySpreadConstraints is attached + description: TopologySpreadConstraint specifies how to spread matching + pods among the given topology. properties: - maxSkew: - description: the degree to which Pods may be unevenly distributed. - You must specify this field and the number must be greater than zero. - Its semantics differ according to the value of whenUnsatisfiable - format: int32 - type: integer - minDomains: - description: (Optional) indicates a minimum number of eligible domains. - This field is optional. A domain is a particular instance of a topology. - An eligible domain is a domain whose nodes match the node selector - format: int32 - type: integer - topologyKey: - description: the key of node labels. Nodes that have a label with this key and - identical values are considered to be in the same topology. We call each - instance of a topology (in other words, a pair) a domain. - The scheduler will try to put a balanced number of pods into each domain. - Also, we define an eligible domain as a domain whose nodes meet the - requirements of nodeAffinityPolicy and nodeTaintsPolicy. - type: string - whenUnsatisfiable: - description: DoNotSchedule (default) tells the scheduler not to schedule it. - ScheduleAnyway tells the scheduler to still schedule it while prioritizing - nodes that minimize the skew. - type: string labelSelector: - description: A label query over a set of resources, - in this case pods. + description: LabelSelector is used to find matching pods. Pods + that match this label selector are counted to determine the + number of pods in their corresponding topology domain. properties: matchExpressions: - description: matchExpressions is a list of label - selector requirements. The requirements are - ANDed. + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. items: - description: A label selector requirement - is a selector that contains values, a key, - and an operator that relates the key and - values. + description: A label selector requirement is a selector + that contains values, a key, and an operator that relates + the key and values. properties: key: - description: key is the label key that - the selector applies to. + description: key is the label key that the selector + applies to. type: string operator: - description: operator represents a key's - relationship to a set of values. Valid - operators are In, NotIn, Exists and - DoesNotExist. + description: operator represents a key's relationship + to a set of values. Valid operators are In, NotIn, + Exists and DoesNotExist. type: string values: - description: values is an array of string - values. If the operator is In or NotIn, - the values array must be non-empty. - If the operator is Exists or DoesNotExist, - the values array must be empty. This - array is replaced during a strategic - merge patch. + description: values is an array of string values. + If the operator is In or NotIn, the values array + must be non-empty. If the operator is Exists or + DoesNotExist, the values array must be empty. This + array is replaced during a strategic merge patch. items: type: string type: array required: - - key - - operator + - key + - operator type: object type: array matchLabels: additionalProperties: type: string - description: matchLabels is a map of {key,value} - pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, - whose key field is "key", the operator is - "In", and the values array contains only "value". - The requirements are ANDed. + description: matchLabels is a map of {key,value} pairs. + A single {key,value} in the matchLabels map is equivalent + to an element of matchExpressions, whose key field is + "key", the operator is "In", and the values array contains + only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic matchLabelKeys: - description: field is a beta-level field and enabled by default in 1.27. - You can disable it by disabling the MatchLabelKeysInPodTopologySpread + description: MatchLabelKeys is a set of pod label keys to select + the pods over which spreading will be calculated. The keys + are used to lookup values from the incoming pod labels, those + key-value labels are ANDed with labelSelector to select the + group of existing pods over which spreading will be calculated + for the incoming pod. Keys that don't exist in the incoming + pod labels will be ignored. A null or empty list means only + match against labelSelector. items: type: string type: array + x-kubernetes-list-type: atomic + maxSkew: + description: 'MaxSkew describes the degree to which pods may + be unevenly distributed. When `whenUnsatisfiable=DoNotSchedule`, + it is the maximum permitted difference between the number + of matching pods in the target topology and the global minimum. + The global minimum is the minimum number of matching pods + in an eligible domain or zero if the number of eligible domains + is less than MinDomains. For example, in a 3-zone cluster, + MaxSkew is set to 1, and pods with the same labelSelector + spread as 2/2/1: In this case, the global minimum is 1. | + zone1 | zone2 | zone3 | | P P | P P | P | - if MaxSkew + is 1, incoming pod can only be scheduled to zone3 to become + 2/2/2; scheduling it onto zone1(zone2) would make the ActualSkew(3-1) + on zone1(zone2) violate MaxSkew(1). - if MaxSkew is 2, incoming + pod can be scheduled onto any zone. When `whenUnsatisfiable=ScheduleAnyway`, + it is used to give higher precedence to topologies that satisfy + it. It''s a required field. Default value is 1 and 0 is not + allowed.' + format: int32 + type: integer + minDomains: + description: "MinDomains indicates a minimum number of eligible + domains. When the number of eligible domains with matching + topology keys is less than minDomains, Pod Topology Spread + treats \"global minimum\" as 0, and then the calculation of + Skew is performed. And when the number of eligible domains + with matching topology keys equals or greater than minDomains, + this value has no effect on scheduling. As a result, when + the number of eligible domains is less than minDomains, scheduler + won't schedule more than maxSkew Pods to those domains. If + value is nil, the constraint behaves as if MinDomains is equal + to 1. Valid values are integers greater than 0. When value + is not nil, WhenUnsatisfiable must be DoNotSchedule. \n For + example, in a 3-zone cluster, MaxSkew is set to 2, MinDomains + is set to 5 and pods with the same labelSelector spread as + 2/2/2: | zone1 | zone2 | zone3 | | P P | P P | P P | + The number of domains is less than 5(MinDomains), so \"global + minimum\" is treated as 0. In this situation, new pod with + the same labelSelector cannot be scheduled, because computed + skew will be 3(3 - 0) if new Pod is scheduled to any of the + three zones, it will violate MaxSkew. \n This is a beta field + and requires the MinDomainsInPodTopologySpread feature gate + to be enabled (enabled by default)." + format: int32 + type: integer nodeAffinityPolicy: - description: indicates how we will treat Pod's nodeAffinity/nodeSelector - when calculating pod topology spread skew. Options are Honor or Ignore + description: "NodeAffinityPolicy indicates how we will treat + Pod's nodeAffinity/nodeSelector when calculating pod topology + spread skew. Options are: - Honor: only nodes matching nodeAffinity/nodeSelector + are included in the calculations. - Ignore: nodeAffinity/nodeSelector + are ignored. All nodes are included in the calculations. \n + If this value is nil, the behavior is equivalent to the Honor + policy. This is a beta-level feature default enabled by the + NodeInclusionPolicyInPodTopologySpread feature flag." type: string nodeTaintsPolicy: - description: indicates how we will treat node taints when calculating pod topology spread skew. Honor or Ignore + description: "NodeTaintsPolicy indicates how we will treat node + taints when calculating pod topology spread skew. Options + are: - Honor: nodes without taints, along with tainted nodes + for which the incoming pod has a toleration, are included. + - Ignore: node taints are ignored. All nodes are included. + \n If this value is nil, the behavior is equivalent to the + Ignore policy. This is a beta-level feature default enabled + by the NodeInclusionPolicyInPodTopologySpread feature flag." + type: string + topologyKey: + description: TopologyKey is the key of node labels. Nodes that + have a label with this key and identical values are considered + to be in the same topology. We consider each + as a "bucket", and try to put balanced number of pods into + each bucket. We define a domain as a particular instance of + a topology. Also, we define an eligible domain as a domain + whose nodes meet the requirements of nodeAffinityPolicy and + nodeTaintsPolicy. e.g. If TopologyKey is "kubernetes.io/hostname", + each Node is a domain of that topology. And, if TopologyKey + is "topology.kubernetes.io/zone", each zone is a domain of + that topology. It's a required field. type: string + whenUnsatisfiable: + description: 'WhenUnsatisfiable indicates how to deal with a + pod if it doesn''t satisfy the spread constraint. - DoNotSchedule + (default) tells the scheduler not to schedule it. - ScheduleAnyway + tells the scheduler to schedule the pod in any location, but + giving higher precedence to topologies that would help reduce + the skew. A constraint is considered "Unsatisfiable" for an + incoming pod if and only if every possible node assignment + for that pod would violate "MaxSkew" on some topology. For + example, in a 3-zone cluster, MaxSkew is set to 1, and pods + with the same labelSelector spread as 3/1/1: | zone1 | zone2 + | zone3 | | P P P | P | P | If WhenUnsatisfiable is + set to DoNotSchedule, incoming pod can only be scheduled to + zone2(zone3) to become 3/2/1(3/1/2) as ActualSkew(2-1) on + zone2(zone3) satisfies MaxSkew(1). In other words, the cluster + can still be imbalanced, but scheduler won''t make it *more* + imbalanced. It''s a required field.' + type: string + required: + - maxSkew + - topologyKey + - whenUnsatisfiable type: object type: array type: object