diff --git a/internal/controllers/common/resource_definitions/resource_definitions.go b/internal/controllers/common/resource_definitions/resource_definitions.go index 5f46968b..5a4e5e0e 100644 --- a/internal/controllers/common/resource_definitions/resource_definitions.go +++ b/internal/controllers/common/resource_definitions/resource_definitions.go @@ -101,6 +101,8 @@ const ( func NewDeploymentForCR(cr *operatorv1beta1.Cryostat, specs *ServiceSpecs, imageTags *ImageTags, tls *TLSConfig, fsGroup int64, openshift bool) *appsv1.Deployment { + // Force one replica to avoid lock file and PVC contention + replicas := int32(1) return &appsv1.Deployment{ ObjectMeta: metav1.ObjectMeta{ Name: cr.Name, @@ -136,6 +138,10 @@ func NewDeploymentForCR(cr *operatorv1beta1.Cryostat, specs *ServiceSpecs, image }, Spec: *NewPodForCR(cr, specs, imageTags, tls, fsGroup, openshift), }, + Replicas: &replicas, + Strategy: appsv1.DeploymentStrategy{ + Type: appsv1.RecreateDeploymentStrategyType, + }, }, } } diff --git a/internal/controllers/cryostat_controller.go b/internal/controllers/cryostat_controller.go index 625d939c..65064def 100644 --- a/internal/controllers/cryostat_controller.go +++ b/internal/controllers/cryostat_controller.go @@ -500,10 +500,10 @@ func (r *CryostatReconciler) createOrUpdateDeployment(ctx context.Context, deplo // Return error so deployment can be recreated return errSelectorModified } - // Set the replica count, if managed by the operator - if deployCopy.Spec.Replicas != nil { - deploy.Spec.Replicas = deployCopy.Spec.Replicas - } + // Set the replica count and update strategy + deploy.Spec.Replicas = deployCopy.Spec.Replicas + deploy.Spec.Strategy = deployCopy.Spec.Strategy + // Update pod template spec to propagate any changes from Cryostat CR deploy.Spec.Template.Spec = deployCopy.Spec.Template.Spec // Update pod template metadata diff --git a/internal/controllers/cryostat_controller_test.go b/internal/controllers/cryostat_controller_test.go index 641ede60..0831ea22 100644 --- a/internal/controllers/cryostat_controller_test.go +++ b/internal/controllers/cryostat_controller_test.go @@ -309,7 +309,8 @@ var _ = Describe("CryostatController", func() { // Deployment Selector is immutable Expect(deploy.Spec.Selector).To(Equal(oldDeploy.Spec.Selector)) - Expect(deploy.Spec.Replicas).To(Equal(oldDeploy.Spec.Replicas)) + Expect(deploy.Spec.Replicas).To(Equal(&[]int32{1}[0])) + Expect(deploy.Spec.Strategy).To(Equal(test.NewMainDeploymentStrategy())) }) Context("with a different selector", func() { BeforeEach(func() { @@ -2578,6 +2579,9 @@ func (t *cryostatTestInput) checkMainDeployment() { })) Expect(metav1.IsControlledBy(deployment, cr)).To(BeTrue()) Expect(deployment.Spec.Selector).To(Equal(test.NewMainDeploymentSelector())) + Expect(deployment.Spec.Replicas).ToNot(BeNil()) + Expect(*deployment.Spec.Replicas).To(Equal(int32(1))) + Expect(deployment.Spec.Strategy).To(Equal(test.NewMainDeploymentStrategy())) // compare Pod template t.checkMainPodTemplate(deployment, cr) @@ -2669,7 +2673,9 @@ func (t *cryostatTestInput) checkReportsDeployment() { })) Expect(metav1.IsControlledBy(deployment, cr)).To(BeTrue()) Expect(deployment.Spec.Selector).To(Equal(test.NewReportsDeploymentSelector())) + Expect(deployment.Spec.Replicas).ToNot(BeNil()) Expect(*deployment.Spec.Replicas).To(Equal(t.reportReplicas)) + Expect(deployment.Spec.Strategy).To(BeZero()) // compare Pod template template := deployment.Spec.Template diff --git a/internal/test/resources.go b/internal/test/resources.go index 2d126064..b4a0060a 100644 --- a/internal/test/resources.go +++ b/internal/test/resources.go @@ -1720,6 +1720,12 @@ func NewReportsDeploymentSelector() *metav1.LabelSelector { } } +func NewMainDeploymentStrategy() appsv1.DeploymentStrategy { + return appsv1.DeploymentStrategy{ + Type: appsv1.RecreateDeploymentStrategyType, + } +} + func OtherDeployment() *appsv1.Deployment { replicas := int32(2) return &appsv1.Deployment{