Skip to content

Commit 7515693

Browse files
feat(api): Replace fluentd deployment with statefulset (#370)
* Replace fluentd deployment with statefulset * Remove redundant pvc volume and refactor volume mount from fluentd pod spec * Refactor fluentd deletion steps to remove its stateful set * Add pod disruption budgets to fluentd stateful set * Shorten lines that are too long * Halve fluentd cpu and mem requests * Fix docstring typo * Configure fluentd flush interval seconds to make it dependent on the number of replicas * Refactor pvc deletion helper function to make it more generic * Make pdb key dependent on the component type to be deployed * Fix long line lint error * Fix unit tests after changes to pdb keys
1 parent 40df8e9 commit 7515693

File tree

10 files changed

+340
-337
lines changed

10 files changed

+340
-337
lines changed

api/turing/cluster/controller.go

Lines changed: 45 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -66,8 +66,8 @@ type Controller interface {
6666
ApplyIstioVirtualService(ctx context.Context, routerEndpoint *VirtualService) error
6767
DeleteIstioVirtualService(ctx context.Context, svcName string, namespace string) error
6868

69-
// Deployment
70-
DeleteKubernetesDeployment(ctx context.Context, name string, namespace string, ignoreNotFound bool) error
69+
// StatefulSet
70+
DeleteKubernetesStatefulSet(ctx context.Context, name string, namespace string, ignoreNotFound bool) error
7171

7272
// Service
7373
DeployKubernetesService(ctx context.Context, svc *KubernetesService) error
@@ -82,8 +82,7 @@ type Controller interface {
8282
DeleteSecret(ctx context.Context, secretName string, namespace string, ignoreNotFound bool) error
8383

8484
// PVC
85-
ApplyPersistentVolumeClaim(ctx context.Context, namespace string, pvc *PersistentVolumeClaim) error
86-
DeletePersistentVolumeClaim(ctx context.Context, pvcName string, namespace string, ignoreNotFound bool) error
85+
DeletePVCs(ctx context.Context, listOptions metav1.ListOptions, namespace string, ignoreNotFound bool) error
8786

8887
// Pod
8988
ListPods(ctx context.Context, namespace string, labelSelector string) (*apicorev1.PodList, error)
@@ -347,34 +346,34 @@ func (c *controller) GetKnativeServiceDesiredReplicas(
347346
return int(*rev.Status.DesiredReplicas), nil
348347
}
349348

350-
// DeployKubernetesService deploys a kubernetes service and deployment
349+
// DeployKubernetesService deploys a kubernetes service and stateful set
351350
func (c *controller) DeployKubernetesService(
352351
ctx context.Context,
353352
svcConf *KubernetesService,
354353
) error {
355-
desiredDeployment, desiredSvc := svcConf.BuildKubernetesServiceConfig()
354+
desiredStatefulSet, desiredSvc := svcConf.BuildKubernetesServiceConfig()
356355

357-
// Deploy deployment
358-
deployments := c.k8sAppsClient.Deployments(svcConf.Namespace)
359-
// Check if deployment already exists. If exists, update it. If not, create.
360-
var existingDeployment *apiappsv1.Deployment
356+
// Deploy stateful set
357+
statefulSets := c.k8sAppsClient.StatefulSets(svcConf.Namespace)
358+
// Check if stateful set already exists. If exists, update it. If not, create.
359+
var existingStatefulSet *apiappsv1.StatefulSet
361360
var err error
362-
existingDeployment, err = deployments.Get(ctx, svcConf.Name, metav1.GetOptions{})
361+
existingStatefulSet, err = statefulSets.Get(ctx, svcConf.Name, metav1.GetOptions{})
363362
if err != nil {
364363
if k8serrors.IsNotFound(err) {
365364
// Create new deployment
366-
_, err = deployments.Create(ctx, desiredDeployment, metav1.CreateOptions{})
365+
_, err = statefulSets.Create(ctx, desiredStatefulSet, metav1.CreateOptions{})
367366
} else {
368367
// Unexpected error, return it
369368
return err
370369
}
371370
} else {
372371
// Check for differences between current and new specs
373-
if !k8sDeploymentSemanticEquals(desiredDeployment, existingDeployment) {
372+
if !k8sStatefulSetSemanticEquals(existingStatefulSet, existingStatefulSet) {
374373
// Update the existing service with the new config
375-
existingDeployment.Spec.Template = desiredDeployment.Spec.Template
376-
existingDeployment.ObjectMeta.Labels = desiredDeployment.ObjectMeta.Labels
377-
_, err = deployments.Update(ctx, existingDeployment, metav1.UpdateOptions{})
374+
existingStatefulSet.Spec.Template = desiredStatefulSet.Spec.Template
375+
existingStatefulSet.ObjectMeta.Labels = desiredStatefulSet.ObjectMeta.Labels
376+
_, err = statefulSets.Update(ctx, existingStatefulSet, metav1.UpdateOptions{})
378377
}
379378
}
380379
if err != nil {
@@ -405,25 +404,25 @@ func (c *controller) DeployKubernetesService(
405404
}
406405

407406
// Wait until deployment ready and return any errors
408-
return c.waitDeploymentReady(ctx, svcConf.Name, svcConf.Namespace)
407+
return c.waitStatefulSetReady(ctx, svcConf.Name, svcConf.Namespace)
409408
}
410409

411-
// DeleteKubernetesDeployment deletes a kubernetes deployment
412-
func (c *controller) DeleteKubernetesDeployment(
410+
// DeleteKubernetesStatefulSet deletes a stateful set
411+
func (c *controller) DeleteKubernetesStatefulSet(
413412
ctx context.Context,
414413
name string,
415414
namespace string,
416415
ignoreNotFound bool,
417416
) error {
418-
deployments := c.k8sAppsClient.Deployments(namespace)
419-
_, err := deployments.Get(ctx, name, metav1.GetOptions{})
417+
statefulSets := c.k8sAppsClient.StatefulSets(namespace)
418+
_, err := statefulSets.Get(ctx, name, metav1.GetOptions{})
420419
if err != nil {
421420
if ignoreNotFound {
422421
return nil
423422
}
424423
return err
425424
}
426-
return deployments.Delete(ctx, name, metav1.DeleteOptions{})
425+
return statefulSets.Delete(ctx, name, metav1.DeleteOptions{})
427426
}
428427

429428
// DeleteKubernetesService deletes a kubernetes service
@@ -517,44 +516,21 @@ func (c *controller) GetKnativeServiceURL(ctx context.Context, svcName string, n
517516
return url
518517
}
519518

520-
// ApplyPersistentVolumeClaim creates a PVC in the given namespace.
521-
// If the PVC already exists, it will update the existing PVC.
522-
func (c *controller) ApplyPersistentVolumeClaim(
519+
// DeletePVCs deletes all PVCs specified by the given list options in the given namespace.
520+
func (c *controller) DeletePVCs(
523521
ctx context.Context,
524-
namespace string,
525-
pvcCfg *PersistentVolumeClaim,
526-
) error {
527-
pvcs := c.k8sCoreClient.PersistentVolumeClaims(namespace)
528-
existingPVC, err := pvcs.Get(ctx, pvcCfg.Name, metav1.GetOptions{})
529-
pvc := pvcCfg.BuildPersistentVolumeClaim()
530-
531-
// If not exists, create
532-
if err != nil {
533-
_, err := pvcs.Create(ctx, pvc, metav1.CreateOptions{})
534-
return err
535-
}
536-
// If exists, update
537-
existingPVC.Spec.Resources = pvc.Spec.Resources
538-
_, err = pvcs.Update(ctx, existingPVC, metav1.UpdateOptions{})
539-
return err
540-
}
541-
542-
// DeletePersistentVolumeClaim deletes the PVC in the given namespace.
543-
func (c *controller) DeletePersistentVolumeClaim(
544-
ctx context.Context,
545-
pvcName string,
522+
listOptions metav1.ListOptions,
546523
namespace string,
547524
ignoreNotFound bool,
548525
) error {
549-
pvcs := c.k8sCoreClient.PersistentVolumeClaims(namespace)
550-
_, err := pvcs.Get(ctx, pvcName, metav1.GetOptions{})
526+
_, err := c.k8sCoreClient.PersistentVolumeClaims(namespace).List(ctx, listOptions)
551527
if err != nil {
552528
if ignoreNotFound {
553529
return nil
554530
}
555-
return fmt.Errorf("unable to get pvc with name %s: %s", pvcName, err.Error())
531+
return err
556532
}
557-
return pvcs.Delete(ctx, pvcName, metav1.DeleteOptions{})
533+
return c.k8sCoreClient.PersistentVolumeClaims(namespace).DeleteCollection(ctx, metav1.DeleteOptions{}, listOptions)
558534
}
559535

560536
func (c *controller) ListPods(ctx context.Context, namespace string, labelSelector string) (*apicorev1.PodList, error) {
@@ -813,49 +789,45 @@ func (c *controller) getKnativePodTerminationMessage(ctx context.Context, svcNam
813789
return terminationMessage
814790
}
815791

816-
// waitDeploymentReady waits for the given k8s deployment to become ready, until the
792+
// waitStatefulSetReady waits for the given k8s stateful set to become ready, until the
817793
// default timeout
818-
func (c *controller) waitDeploymentReady(
794+
func (c *controller) waitStatefulSetReady(
819795
ctx context.Context,
820-
deploymentName string,
796+
statefulSetName string,
821797
namespace string,
822798
) error {
823799
// Init ticker to check status every second
824800
ticker := time.NewTicker(time.Second)
825801
defer ticker.Stop()
826802

827-
// Init knative ServicesGetter
828-
deployments := c.k8sAppsClient.Deployments(namespace)
803+
// Init stateful set getter
804+
statefulSets := c.k8sAppsClient.StatefulSets(namespace)
829805

830806
for {
831807
select {
832808
case <-ctx.Done():
833-
return fmt.Errorf("timeout waiting for deployment %s to be ready", deploymentName)
809+
return fmt.Errorf("timeout waiting for stateful set %s to be ready", statefulSetName)
834810
case <-ticker.C:
835-
deployment, err := deployments.Get(ctx, deploymentName, metav1.GetOptions{})
811+
statefulSet, err := statefulSets.Get(ctx, statefulSetName, metav1.GetOptions{})
836812
if err != nil {
837-
return fmt.Errorf("unable to get deployment status for %s: %v", deploymentName, err)
813+
return fmt.Errorf("unable to get stateful set status for %s: %v", statefulSetName, err)
838814
}
839815

840-
if deploymentReady(deployment) {
816+
if statefulSetReady(statefulSet) {
841817
// Service is completely ready
842818
return nil
843819
}
844820
}
845821
}
846822
}
847823

848-
func deploymentReady(deployment *apiappsv1.Deployment) bool {
849-
if deployment.Generation <= deployment.Status.ObservedGeneration {
850-
cond := deployment.Status.Conditions[0]
851-
ready := cond.Type == apiappsv1.DeploymentAvailable
852-
if deployment.Spec.Replicas != nil {
824+
func statefulSetReady(statefulSet *apiappsv1.StatefulSet) bool {
825+
if statefulSet.Generation <= statefulSet.Status.ObservedGeneration {
826+
if statefulSet.Spec.Replicas != nil {
853827
// Account for replica surge during updates
854-
ready = ready &&
855-
deployment.Status.ReadyReplicas == *deployment.Spec.Replicas &&
856-
deployment.Status.Replicas == *deployment.Spec.Replicas
828+
return statefulSet.Status.ReadyReplicas == *statefulSet.Spec.Replicas &&
829+
statefulSet.Status.Replicas == *statefulSet.Spec.Replicas
857830
}
858-
return ready
859831
}
860832
return false
861833
}
@@ -876,10 +848,10 @@ func knServiceSemanticEquals(desiredService, service *knservingv1.Service) bool
876848
equality.Semantic.DeepEqual(desiredService.ObjectMeta.Labels, service.ObjectMeta.Labels)
877849
}
878850

879-
func k8sDeploymentSemanticEquals(desiredDeployment, deployment *apiappsv1.Deployment) bool {
880-
return equality.Semantic.DeepEqual(desiredDeployment.Spec.Template, deployment.Spec.Template) &&
881-
equality.Semantic.DeepEqual(desiredDeployment.ObjectMeta.Labels, deployment.ObjectMeta.Labels) &&
882-
desiredDeployment.Spec.Replicas == deployment.Spec.Replicas
851+
func k8sStatefulSetSemanticEquals(desiredStatefulSet, statefulSet *apiappsv1.StatefulSet) bool {
852+
return equality.Semantic.DeepEqual(desiredStatefulSet.Spec.Template, statefulSet.Spec.Template) &&
853+
equality.Semantic.DeepEqual(desiredStatefulSet.ObjectMeta.Labels, statefulSet.ObjectMeta.Labels) &&
854+
desiredStatefulSet.Spec.Replicas == statefulSet.Spec.Replicas
883855
}
884856

885857
func k8sServiceSemanticEquals(desiredService, service *apicorev1.Service) bool {

0 commit comments

Comments
 (0)