Browse Source

In 290 (#14)

* pdb

* pdb

* IN-290

* pdb

* pdb

* fix deploy

* fix deploy prod
master
Yaroslav 4 weeks ago
parent
commit
8d2fda767e

+ 4
- 0
Jenkinsfile View File

@@ -57,6 +57,7 @@ spec:
"""
archiveArtifacts: 'operator.yaml'
sh "kubectl apply -f operator.yaml -n messaging"
sh "kubectl apply -f deploy/deploy-operator-default/clusterrole.yaml"
}
} else {
// deploy PR to sandbox
@@ -99,6 +100,9 @@ spec:
sh "HOME=/root;KUBECONFIG=/root/.kube/sandbox.config kubectl create ns rabbitmq-operator-${branch} || true"
sh "HOME=/root;KUBECONFIG=/root/.kube/sandbox.config kubectl apply -f deploy/deploy-operator-default/service_account.yaml -n rabbitmq-operator-${branch} || true"
sh "HOME=/root;KUBECONFIG=/root/.kube/sandbox.config kubectl apply -f deploy/deploy-operator-default/role_binding.yaml -n rabbitmq-operator-${branch} || true"
sh "HOME=/root;KUBECONFIG=/root/.kube/sandbox.config kubectl apply -f deploy/deploy-operator-default/role.yaml -n rabbitmq-operator-${branch} || true"
sh "HOME=/root;KUBECONFIG=/root/.kube/sandbox.config kubectl apply -f deploy/deploy-operator-default/clusterrole.yaml -n rabbitmq-operator-${branch} || true"
sh "HOME=/root;KUBECONFIG=/root/.kube/sandbox.config kubectl apply -f deploy/deploy-operator-default/clusterrolebinding.yaml -n rabbitmq-operator-${branch} || true"
sh "HOME=/root;KUBECONFIG=/root/.kube/sandbox.config kubectl apply -f operator.yaml -n rabbitmq-operator-${branch} || true"
}
}

+ 6
- 0
deploy/deploy-operator-debug/clusterrole.yaml View File

@@ -51,3 +51,9 @@ rules:
- '*'
verbs:
- '*'
- apiGroups:
- policy
resources:
- poddisruptionbudgets
verbs:
- '*'

+ 6
- 0
deploy/deploy-operator-debug/role.yaml View File

@@ -43,3 +43,9 @@ rules:
- '*'
verbs:
- '*'
- apiGroups:
- policy
resources:
- poddisruptionbudgets
verbs:
- '*'

+ 0
- 4
deploy/deploy-operator-debug/service_account.yaml View File

@@ -1,4 +0,0 @@
apiVersion: v1
kind: ServiceAccount
metadata:
name: rabbitmq-operator

+ 6
- 0
deploy/deploy-operator-default/clusterrole.yaml View File

@@ -51,3 +51,9 @@ rules:
- '*'
verbs:
- '*'
- apiGroups:
- policy
resources:
- poddisruptionbudgets
verbs:
- '*'

+ 6
- 0
deploy/deploy-operator-default/role.yaml View File

@@ -43,3 +43,9 @@ rules:
- '*'
verbs:
- '*'
- apiGroups:
- policy
resources:
- poddisruptionbudgets
verbs:
- '*'

+ 8
- 3
pkg/apis/rabbitmq/v1/rabbitmq_types.go View File

@@ -2,6 +2,7 @@ package v1

import (
corev1 "k8s.io/api/core/v1"
"k8s.io/api/policy/v1beta1"
"k8s.io/apimachinery/pkg/api/resource"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
@@ -60,6 +61,10 @@ type RabbitmqSpec struct {
// +kubebuilder:validation:Maximum=10
RabbitmqReplicas int32 `json:"replicas"`

// set PodDisruptionBudget. Default values: if replicas >= 2, minA = 1
// else if replicas = 1, maxU = 1
RabbitmqPdb v1beta1.PodDisruptionBudget `json:"pdb,omitempty"`

// set default_vhost, if empty falling to "%2f" (/)
RabbitmqVhost string `json:"default_vhost,omitempty"`

@@ -119,9 +124,9 @@ type RabbitmqSpec struct {
RabbitmqPrometheusExporterPort int32 `json:"prometheus_exporter_port,omitempty"`
RabbitmqPrometheusImage string `json:"prometheus_image,omitempty"`

RabbitmqAffinity *corev1.Affinity `json:"affinity,omitempty"`
NodeSelector map[string]string `json:"nodeSelector"`
Tolerations []corev1.Toleration `json:"tolerations"`
RabbitmqAffinity *corev1.Affinity `json:"affinity,omitempty"`
NodeSelector map[string]string `json:"nodeSelector"`
Tolerations []corev1.Toleration `json:"tolerations"`

RabbitmqUseServiceMonitor bool `json:"use_service_monitor,omitempty"`
}

+ 1
- 0
pkg/apis/rabbitmq/v1/zz_generated.deepcopy.go View File

@@ -160,6 +160,7 @@ func (in *RabbitmqSSL) DeepCopy() *RabbitmqSSL {
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *RabbitmqSpec) DeepCopyInto(out *RabbitmqSpec) {
*out = *in
in.RabbitmqPdb.DeepCopyInto(&out.RabbitmqPdb)
out.RabbitmqSSL = in.RabbitmqSSL
in.RabbitmqAuth.DeepCopyInto(&out.RabbitmqAuth)
if in.RabbitmqPolicies != nil {

+ 11
- 2
pkg/controller/rabbitmq/rabbitmq_controller.go View File

@@ -329,6 +329,15 @@ func (r *ReconcileRabbitmq) Reconcile(request reconcile.Request) (reconcile.Resu
}
}

// reconcile PodDisruptionBudget
reqLogger.Info("Reconciling PodDisruptionBudget")

_, err = r.reconcilePdb(reqLogger, instance)
if err != nil {
raven.CaptureErrorAndWait(err, nil)
return reconcile.Result{}, err
}

_, err = r.reconcileFinalizers(reqLogger, instance)
if err != nil {
raven.CaptureErrorAndWait(err, nil)
@@ -473,8 +482,8 @@ func newStatefulSet(cr *rabbitmqv1.Rabbitmq, secretNames secretResouces) *v1.Sta
},
},
},
Containers: podContainers,
Tolerations: cr.Spec.Tolerations,
Containers: podContainers,
Tolerations: cr.Spec.Tolerations,
NodeSelector: cr.Spec.NodeSelector,
Volumes: []corev1.Volume{
{

+ 97
- 0
pkg/controller/rabbitmq/rabbitmq_pdb.go View File

@@ -0,0 +1,97 @@
package rabbitmq

import (
"context"
"github.com/getsentry/raven-go"
"github.com/go-logr/logr"
v1beta1policy "k8s.io/api/policy/v1beta1"
apierrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/types"
"k8s.io/apimachinery/pkg/util/intstr"
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
"sigs.k8s.io/controller-runtime/pkg/reconcile"

rabbitmqv1 "github.com/tekliner/rabbitmq-operator/pkg/apis/rabbitmq/v1"
)

func (r *ReconcileRabbitmq) reconcilePdb(reqLogger logr.Logger, cr *rabbitmqv1.Rabbitmq) (reconcile.Result, error) {

newPdb := getDisruptionBudget(cr)
reqLogger.Info("Started reconciling PodDisruptionBudget", "Pdb.Namespace", newPdb.Namespace, "Pdb.Name", newPdb.Name)

if err := controllerutil.SetControllerReference(cr, &newPdb, r.scheme); err != nil {
reqLogger.Info("Error setting controller reference for PodDisruptionBudget", "Pdb.Namespace", &newPdb.Namespace, "Pdb.Name", &newPdb.Name)
return reconcile.Result{}, err
}
// Check existing pdb
foundPdb := &v1beta1policy.PodDisruptionBudget{}
reqLogger.Info("Getting PodDisruptionBudget", "Pdb.Namespace", &newPdb.Namespace, "Pdb.Name", &newPdb.Name)
err := r.client.Get(context.TODO(), types.NamespacedName{Name: newPdb.Name, Namespace: newPdb.Namespace}, foundPdb)

if err != nil && apierrors.IsNotFound(err) {
reqLogger.Info("No PodDisruptionBudget found, creating new", "Pdb.Namespace", &newPdb.Namespace, "Pdb.Name", &newPdb.Name)
err = r.client.Create(context.TODO(), &newPdb)
foundPdb = &newPdb

if err != nil {
reqLogger.Info("Error creating new PodDisruptionBudget", "Pdb.Namespace", &newPdb.Namespace, "Pdb.Name", &newPdb.Name)
return reconcile.Result{}, err
}
} else if err != nil {
reqLogger.Info("Error getting PodDisruptionBudget", "Pdb.Namespace", &newPdb.Namespace, "Pdb.Name", &newPdb.Name)
return reconcile.Result{}, err
} else {
if reconcileRequired, reconPdb := reconcilePdb(reqLogger, *foundPdb, newPdb); reconcileRequired {
reqLogger.Info("Updating PodDisruptionBudget", "Namespace", reconPdb.Namespace, "Name", reconPdb.Name)
if err = r.client.Update(context.TODO(), &reconPdb); err != nil {
reqLogger.Info("Reconcile PodDisruptionBudget error", "Namespace", foundPdb.Namespace, "Name", foundPdb.Name)
raven.CaptureErrorAndWait(err, nil)
return reconcile.Result{}, err
}
}
}

return reconcile.Result{}, nil
}

func getDisruptionBudget(cr *rabbitmqv1.Rabbitmq) v1beta1policy.PodDisruptionBudget {
podDisruptionBudget := v1beta1policy.PodDisruptionBudget{}
labelSelector := metav1.LabelSelector{MatchLabels: cr.Labels}
if cr.Spec.RabbitmqReplicas >= 2 {
specPDB := v1beta1policy.PodDisruptionBudgetSpec{Selector: &labelSelector}

if cr.Spec.RabbitmqPdb.Spec.MinAvailable != nil && cr.Spec.RabbitmqPdb.Spec.MaxUnavailable != nil {
specPDB.MinAvailable = cr.Spec.RabbitmqPdb.Spec.MinAvailable
} else if cr.Spec.RabbitmqPdb.Spec.MinAvailable != nil {
specPDB.MinAvailable = cr.Spec.RabbitmqPdb.Spec.MinAvailable
} else if cr.Spec.RabbitmqPdb.Spec.MaxUnavailable != nil {
specPDB.MaxUnavailable = cr.Spec.RabbitmqPdb.Spec.MaxUnavailable
} else {
specPDB.MinAvailable = func() *intstr.IntOrString { v := intstr.FromInt(1); return &v }()
}

podDisruptionBudget = v1beta1policy.PodDisruptionBudget{
ObjectMeta: metav1.ObjectMeta{
Name: cr.Name,
Namespace: cr.Namespace,
},
Spec: specPDB,
}
} else {
maxUnavailable := intstr.FromInt(1)
specPDB := v1beta1policy.PodDisruptionBudgetSpec{
Selector: &labelSelector,
MaxUnavailable: &maxUnavailable,
}
podDisruptionBudget = v1beta1policy.PodDisruptionBudget{
ObjectMeta: metav1.ObjectMeta{
Name: cr.Name,
Namespace: cr.Namespace,
},
Spec: specPDB,
}
}
return podDisruptionBudget

}

+ 30
- 0
pkg/controller/rabbitmq/reconcile.go View File

@@ -0,0 +1,30 @@
package rabbitmq

import (
"github.com/go-logr/logr"
"k8s.io/api/policy/v1beta1"
"reflect"
)

func reconcilePdb(reqLogger logr.Logger, foundPdb v1beta1.PodDisruptionBudget, newPdb v1beta1.PodDisruptionBudget) (bool, v1beta1.PodDisruptionBudget) {

reconcileRequired := false
if !reflect.DeepEqual(foundPdb.Spec.Selector, newPdb.Spec.Selector) {
reqLogger.Info("Selectors not deep equal", "Pdb.Namespace", &newPdb.Namespace, "Pdb.Name", &newPdb.Name)
foundPdb.Spec.Selector = newPdb.Spec.Selector
reconcileRequired = true
}

if !reflect.DeepEqual(foundPdb.Spec.MaxUnavailable, newPdb.Spec.MaxUnavailable) {
reqLogger.Info("MaxUnavailable not deep equal", "Pdb.Namespace", &newPdb.Namespace, "Pdb.Name", &newPdb.Name)
foundPdb.Spec.MaxUnavailable = newPdb.Spec.MaxUnavailable
reconcileRequired = true
}

if !reflect.DeepEqual(foundPdb.Spec.MinAvailable, newPdb.Spec.MinAvailable) {
reqLogger.Info("MinAvailable not deep equal", "Pdb.Namespace", &newPdb.Namespace, "Pdb.Name", &newPdb.Name)
foundPdb.Spec.MinAvailable = newPdb.Spec.MinAvailable
reconcileRequired = true
}
return reconcileRequired, foundPdb
}

Loading…
Cancel
Save