mon: fix mon failover on path change

This PR fails over mon when the mon path is changed from hostPath to PVC or vice versa

Signed-off-by: sp98 <sapillai@redhat.com>
(cherry picked from commit 4b6fd89365)
This commit is contained in:
sp98 authored and travisn committed 2023-12-12 11:06:14 -07:00
1 parent f032fef069
commit 365aa4658a
4 files changed
+59 -56

No files matched your search

+4 -17
View File
@@ -366,11 +366,12 @@ func (c *Cluster) checkHealth(ctx context.Context) error {
}
}
// failover mons running on host path to use persistent volumes if VolumeClaimTemplate is set and vice versa
// failover any mons present in the mon fail over list
for _, mon := range c.ClusterInfo.Monitors {
if c.HasMonPathChanged(mon.Name) {
logger.Infof("fail over mon %q due to change in mon path", mon.Name)
if c.monsToFailover.Has(mon.Name) {
logger.Infof("fail over mon %q from the mon fail over list", mon.Name)
c.failMon(len(c.ClusterInfo.Monitors), desiredMonCount, mon.Name)
c.monsToFailover.Delete(mon.Name)
return nil
}
}
@@ -378,20 +379,6 @@ func (c *Cluster) checkHealth(ctx context.Context) error {
return nil
}
// HasMonPathChanged checks if the mon storage path has changed from host path to persistent volume or vice versa
func (c *Cluster) HasMonPathChanged(mon string) bool {
var monPathChanged bool
if c.mapping.Schedule[mon] != nil && c.spec.Mon.VolumeClaimTemplate != nil {
logger.Infof("mon %q path has changed from host path to persistent volumes", mon)
monPathChanged = true
} else if c.mapping.Schedule[mon] == nil && c.spec.Mon.VolumeClaimTemplate == nil {
logger.Infof("mon %q path has changed from persistent volumes to host path", mon)
monPathChanged = true
}
return monPathChanged
}
func (c *Cluster) trackMonInOrOutOfQuorum(monName string, inQuorum bool) (bool, error) {
updateNeeded := false
var monsOutOfQuorum []string
@@ -645,37 +645,3 @@ func TestUpdateMonInterval(t *testing.T) {
assert.Equal(t, time.Minute, h.interval)
})
}
func TestHasMonPathChanged(t *testing.T) {
t.Run("mon path changed from pv to hostpath", func(t *testing.T) {
c := New(context.TODO(), &clusterd.Context{}, "ns", cephv1.ClusterSpec{}, nil)
c.mapping.Schedule["a"] = nil
result := c.HasMonPathChanged("a")
assert.True(t, result)
})
t.Run("mon path has not changed from pv to hostpath", func(t *testing.T) {
c := New(context.TODO(), &clusterd.Context{}, "ns", cephv1.ClusterSpec{}, nil)
c.spec.Mon.VolumeClaimTemplate = &v1.PersistentVolumeClaim{Spec: v1.PersistentVolumeClaimSpec{}}
c.mapping.Schedule["b"] = nil
result := c.HasMonPathChanged("b")
c.spec.Mon.VolumeClaimTemplate = nil
assert.False(t, result)
})
t.Run("mon path changed from hostpath to pv", func(t *testing.T) {
c := New(context.TODO(), &clusterd.Context{}, "ns", cephv1.ClusterSpec{}, nil)
c.mapping.Schedule["c"] = &opcontroller.MonScheduleInfo{}
c.spec.Mon.VolumeClaimTemplate = &v1.PersistentVolumeClaim{Spec: v1.PersistentVolumeClaimSpec{}}
result := c.HasMonPathChanged("c")
assert.True(t, result)
})
t.Run("mon path has not changed from host path to pv", func(t *testing.T) {
c := New(context.TODO(), &clusterd.Context{}, "ns", cephv1.ClusterSpec{}, nil)
c.mapping.Schedule["d"] = &opcontroller.MonScheduleInfo{}
result := c.HasMonPathChanged("d")
c.spec.Mon.VolumeClaimTemplate = nil
assert.False(t, result)
})
}
+21 -5
View File
@@ -115,6 +115,8 @@ type Cluster struct {
ownerInfo *k8sutil.OwnerInfo
isUpgrade bool
arbiterMon string
// list of mons to be failed over
monsToFailover sets.Set[string]
}
// monConfig for a single monitor
@@ -162,6 +164,7 @@ func New(ctx context.Context, clusterdContext *clusterd.Context, namespace strin
ClusterInfo: &cephclient.ClusterInfo{
Context: ctx,
},
monsToFailover: sets.New[string](),
}
}
@@ -1230,11 +1233,6 @@ var updateDeploymentAndWait = UpdateCephDeploymentAndWait
func (c *Cluster) updateMon(m *monConfig, d *apps.Deployment) error {
if c.HasMonPathChanged(m.DaemonName) {
logger.Infof("path has changed for mon %q. Skip updating mon deployment %q in order to failover the mon", m.DaemonName, d.Name)
return nil
}
// Expand mon PVC if storage request for mon has increased in cephcluster crd
if c.monVolumeClaimTemplate(m) != nil {
desiredPvc, err := c.makeDeploymentPVC(m, false)
@@ -1339,6 +1337,12 @@ func (c *Cluster) startMon(m *monConfig, schedule *controller.MonScheduleInfo) e
p.ApplyToPodSpec(&d.Spec.Template.Spec)
if deploymentExists {
// skip update if mon path has changed
if hasMonPathChanged(existingDeployment, c.spec.Mon.VolumeClaimTemplate) {
c.monsToFailover.Insert(m.DaemonName)
return nil
}
// the existing deployment may have a node selector. if the cluster
// isn't using host networking and the deployment is using pvc storage,
// then the node selector can be removed. this may happen after
@@ -1404,6 +1408,18 @@ func (c *Cluster) startMon(m *monConfig, schedule *controller.MonScheduleInfo) e
return nil
}
func hasMonPathChanged(d *apps.Deployment, claim *v1.PersistentVolumeClaim) bool {
if d.Labels["pvc_name"] == "" && claim != nil {
logger.Infof("skipping update for mon %q where path has changed from hostPath to pvc", d.Name)
return true
} else if d.Labels["pvc_name"] != "" && claim == nil {
logger.Infof("skipping update for mon %q where path has changed from pvc to hostPath", d.Name)
return true
}
return false
}
func waitForQuorumWithMons(context *clusterd.Context, clusterInfo *cephclient.ClusterInfo, mons []string, sleepTime int, requireAllInQuorum bool) error {
logger.Infof("waiting for mon quorum with %v", mons)
+34
View File
@@ -40,6 +40,7 @@ import (
"github.com/rook/rook/pkg/operator/test"
exectest "github.com/rook/rook/pkg/util/exec/test"
"github.com/stretchr/testify/assert"
apps "k8s.io/api/apps/v1"
v1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
@@ -848,3 +849,36 @@ func TestCheckIfArbiterReady(t *testing.T) {
assert.False(t, ready)
assert.Error(t, err)
}
func TestHasMonPathChanged(t *testing.T) {
monDeployment := &apps.Deployment{
ObjectMeta: metav1.ObjectMeta{
Name: "rook-ceph-mon-a",
Namespace: "test",
Labels: map[string]string{
"pvc_name": "test-pvc",
},
}}
pvcTemplate := &v1.PersistentVolumeClaim{
ObjectMeta: metav1.ObjectMeta{
Name: "test-claim",
},
}
t.Run("mon path changed from pv to hostpath", func(t *testing.T) {
assert.True(t, hasMonPathChanged(monDeployment, nil))
})
t.Run("mon path not changed from pv to hostpath", func(t *testing.T) {
assert.False(t, hasMonPathChanged(monDeployment, pvcTemplate))
})
t.Run("mon path changed from hostPath to pvc", func(t *testing.T) {
delete(monDeployment.Labels, "pvc_name")
assert.True(t, hasMonPathChanged(monDeployment, pvcTemplate))
})
t.Run("mon path not changed from hostPath to pvc", func(t *testing.T) {
delete(monDeployment.Labels, "pvc_name")
assert.False(t, hasMonPathChanged(monDeployment, nil))
})
}