Skip to content

Commit 42eaa01

Browse files
Microzuul CIGerrit Code Review
authored andcommitted
Merge "Implement PodDisruptionBudget and RollingUpdate for HA"
2 parents c2afb23 + 799aa1c commit 42eaa01

5 files changed

Lines changed: 57 additions & 0 deletions

File tree

controllers/libs/base/base.go

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import (
1313
appsv1 "k8s.io/api/apps/v1"
1414
batchv1 "k8s.io/api/batch/v1"
1515
apiv1 "k8s.io/api/core/v1"
16+
policyv1 "k8s.io/api/policy/v1"
1617
"k8s.io/apimachinery/pkg/api/resource"
1718
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
1819
"k8s.io/apimachinery/pkg/util/intstr"
@@ -27,6 +28,23 @@ var DefaultPodSecurityContext = apiv1.PodSecurityContext{
2728
},
2829
}
2930

31+
// MkPodDisruptionBudget produces a PodDisruptionBudget.
32+
func MkPodDisruptionBudget(name, ns string, maxUnavailable int32, selector, annotations map[string]string) policyv1.PodDisruptionBudget {
33+
return policyv1.PodDisruptionBudget{
34+
ObjectMeta: metav1.ObjectMeta{
35+
Name: name,
36+
Namespace: ns,
37+
Annotations: annotations,
38+
},
39+
Spec: policyv1.PodDisruptionBudgetSpec{
40+
MaxUnavailable: utils.IntOrStringPtr(maxUnavailable),
41+
Selector: &metav1.LabelSelector{
42+
MatchLabels: selector,
43+
},
44+
},
45+
}
46+
}
47+
3048
// MkSecurityContext produces a SecurityContext
3149
func MkSecurityContext(privileged bool, openshiftUser bool) *apiv1.SecurityContext {
3250
scc := &apiv1.SecurityContext{

controllers/libs/utils/utils.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import (
2222
"golang.org/x/crypto/ssh"
2323
"gopkg.in/ini.v1"
2424
"k8s.io/apimachinery/pkg/api/resource"
25+
"k8s.io/apimachinery/pkg/util/intstr"
2526
)
2627

2728
// GetEnvVarValue returns the value of the named env var. Return an empty string when not found.
@@ -35,6 +36,9 @@ func GetEnvVarValue(varName string) (string, error) {
3536

3637
func Int32Ptr(i int32) *int32 { return &i }
3738
func BoolPtr(b bool) *bool { return &b }
39+
func IntOrStringPtr(i int32) *intstr.IntOrString {
40+
return &intstr.IntOrString{Type: intstr.Int, IntVal: i}
41+
}
3842

3943
var Execmod int32 = 493 // decimal for 0755 octal
4044
var Readmod int32 = 292 // decimal for 0444 octal

controllers/utils.go

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ import (
3333

3434
appsv1 "k8s.io/api/apps/v1"
3535
apiv1 "k8s.io/api/core/v1"
36+
policyv1 "k8s.io/api/policy/v1"
3637
storagev1 "k8s.io/api/storage/v1"
3738
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
3839

@@ -1060,3 +1061,28 @@ func WaitFor(ensureFun func() bool, linear bool) bool {
10601061
time.Sleep(duration)
10611062
}
10621063
}
1064+
1065+
// EnsurePodDisruptionBudget ensures a PodDisruptionBudget exists
1066+
// The PodDisruptionBudget is updated if needed
1067+
func (r *SFKubeContext) EnsurePodDisruptionBudget(pdb *policyv1.PodDisruptionBudget) {
1068+
var current policyv1.PodDisruptionBudget
1069+
name := pdb.GetName()
1070+
1071+
if !r.GetOrDie(name, &current) {
1072+
if !r.DryRun {
1073+
logging.LogI("Creating PodDisruptionBudget, name: " + name)
1074+
}
1075+
r.CreateR(pdb)
1076+
} else {
1077+
if !reflect.DeepEqual(current.Spec, pdb.Spec) || !utils.MapEquals(&current.ObjectMeta.Annotations, &pdb.ObjectMeta.Annotations) {
1078+
if r.DryRun {
1079+
logging.LogI("[Dry Run] Would update PodDisruptionBudget, name: " + name + ". Reason: Spec or Annotations have changed")
1080+
} else {
1081+
logging.LogI("Updating PodDisruptionBudget, name: " + name)
1082+
}
1083+
current.Spec = pdb.Spec
1084+
current.ObjectMeta.Annotations = pdb.ObjectMeta.Annotations
1085+
r.UpdateR(&current)
1086+
}
1087+
}
1088+
}

controllers/zookeeper.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ const zkServerPort = 2888
4141

4242
const ZookeeperIdent = "zookeeper"
4343
const ZookeeperReplicas = 3
44+
const ZookeeperMaxUnavailable = 1
4445

4546
const zkPIMountPath = "/config-scripts"
4647

@@ -175,8 +176,14 @@ func (r *SFController) DeployZookeeper() bool {
175176
StorageClassName: storageConfig.StorageClassName,
176177
ExtraAnnotations: storageConfig.ExtraAnnotations,
177178
}
179+
pdb := base.MkPodDisruptionBudget(ZookeeperIdent, r.Ns, ZookeeperMaxUnavailable, map[string]string{"app": "sf", "run": ZookeeperIdent}, nil)
180+
r.EnsurePodDisruptionBudget(&pdb)
178181
zk := r.mkHeadlessStatefulSet(
179182
ZookeeperIdent, base.ZookeeperImage(), storageConfig, apiv1.ReadWriteOnce, r.cr.Spec.ExtraLabels, r.IsOpenShift)
183+
zk.Spec.UpdateStrategy = appsv1.StatefulSetUpdateStrategy{
184+
Type: appsv1.RollingUpdateStatefulSetStrategyType,
185+
}
186+
zk.Spec.PodManagementPolicy = appsv1.OrderedReadyPodManagement
180187
// We overwrite the VolumeClaimTemplates set by MkHeadlessStatefulSet to keep the previous volume name
181188
// Previously the default PVC created by MkHeadlessStatefulSet was not used by Zookeeper (not mounted). So to avoid having two Volumes
182189
// and to ensure data persistence during the upgrade we keep the previous naming 'ZookeeperIdent + "-data"' and we discard the one

docs/reference/CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ All notable changes to this project will be documented in this file.
1111
While the process handles snapshotting Zookeeper's data and restoring it to all pods after the extra replicas rollout, you are **strongly** advised
1212
to perform a backup with the sf-operator CLI before upgrading to avoid accidental data loss.
1313
PKI certificates will be recreated to reflect the new ensemble setup.
14+
- Added `PodDisruptionBudget` and `RollingUpdate` strategy to the Zookeeper controller, in accordance with zookeeper
15+
being now deployed as a 3-replica ensemble (see below).
1416

1517
### Deprecated
1618
### Removed

0 commit comments

Comments
 (0)