Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: Avoid system cfg changed can't restart #2253

Merged
merged 9 commits into from
Aug 26, 2024
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions pkg/controller/main-controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import (
"encoding/json"
"errors"
"fmt"
"maps"
"net/http"
"os"
"os/signal"
Expand Down Expand Up @@ -1316,6 +1317,29 @@ func (c *Controller) syncHandler(key string) (Result, error) {
// return nil so we don't re-queue this work item, this error won't get fixed by reprocessing
return WrapResult(Result{}, nil)
}

// check if the system config has changed
// if changed, minio request the systemCfg must be the same to restart.
expectSystemCfg, err := c.getSystemCfgFromStatefulSet(ctx, expectedStatefulSet)
jiuker marked this conversation as resolved.
Show resolved Hide resolved
if err != nil {
return WrapResult(Result{}, err)
}
existSystemCfg, err := c.getSystemCfgFromStatefulSet(ctx, existingStatefulSet)
jiuker marked this conversation as resolved.
Show resolved Hide resolved
if err != nil {
return WrapResult(Result{}, err)
}
if !maps.Equal(expectSystemCfg, existSystemCfg) {
harshavardhana marked this conversation as resolved.
Show resolved Hide resolved
// delete pdb to let deleted all the statefulSet pods
jiuker marked this conversation as resolved.
Show resolved Hide resolved
err = c.DeletePDB(ctx, tenant)
if err != nil {
return Result{}, err
}
// found all existing statefulSet pods and delete them
jiuker marked this conversation as resolved.
Show resolved Hide resolved
err = c.DeletePodsByStatefulSet(ctx, existingStatefulSet)
if err != nil {
return WrapResult(Result{}, err)
}
}
}

// Handle PVC expansion
Expand Down
27 changes: 27 additions & 0 deletions pkg/controller/pods.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,16 @@
package controller

import (
"context"
"fmt"
"time"

miniov2 "github.com/minio/operator/pkg/apis/minio.min.io/v2"
"github.com/minio/operator/pkg/utils"
appsv1 "k8s.io/api/apps/v1"
corev1 "k8s.io/api/core/v1"
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
"sigs.k8s.io/controller-runtime/pkg/client"
)

// handlePodChange will handle changes in pods and queue it for processing, pods are already filtered by PodInformer
Expand All @@ -43,3 +47,26 @@ func (c *Controller) handlePodChange(obj interface{}) {
key := fmt.Sprintf("%s/%s", object.GetNamespace(), instanceName)
c.healthCheckQueue.AddAfter(key, 1*time.Second)
}

// DeletePodsByStatefulSet deletes all pods associated with a statefulset
func (c *Controller) DeletePodsByStatefulSet(ctx context.Context, sts *appsv1.StatefulSet) (err error) {
ramondeklein marked this conversation as resolved.
Show resolved Hide resolved
listOpt := &client.ListOptions{
Namespace: sts.Namespace,
}
client.MatchingLabels(sts.Spec.Template.Labels).ApplyToList(listOpt)
ramondeklein marked this conversation as resolved.
Show resolved Hide resolved
podList := &corev1.PodList{}
err = c.k8sClient.List(ctx, podList, listOpt)
if err != nil {
return err
}
jiuker marked this conversation as resolved.
Show resolved Hide resolved
for _, item := range podList.Items {
err = c.k8sClient.Delete(ctx, &item)
if err != nil {
// Ignore Not Found
if client.IgnoreNotFound(err) != nil {
return err
jiuker marked this conversation as resolved.
Show resolved Hide resolved
}
}
jiuker marked this conversation as resolved.
Show resolved Hide resolved
}
return
}
33 changes: 33 additions & 0 deletions pkg/controller/pools.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (
"context"
"errors"
"fmt"
"strings"

corev1 "k8s.io/api/core/v1"

Expand Down Expand Up @@ -92,6 +93,38 @@ func poolSSMatchesSpec(expectedStatefulSet, existingStatefulSet *appsv1.Stateful
return true, nil
}

// getSystemCfgFromStatefulSet gets the MinIO environment variables from a statefulset
// set getServerSystemCfg at minio
jiuker marked this conversation as resolved.
Show resolved Hide resolved
func (c *Controller) getSystemCfgFromStatefulSet(ctx context.Context, sts *appsv1.StatefulSet) (systemCfg map[string]string, err error) {
for _, container := range sts.Spec.Template.Spec.Containers {
if container.Name == miniov2.MinIOServerName {
for _, e := range container.Env {
if strings.HasPrefix(e.Name, "MINIO_") {
switch {
case e.Value != "":
systemCfg[e.Name] = e.Value
case e.ValueFrom != nil && e.ValueFrom.SecretKeyRef != nil:
secret, err := c.kubeClientSet.CoreV1().Secrets(sts.Namespace).Get(ctx, e.ValueFrom.SecretKeyRef.Name, metav1.GetOptions{})
if err != nil {
return nil, err
}
systemCfg[e.Name] = string(secret.Data[e.ValueFrom.SecretKeyRef.Key])
jiuker marked this conversation as resolved.
Show resolved Hide resolved
case e.ValueFrom != nil && e.ValueFrom.ConfigMapKeyRef != nil:
configMap, err := c.kubeClientSet.CoreV1().ConfigMaps(sts.Namespace).Get(ctx, e.ValueFrom.ConfigMapKeyRef.Name, metav1.GetOptions{})
if err != nil {
return nil, err
}
systemCfg[e.Name] = configMap.Data[e.ValueFrom.ConfigMapKeyRef.Key]
jiuker marked this conversation as resolved.
Show resolved Hide resolved
default:
return nil, fmt.Errorf("unsupported env var %s", e.Name)
}
}
}
}
}
return
}

// restartInitializedPool restarts a pool that is assumed to have been initialized
func (c *Controller) restartInitializedPool(ctx context.Context, tenant *miniov2.Tenant, pool miniov2.Pool, tenantConfiguration map[string][]byte) error {
// get a new admin client that points to a pod of an already initialized pool (ie: pool-0)
Expand Down
Loading