Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add PodDisruptionBudget for NodePools #547

Merged
merged 80 commits into from
Aug 30, 2023
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
Show all changes
80 commits
Select commit Hold shift + click to select a range
ed4a738
added artifacthub-repo.yml
idanl21 May 31, 2022
233af07
Merge branch 'main' of https://github.com/Opster/opensearch-k8s-operator
idanl21 Jul 24, 2022
cba18fd
Merge branch 'main' of https://github.com/Opster/opensearch-k8s-operator
idanl21 Jun 26, 2023
3753f82
added new PDB resource creatiuon to the Operator
idanl21 Jun 26, 2023
9010511
added new PDB resource creatiuon to the Operator
idanl21 Jun 26, 2023
2977313
fix after sebastian's review
idanl21 Jul 2, 2023
9fdaa45
fix after sebastian's review
idanl21 Jul 2, 2023
dc6c129
fix tests
idanl21 Jul 3, 2023
5a48b8a
Merge branch 'main' into add_pdb
idanl21 Jul 3, 2023
e9cdcd8
Update docs/userguide/main.md
idanl21 Jul 4, 2023
da1d0fa
fix
idanl21 Jul 4, 2023
0f7cea6
fix
idanl21 Jul 4, 2023
b9c6536
fixed
idanl21 Jul 4, 2023
880d744
Merge branch 'main' into add_pdb
idanl21 Jul 5, 2023
dec7dee
Merge branch 'main' into add_pdb
idanl21 Jul 16, 2023
07be50a
fix and add PDB to chart
idanl21 Jul 16, 2023
923dc89
Merge branch 'main' into add_pdb
idanl21 Aug 2, 2023
b0eb3b7
fix last reviews
idanl21 Aug 2, 2023
627f849
check functional tests
idanl21 Aug 2, 2023
5d5dc7d
check functional tests
idanl21 Aug 2, 2023
dce4cf9
check functional tests
idanl21 Aug 2, 2023
9bce071
check functional tests
idanl21 Aug 2, 2023
4663230
check functional tests
idanl21 Aug 2, 2023
68867a1
fix pdb deletion
idanl21 Aug 3, 2023
cafddb4
added artifacthub-repo.yml
idanl21 May 31, 2022
1930f59
fix functional tests
idanl21 Aug 7, 2023
7353284
added new PDB resource creatiuon to the Operator
idanl21 Jun 26, 2023
94a2086
added new PDB resource creatiuon to the Operator
idanl21 Jun 26, 2023
dfb6702
fix after sebastian's review
idanl21 Jul 2, 2023
85d9071
fix after sebastian's review
idanl21 Jul 2, 2023
c71c864
fix tests
idanl21 Jul 3, 2023
f554e36
Update docs/userguide/main.md
idanl21 Jul 4, 2023
c947b2c
fix
idanl21 Jul 4, 2023
5107018
fix
idanl21 Jul 4, 2023
4ec85fb
fix tests
idanl21 Aug 7, 2023
6d4ed49
fix tests
idanl21 Aug 7, 2023
97bcf4b
fix tests
idanl21 Aug 7, 2023
981ceba
Merge remote-tracking branch 'origin/add_pdb' into add_pdb
idanl21 Aug 7, 2023
59958e2
fix func
idanl21 Aug 7, 2023
9634e3e
Add missing rbac rule for PDB
swoehrl-mw Aug 9, 2023
3f3314e
Merge remote-tracking branch 'origin/add_pdb' into add_pdb
idanl21 Aug 9, 2023
a4d2120
fix conflicts
idanl21 Aug 10, 2023
64e7169
delete unrelated to pr changes
idanl21 Aug 28, 2023
090a11f
Merge branch 'main' into add_pdb
idanl21 Aug 28, 2023
500a5de
added artifacthub-repo.yml
idanl21 May 31, 2022
4844217
fix functional tests
idanl21 Aug 7, 2023
1120c45
added new PDB resource creatiuon to the Operator
idanl21 Jun 26, 2023
75082d8
fix after sebastian's review
idanl21 Jul 2, 2023
e4126d5
fix after sebastian's review
idanl21 Jul 2, 2023
4dd25e1
fix tests
idanl21 Jul 3, 2023
ec1ce0c
Update docs/userguide/main.md
idanl21 Jul 4, 2023
5b8fd71
fix
idanl21 Jul 4, 2023
2a9999a
fix
idanl21 Jul 4, 2023
74694a4
fix tests
idanl21 Aug 7, 2023
5bf31d0
fix tests
idanl21 Aug 7, 2023
67a7463
fix tests
idanl21 Aug 7, 2023
7d57ef2
added new PDB resource creatiuon to the Operator
idanl21 Jun 26, 2023
7eda7f7
added new PDB resource creatiuon to the Operator
idanl21 Jun 26, 2023
f4bffae
fix after sebastian's review
idanl21 Jul 2, 2023
283d2be
fix after sebastian's review
idanl21 Jul 2, 2023
d5e6c5d
fix tests
idanl21 Jul 3, 2023
89aa2ba
fix
idanl21 Jul 4, 2023
b8c487b
fixed
idanl21 Jul 4, 2023
9235ac9
fix and add PDB to chart
idanl21 Jul 16, 2023
adcf3e1
fix last reviews
idanl21 Aug 2, 2023
ffc1580
check functional tests
idanl21 Aug 2, 2023
7c760e5
check functional tests
idanl21 Aug 2, 2023
4bc3e37
check functional tests
idanl21 Aug 2, 2023
cb1a571
check functional tests
idanl21 Aug 2, 2023
8afb5a5
check functional tests
idanl21 Aug 2, 2023
5c42fdf
fix pdb deletion
idanl21 Aug 3, 2023
ac4361f
fix func
idanl21 Aug 7, 2023
a10b277
Add missing rbac rule for PDB
swoehrl-mw Aug 9, 2023
70c8e6f
fix conflicts
idanl21 Aug 10, 2023
60a90cc
delete unrelated to pr changes
idanl21 Aug 28, 2023
88eef00
rebase to main
idanl21 Aug 30, 2023
fc3abf8
merge confilicts
idanl21 Aug 30, 2023
c6bfd15
fix conflict, rebase to main
idanl21 Aug 30, 2023
ed9fe07
Cleanup PR
swoehrl-mw Aug 30, 2023
7a5169c
Remove unneeded finalizer for PDB
swoehrl-mw Aug 30, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions artifacthub-repo.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
repositoryID: 4b29d8fe-d914-494f-805e-d5fd0938f9af
owners:
- name: Idan Levi
email: [email protected]
- name: Prudhvi Godithi
email: [email protected]
Original file line number Diff line number Diff line change
Expand Up @@ -295,3 +295,12 @@ rules:
- patch
- update
- watch
- apiGroups:
- policy
resources:
- poddisruptionbudgets
verbs:
- get
- create
- update
- delete
36 changes: 35 additions & 1 deletion docs/userguide/main.md
Original file line number Diff line number Diff line change
Expand Up @@ -1036,6 +1036,40 @@ spec:
description: Sample tenant
```


### PodDisruptionBudget
idanl21 marked this conversation as resolved.
Show resolved Hide resolved


The PDB (Pod Disruption Budget) is a Kubernetes resource that helps ensure the high availability of applications by defining the acceptable disruption level during maintenance or unexpected events.
It specifies the minimum number of pods that must remain available to maintain the desired level of service.
The PDB definition is unique for every nodePool.
Please be aware that you must provide `MinAvailable` and `MaxUnavailable` configurations in order to use PDB feature.
idanl21 marked this conversation as resolved.
Show resolved Hide resolved


```yaml
apiVersion: opensearch.opster.io/v1
kind: OpenSearchCluster
...
spec:
nodePools:
- component: masters
replicas: 3
diskSize: "30Gi"
pdb:
enable: true
MinAvailable: 3
idanl21 marked this conversation as resolved.
Show resolved Hide resolved
MaxUnavailable: 0
idanl21 marked this conversation as resolved.
Show resolved Hide resolved
- component: datas
replicas: 7
diskSize: "100Gi"
pdb:
enable: true
MinAvailable: 5
MaxUnavailable: 2
idanl21 marked this conversation as resolved.
Show resolved Hide resolved
```
```
idanl21 marked this conversation as resolved.
Show resolved Hide resolved


### Custom Admin User

In order to create your cluster with an adminuser different from the default `admin:admin` you will have to walk through the following steps:
Expand Down Expand Up @@ -1101,7 +1135,7 @@ spec:
name: dashboards-credentials # This is the name of your secret that contains the credentials for Dashboards to use
```

## Adding Opensearch Monitoring to your cluster
### Adding Opensearch Monitoring to your cluster

The operator allows you to install and enable the [Aiven monitoring plugin for OpenSearch](https://github.com/aiven/prometheus-exporter-plugin-for-opensearch) on your cluster as a built-in feature. If enabled the operator will install the aiven plugin into the opensearch pods and generate a Prometheus ServiceMonitor object to configure the plugin for scraping.
This feature needs internet connectivity to download the plugin. if you are working in a restricted environment, please download the plugin zip for your cluster version (example for 2.3.0: `https://github.com/aiven/prometheus-exporter-plugin-for-opensearch/releases/download/2.3.0.0/prometheus-exporter-2.3.0.0.zip`) and provide it at a location the operator can reach. Configure that URL as `pluginURL` in the monitoring config. By default the convention shown below in the example will be used if no `pluginUrl` is specified.
Expand Down
9 changes: 9 additions & 0 deletions opensearch-operator/api/v1/opensearch_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ package v1
import (
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/intstr"
)

const (
Expand Down Expand Up @@ -58,6 +59,13 @@ type GeneralConfig struct {
SecurityContext *corev1.SecurityContext `json:"securityContext,omitempty"`
}

type PdbConfig struct {
EnablePDB bool `json:"enablePDB,omitempty"`
idanl21 marked this conversation as resolved.
Show resolved Hide resolved
MinAvailable *intstr.IntOrString `json:"minAvailable,omitempty"`
MaxUnavailable *intstr.IntOrString `json:"maxUnavailable,omitempty"`
Selector metav1.LabelSelector `json:"selector,omitempty"`
idanl21 marked this conversation as resolved.
Show resolved Hide resolved
}

type InitHelperConfig struct {
*ImageSpec `json:",inline,omitempty"`
Resources corev1.ResourceRequirements `json:"resources,omitempty"`
Expand All @@ -81,6 +89,7 @@ type NodePool struct {
Annotations map[string]string `json:"annotations,omitempty"`
Env []corev1.EnvVar `json:"env,omitempty"`
PriorityClassName string `json:"priorityClassName,omitempty"`
Pdb PdbConfig `json:"pdb,omitempty"`
idanl21 marked this conversation as resolved.
Show resolved Hide resolved
}

// PersistencConfig defines options for data persistence
Expand Down
28 changes: 28 additions & 0 deletions opensearch-operator/api/v1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -4334,6 +4334,70 @@ spec:
additionalProperties:
type: string
type: object
pdb:
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The change also needs to be copied into the helm chart

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CRD changes have not been copied to helm chart

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changes have still not been copied to the helm chart

properties:
enablePDB:
type: boolean
maxUnavailable:
anyOf:
- type: integer
- type: string
x-kubernetes-int-or-string: true
minAvailable:
anyOf:
- type: integer
- type: string
x-kubernetes-int-or-string: true
selector:
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
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
type: array
required:
- 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.
type: object
type: object
x-kubernetes-map-type: atomic
type: object
persistence:
description: PersistencConfig defines options for data persistence
properties:
Expand Down
13 changes: 13 additions & 0 deletions opensearch-operator/controllers/cluster_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"time"

monitoring "github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1"
v1 "k8s.io/api/policy/v1"
idanl21 marked this conversation as resolved.
Show resolved Hide resolved

. "github.com/kralicky/kmatch"
. "github.com/onsi/ginkgo/v2"
Expand Down Expand Up @@ -490,5 +491,17 @@ var _ = Describe("Cluster Reconciler", func() {
}
wg.Wait()
})
When("pdb is enable", func() {
It("Create a pdb resource", func() {
pdb := v1.PodDisruptionBudget{}
Eventually(func() bool {
if err := k8sClient.Get(context.Background(), client.ObjectKeyFromObject(&pdb), &pdb); err != nil {
return false
}
return true
}, timeout, interval)
})
})

})
})
14 changes: 12 additions & 2 deletions opensearch-operator/controllers/suite_test_helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package controllers

import (
"context"
"k8s.io/apimachinery/pkg/util/intstr"
"strings"

appsv1 "k8s.io/api/apps/v1"
Expand Down Expand Up @@ -175,8 +176,17 @@ func ComposeOpensearchCrd(clusterName string, namespace string) opsterv1.OpenSea
},
NodePools: []opsterv1.NodePool{{
Component: "master",
Replicas: 3,
DiskSize: "32Gi",
Pdb: opsterv1.PdbConfig{
EnablePDB: true,
MinAvailable: &intstr.IntOrString{
IntVal: 3,
},
MaxUnavailable: &intstr.IntOrString{
IntVal: 3,
},
idanl21 marked this conversation as resolved.
Show resolved Hide resolved
},
Replicas: 3,
DiskSize: "32Gi",
Resources: corev1.ResourceRequirements{
Limits: corev1.ResourceList{
corev1.ResourceCPU: resource.MustParse("500m"),
Expand Down
3 changes: 3 additions & 0 deletions opensearch-operator/examples/opensearch-cluster.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@ spec:
smartScaler: true
nodePools:
- component: masters
pdb:
enablePDB: true
minAvailable: 3
idanl21 marked this conversation as resolved.
Show resolved Hide resolved
replicas: 3
diskSize: "30Gi"
nodeSelector:
Expand Down
67 changes: 66 additions & 1 deletion opensearch-operator/pkg/reconcilers/cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ import (
"context"
"encoding/json"
"fmt"

batchv1 "k8s.io/api/batch/v1"
v1 "k8s.io/api/policy/v1"
"opensearch.opster.io/pkg/reconcilers/util"

"github.com/banzaicloud/k8s-objectmatcher/patch"
Expand Down Expand Up @@ -286,6 +286,71 @@ func (r *ClusterReconciler) reconcileNodeStatefulSet(nodePool opsterv1.NodePool,
}
}

// Habdle PDB
needToUpdate := false
// Check if it needed
if nodePool.Pdb.EnablePDB {
idanl21 marked this conversation as resolved.
Show resolved Hide resolved

pdb := v1.PodDisruptionBudget{}
newpdb := v1.PodDisruptionBudget{}
// Check if it already exist
if err = r.Get(r.ctx, client.ObjectKey{Name: r.instance.Name + "-" + nodePool.Component + "-pdb", Namespace: r.instance.Namespace}, &pdb); err == nil {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No need to do this diff logic, just generate the PDB as it should be and then use reconcileResource

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you mean that i have to reconcile it everytime after that it exist without any diff checking ? why ?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The diff checking is done by reconcileResource using kubernetes mechanisms, which is safer and cleaner than doing it yourself. Also we use this mechanism everywhere else in the operator so using reconcileResource is consistent.

// IF the resource exist, start to check if there is any changes in the configurations
if pdb.Spec.MaxUnavailable != nil {
if pdb.Spec.MaxUnavailable.IntVal != nodePool.Pdb.MaxUnavailable.IntVal {
pdb.Spec.MaxUnavailable.IntVal = nodePool.Pdb.MaxUnavailable.IntVal
needToUpdate = true
}
}
if pdb.Spec.MinAvailable != nil {
if pdb.Spec.MinAvailable.IntVal != nodePool.Pdb.MinAvailable.IntVal {
pdb.Spec.MinAvailable.IntVal = nodePool.Pdb.MinAvailable.IntVal
needToUpdate = true
}
}
// Update configuration and requeue
if needToUpdate {
r.logger.Info("Updating PDB ")
if err = r.Update(r.ctx, &pdb); err != nil {
return result, err
}
}
} else {

// If it not exists , build && create it but before check that all the parameters are provided
idanl21 marked this conversation as resolved.
Show resolved Hide resolved
if (nodePool.Pdb.MinAvailable != nil && nodePool.Pdb.MaxUnavailable != nil) || (nodePool.Pdb.MinAvailable == nil && nodePool.Pdb.MaxUnavailable == nil) {
r.logger.Info(" Aborting PodDisruptionBudget creation - Please provided one parameter (MinAvailable OR MaxUnavailable) in order to create PodDisruptionBudget resource")
idanl21 marked this conversation as resolved.
Show resolved Hide resolved

} else {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you should also have logic to generate a default PDB if neither MinAvailable or MaxUnavailable are set. A good default could be to set MaxUnAvailable=1.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So i thought about that also, but i could not find any docs of ES/OS that they are reocmmend about default value...
only that : https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-pod-disruption-budget.html
and the value here is true.
I dont what to make customers to expirince things that they are not defined.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the second paragraph of the elastic docs you linked is written "ECK manages a default PDB per Elasticsearch resource. It allows one Elasticsearch Pod to be taken down". That for me is a clear indication that the default is MaxUnavailable=1. So doing it the same for our operator would be consistent.

I dont what to make customers to expirince things that they are not defined.

They need to explicitly enable the budget anyway, and as long as it is documented what the default budget is I don't see a problem with that. On the contrary, one of the jobs of the operator is to do sensible defaults, so setting a default config for the budget if the user enables it is normal behaviour IMO.

// If all details are proveided, build and create PDB
idanl21 marked this conversation as resolved.
Show resolved Hide resolved
matchLabels := map[string]string{
helpers.ClusterLabel: r.instance.Name,
helpers.NodePoolLabel: nodePool.Component,
}
// Build the PDB resource
newpdb = v1.PodDisruptionBudget{
ObjectMeta: metav1.ObjectMeta{
Name: r.instance.Name + "-" + nodePool.Component + "-pdb",
Namespace: r.instance.Namespace,
},
Spec: v1.PodDisruptionBudgetSpec{
MinAvailable: nodePool.Pdb.MinAvailable,
Selector: &metav1.LabelSelector{
MatchLabels: matchLabels,
},
MaxUnavailable: nodePool.Pdb.MaxUnavailable,
},
}
// Create the PDB resource
err = r.Create(r.ctx, &newpdb)
idanl21 marked this conversation as resolved.
Show resolved Hide resolved
if err != nil {
return result, err
}
}

}
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This needs an else to delete a potentially existing PDB if enable is set to false

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Else case is still missing

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Deletion is still not handled, is it?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Else with deletion is not handled


// Handle PVC resizing

//Default is PVC, or explicit check for PersistenceSource as PVC
Expand Down