Skip to content

Commit c238a0d

Browse files
authored
Add WebSphereLibertyApplication and Semeru toplogy spread constraints (#576)
* Add wlapp/semeru toplogy spread constraints * Get semeru topologySpreadConstraints from wlapp * Update comment
1 parent f118d31 commit c238a0d

11 files changed

+845
-10
lines changed

api/v1/webspherelibertyapplication_types.go

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,9 @@ type WebSphereLibertyApplicationSpec struct {
163163
// Security context for the application container.
164164
// +operator-sdk:csv:customresourcedefinitions:order=31,type=spec,displayName="Security Context"
165165
SecurityContext *corev1.SecurityContext `json:"securityContext,omitempty"`
166+
167+
// +operator-sdk:csv:customresourcedefinitions:order=26,type=spec,displayName="Topology Spread Constraints"
168+
TopologySpreadConstraints *WebSphereLibertyApplicationTopologySpreadConstraints `json:"topologySpreadConstraints,omitempty"`
166169
}
167170

168171
// License information is required.
@@ -225,6 +228,17 @@ const (
225228
LicenseEntitlementWSHE LicenseEntitlement = "IBM WebSphere Hybrid Edition"
226229
)
227230

231+
// Defines the topology spread constraints
232+
type WebSphereLibertyApplicationTopologySpreadConstraints struct {
233+
// The list of TopologySpreadConstraints for the application instance and if applicable, the Semeru Cloud Compiler instance.
234+
// +operator-sdk:csv:customresourcedefinitions:order=1,type=spec,displayName="Constraints"
235+
Constraints *[]corev1.TopologySpreadConstraint `json:"constraints,omitempty"`
236+
237+
// Whether the operator should disable its default set of TopologySpreadConstraints. Defaults to false.
238+
// +operator-sdk:csv:customresourcedefinitions:order=1,type=spec,displayName="Disable Operator Defaults",xDescriptors="urn:alm:descriptor:com.tectonic.ui:booleanSwitch"
239+
DisableOperatorDefaults *bool `json:"disableOperatorDefaults,omitempty"`
240+
}
241+
228242
// Defines the service account
229243
type WebSphereLibertyApplicationServiceAccount struct {
230244
// Whether the Service Account token should be mounted into the application pods. Defaults to true.
@@ -1213,6 +1227,25 @@ func (scc *WebSphereLibertyApplicationSemeruCloudCompiler) GetReplicas() *int32
12131227
return &one
12141228
}
12151229

1230+
// GetTopologySpreadConstraints returns the pod topology spread constraints configuration
1231+
func (cr *WebSphereLibertyApplication) GetTopologySpreadConstraints() common.BaseComponentTopologySpreadConstraints {
1232+
if cr.Spec.TopologySpreadConstraints == nil {
1233+
return nil
1234+
}
1235+
return cr.Spec.TopologySpreadConstraints
1236+
}
1237+
1238+
func (cr *WebSphereLibertyApplicationTopologySpreadConstraints) GetConstraints() *[]corev1.TopologySpreadConstraint {
1239+
if cr.Constraints == nil {
1240+
return nil
1241+
}
1242+
return cr.Constraints
1243+
}
1244+
1245+
func (cr *WebSphereLibertyApplicationTopologySpreadConstraints) GetDisableOperatorDefaults() *bool {
1246+
return cr.DisableOperatorDefaults
1247+
}
1248+
12161249
// Initialize sets default values
12171250
func (cr *WebSphereLibertyApplication) Initialize() {
12181251
if cr.Spec.PullPolicy == nil {

api/v1/zz_generated.deepcopy.go

Lines changed: 36 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

bundle/manifests/ibm-websphere-liberty.clusterserviceversion.yaml

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ metadata:
6262
capabilities: Auto Pilot
6363
categories: Application Runtime
6464
containerImage: icr.io/cpopen/websphere-liberty-operator:daily
65-
createdAt: "2023-10-30T04:18:07Z"
65+
createdAt: "2023-11-02T15:00:01Z"
6666
description: Deploy and manage containerized Liberty applications
6767
olm.skipRange: '>=1.0.0 <1.3.0'
6868
operators.openshift.io/infrastructure-features: '["disconnected"]'
@@ -140,6 +140,16 @@ spec:
140140
- description: The unique ID for the provider. Default value is oidc.
141141
displayName: ID
142142
path: sso.oidc[0].id
143+
- description: The list of TopologySpreadConstraints for the application instance
144+
and if applicable, the Semeru Cloud Compiler instance.
145+
displayName: Constraints
146+
path: topologySpreadConstraints.constraints
147+
- description: Whether the operator should disable its default set of TopologySpreadConstraints.
148+
Defaults to false.
149+
displayName: Disable Operator Defaults
150+
path: topologySpreadConstraints.disableOperatorDefaults
151+
x-descriptors:
152+
- urn:alm:descriptor:com.tectonic.ui:booleanSwitch
143153
- description: Name of the application. Defaults to the name of this custom
144154
resource.
145155
displayName: Application Name
@@ -379,6 +389,8 @@ spec:
379389
path: statefulSet.storage.className
380390
x-descriptors:
381391
- urn:alm:descriptor:com.tectonic.ui:text
392+
- displayName: Topology Spread Constraints
393+
path: topologySpreadConstraints
382394
- description: Represents a volume with data that is accessible to the application
383395
container.
384396
displayName: Volumes

bundle/manifests/liberty.websphere.ibm.com_webspherelibertyapplications.yaml

Lines changed: 183 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5673,6 +5673,189 @@ spec:
56735673
type: string
56745674
type: object
56755675
type: object
5676+
topologySpreadConstraints:
5677+
description: Defines the topology spread constraints
5678+
properties:
5679+
constraints:
5680+
description: The list of TopologySpreadConstraints for the application
5681+
instance and if applicable, the Semeru Cloud Compiler instance.
5682+
items:
5683+
description: TopologySpreadConstraint specifies how to spread
5684+
matching pods among the given topology.
5685+
properties:
5686+
labelSelector:
5687+
description: LabelSelector is used to find matching pods.
5688+
Pods that match this label selector are counted to determine
5689+
the number of pods in their corresponding topology domain.
5690+
properties:
5691+
matchExpressions:
5692+
description: matchExpressions is a list of label selector
5693+
requirements. The requirements are ANDed.
5694+
items:
5695+
description: A label selector requirement is a selector
5696+
that contains values, a key, and an operator that
5697+
relates the key and values.
5698+
properties:
5699+
key:
5700+
description: key is the label key that the selector
5701+
applies to.
5702+
type: string
5703+
operator:
5704+
description: operator represents a key's relationship
5705+
to a set of values. Valid operators are In,
5706+
NotIn, Exists and DoesNotExist.
5707+
type: string
5708+
values:
5709+
description: values is an array of string values.
5710+
If the operator is In or NotIn, the values array
5711+
must be non-empty. If the operator is Exists
5712+
or DoesNotExist, the values array must be empty.
5713+
This array is replaced during a strategic merge
5714+
patch.
5715+
items:
5716+
type: string
5717+
type: array
5718+
required:
5719+
- key
5720+
- operator
5721+
type: object
5722+
type: array
5723+
matchLabels:
5724+
additionalProperties:
5725+
type: string
5726+
description: matchLabels is a map of {key,value} pairs.
5727+
A single {key,value} in the matchLabels map is equivalent
5728+
to an element of matchExpressions, whose key field
5729+
is "key", the operator is "In", and the values array
5730+
contains only "value". The requirements are ANDed.
5731+
type: object
5732+
type: object
5733+
x-kubernetes-map-type: atomic
5734+
matchLabelKeys:
5735+
description: MatchLabelKeys is a set of pod label keys to
5736+
select the pods over which spreading will be calculated.
5737+
The keys are used to lookup values from the incoming pod
5738+
labels, those key-value labels are ANDed with labelSelector
5739+
to select the group of existing pods over which spreading
5740+
will be calculated for the incoming pod. Keys that don't
5741+
exist in the incoming pod labels will be ignored. A null
5742+
or empty list means only match against labelSelector.
5743+
items:
5744+
type: string
5745+
type: array
5746+
x-kubernetes-list-type: atomic
5747+
maxSkew:
5748+
description: 'MaxSkew describes the degree to which pods
5749+
may be unevenly distributed. When `whenUnsatisfiable=DoNotSchedule`,
5750+
it is the maximum permitted difference between the number
5751+
of matching pods in the target topology and the global
5752+
minimum. The global minimum is the minimum number of matching
5753+
pods in an eligible domain or zero if the number of eligible
5754+
domains is less than MinDomains. For example, in a 3-zone
5755+
cluster, MaxSkew is set to 1, and pods with the same labelSelector
5756+
spread as 2/2/1: In this case, the global minimum is 1.
5757+
| zone1 | zone2 | zone3 | | P P | P P | P | -
5758+
if MaxSkew is 1, incoming pod can only be scheduled to
5759+
zone3 to become 2/2/2; scheduling it onto zone1(zone2)
5760+
would make the ActualSkew(3-1) on zone1(zone2) violate
5761+
MaxSkew(1). - if MaxSkew is 2, incoming pod can be scheduled
5762+
onto any zone. When `whenUnsatisfiable=ScheduleAnyway`,
5763+
it is used to give higher precedence to topologies that
5764+
satisfy it. It''s a required field. Default value is 1
5765+
and 0 is not allowed.'
5766+
format: int32
5767+
type: integer
5768+
minDomains:
5769+
description: "MinDomains indicates a minimum number of eligible
5770+
domains. When the number of eligible domains with matching
5771+
topology keys is less than minDomains, Pod Topology Spread
5772+
treats \"global minimum\" as 0, and then the calculation
5773+
of Skew is performed. And when the number of eligible
5774+
domains with matching topology keys equals or greater
5775+
than minDomains, this value has no effect on scheduling.
5776+
As a result, when the number of eligible domains is less
5777+
than minDomains, scheduler won't schedule more than maxSkew
5778+
Pods to those domains. If value is nil, the constraint
5779+
behaves as if MinDomains is equal to 1. Valid values are
5780+
integers greater than 0. When value is not nil, WhenUnsatisfiable
5781+
must be DoNotSchedule. \n For example, in a 3-zone cluster,
5782+
MaxSkew is set to 2, MinDomains is set to 5 and pods with
5783+
the same labelSelector spread as 2/2/2: | zone1 | zone2
5784+
| zone3 | | P P | P P | P P | The number of domains
5785+
is less than 5(MinDomains), so \"global minimum\" is treated
5786+
as 0. In this situation, new pod with the same labelSelector
5787+
cannot be scheduled, because computed skew will be 3(3
5788+
- 0) if new Pod is scheduled to any of the three zones,
5789+
it will violate MaxSkew. \n This is a beta field and requires
5790+
the MinDomainsInPodTopologySpread feature gate to be enabled
5791+
(enabled by default)."
5792+
format: int32
5793+
type: integer
5794+
nodeAffinityPolicy:
5795+
description: "NodeAffinityPolicy indicates how we will treat
5796+
Pod's nodeAffinity/nodeSelector when calculating pod topology
5797+
spread skew. Options are: - Honor: only nodes matching
5798+
nodeAffinity/nodeSelector are included in the calculations.
5799+
- Ignore: nodeAffinity/nodeSelector are ignored. All nodes
5800+
are included in the calculations. \n If this value is
5801+
nil, the behavior is equivalent to the Honor policy. This
5802+
is a alpha-level feature enabled by the NodeInclusionPolicyInPodTopologySpread
5803+
feature flag."
5804+
type: string
5805+
nodeTaintsPolicy:
5806+
description: "NodeTaintsPolicy indicates how we will treat
5807+
node taints when calculating pod topology spread skew.
5808+
Options are: - Honor: nodes without taints, along with
5809+
tainted nodes for which the incoming pod has a toleration,
5810+
are included. - Ignore: node taints are ignored. All nodes
5811+
are included. \n If this value is nil, the behavior is
5812+
equivalent to the Ignore policy. This is a alpha-level
5813+
feature enabled by the NodeInclusionPolicyInPodTopologySpread
5814+
feature flag."
5815+
type: string
5816+
topologyKey:
5817+
description: TopologyKey is the key of node labels. Nodes
5818+
that have a label with this key and identical values are
5819+
considered to be in the same topology. We consider each
5820+
<key, value> as a "bucket", and try to put balanced number
5821+
of pods into each bucket. We define a domain as a particular
5822+
instance of a topology. Also, we define an eligible domain
5823+
as a domain whose nodes meet the requirements of nodeAffinityPolicy
5824+
and nodeTaintsPolicy. e.g. If TopologyKey is "kubernetes.io/hostname",
5825+
each Node is a domain of that topology. And, if TopologyKey
5826+
is "topology.kubernetes.io/zone", each zone is a domain
5827+
of that topology. It's a required field.
5828+
type: string
5829+
whenUnsatisfiable:
5830+
description: 'WhenUnsatisfiable indicates how to deal with
5831+
a pod if it doesn''t satisfy the spread constraint. -
5832+
DoNotSchedule (default) tells the scheduler not to schedule
5833+
it. - ScheduleAnyway tells the scheduler to schedule the
5834+
pod in any location, but giving higher precedence to topologies
5835+
that would help reduce the skew. A constraint is considered
5836+
"Unsatisfiable" for an incoming pod if and only if every
5837+
possible node assignment for that pod would violate "MaxSkew"
5838+
on some topology. For example, in a 3-zone cluster, MaxSkew
5839+
is set to 1, and pods with the same labelSelector spread
5840+
as 3/1/1: | zone1 | zone2 | zone3 | | P P P | P | P |
5841+
If WhenUnsatisfiable is set to DoNotSchedule, incoming
5842+
pod can only be scheduled to zone2(zone3) to become 3/2/1(3/1/2)
5843+
as ActualSkew(2-1) on zone2(zone3) satisfies MaxSkew(1).
5844+
In other words, the cluster can still be imbalanced, but
5845+
scheduler won''t make it *more* imbalanced. It''s a required
5846+
field.'
5847+
type: string
5848+
required:
5849+
- maxSkew
5850+
- topologyKey
5851+
- whenUnsatisfiable
5852+
type: object
5853+
type: array
5854+
disableOperatorDefaults:
5855+
description: Whether the operator should disable its default set
5856+
of TopologySpreadConstraints. Defaults to false.
5857+
type: boolean
5858+
type: object
56765859
volumeMounts:
56775860
description: Represents where to mount the volumes into the application
56785861
container.

0 commit comments

Comments
 (0)