diff --git a/pubsubplus/templates/solaceStatefulSet.yaml b/pubsubplus/templates/solaceStatefulSet.yaml index 7844729..3976906 100644 --- a/pubsubplus/templates/solaceStatefulSet.yaml +++ b/pubsubplus/templates/solaceStatefulSet.yaml @@ -38,6 +38,10 @@ spec: tolerations: {{ toYaml .Values.solace.tolerations | indent 6 }} {{- end }} +{{- if .Values.solace.topologySpreadConstraints }} + topologySpreadConstraints: +{{ toYaml .Values.solace.topologySpreadConstraints | indent 6 }} +{{- end }} {{- if .Values.image.pullSecretName }} imagePullSecrets: - name: {{ .Values.image.pullSecretName}} diff --git a/pubsubplus/values.schema.json b/pubsubplus/values.schema.json index 417b70d..99c9116 100644 --- a/pubsubplus/values.schema.json +++ b/pubsubplus/values.schema.json @@ -130,6 +130,20 @@ "array", "null" ] + }, + "annotations": { + "type": "object" + }, + "topologySpreadConstraints": { + "description": "If specified, the PubSubPlus+ STS topology spread constraint.", + "items": { + "$ref": "#/definitions/io.k8s.api.core.v1.TopologySpreadConstraint", + "description": "If specified, the PubSubPlus+ STS topology spread." + }, + "type": [ + "array", + "null" + ] } }, "if": { @@ -1262,6 +1276,108 @@ "type": "object", "additionalProperties": false, "$schema": "http://json-schema.org/schema#" + }, + "io.k8s.api.core.v1.TopologySpreadConstraint": { + "description": "TopologySpreadConstraint specifies how to spread matching pods among the given topology.", + "properties": { + "labelSelector": { + "description": "A label selector is a label query over a set of resources. The result of matchLabels and matchExpressions are ANDed. An empty label selector matches all objects. A null label selector matches no objects.", + "properties": { + "matchExpressions": { + "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.", + "properties": { + "key": { + "description": "key is the label key that the selector applies to.", + "type": "string", + "x-kubernetes-patch-merge-key": "key", + "x-kubernetes-patch-strategy": "merge" + }, + "operator": { + "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.", + "items": { + "type": [ + "string", + "null" + ] + }, + "type": [ + "array", + "null" + ] + } + }, + "required": [ + "key", + "operator" + ], + "type": [ + "object", + "null" + ], + "additionalProperties": false + }, + "type": [ + "array", + "null" + ] + }, + "matchLabels": { + "additionalProperties": { + "type": [ + "string", + "null" + ] + }, + "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", + "null" + ] + } + }, + "type": [ + "object", + "null" + ], + "x-kubernetes-map-type": "atomic", + "additionalProperties": false + }, + "maxSkew": { + "description": "MaxSkew describes the degree to which pods may be unevenly distributed. It's the maximum permitted difference between the number of matching pods in any two topology domains of a given topology type. For example, in a 3-zone cluster, MaxSkew is set to 1, and pods with the same labelSelector spread as 1/1/0: | zone1 | zone2 | zone3 | | P | P | | - if MaxSkew is 1, incoming pod can only be scheduled to zone3 to become 1/1/1; scheduling it onto zone1(zone2) would make the ActualSkew(2-0) on zone1(zone2) violate MaxSkew(1). - if MaxSkew is 2, incoming pod can be scheduled onto any zone. It's a required field. Default value is 1 and 0 is not allowed.", + "format": "int32", + "type": [ + "integer", + "null" + ] + }, + "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. It's a required field.", + "type": [ + "string", + "null" + ] + }, + "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 still schedule it It's considered as \"Unsatisfiable\" if and only if placing incoming pod on any topology violates \"MaxSkew\". 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", + "null" + ] + } + }, + "required": [ + "maxSkew", + "topologyKey", + "whenUnsatisfiable" + ], + "type": "object", + "$schema": "http://json-schema.org/schema#" } } } diff --git a/pubsubplus/values.yaml b/pubsubplus/values.yaml index 5c80d9c..f394e3b 100644 --- a/pubsubplus/values.yaml +++ b/pubsubplus/values.yaml @@ -93,6 +93,16 @@ solace: # value: solace tolerations: [] + # topologySpreadConstraints are added to statefulset pods to control how Pods are spread across your + # cluster among failure-domains such as regions, zones, nodes, and other user-defined topology domains. + # see https://kubernetes.io/docs/concepts/scheduling-eviction/topology-spread-constraints/ for more details + # example: + #topologySpreadConstraints: + #- maxSkew: 1 + # topologyKey: topology.kubernetes.io/zone + # whenUnsatisfiable: ScheduleAnyway + topologySpreadConstraints : [] + image: # Default repository repository: solace/solace-pubsub-standard