Skip to content

Commit eb30ade

Browse files
committed
add agent sidecar
Signed-off-by: yangw <[email protected]>
1 parent 243faba commit eb30ade

File tree

1 file changed

+94
-1
lines changed

1 file changed

+94
-1
lines changed

internal/k8sutils/redis-cluster.go

Lines changed: 94 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,16 @@ package k8sutils
22

33
import (
44
"context"
5+
"fmt"
56
"strconv"
67
"strings"
78

9+
common "github.com/OT-CONTAINER-KIT/redis-operator/api/common/v1beta2"
810
rcvb2 "github.com/OT-CONTAINER-KIT/redis-operator/api/rediscluster/v1beta2"
11+
"github.com/OT-CONTAINER-KIT/redis-operator/internal/image"
912
"github.com/OT-CONTAINER-KIT/redis-operator/internal/util"
1013
corev1 "k8s.io/api/core/v1"
14+
"k8s.io/apimachinery/pkg/api/resource"
1115
"k8s.io/apimachinery/pkg/util/intstr"
1216
"k8s.io/client-go/kubernetes"
1317
"k8s.io/utils/ptr"
@@ -283,6 +287,16 @@ func (service RedisClusterSTS) CreateRedisClusterSetup(ctx context.Context, cr *
283287
labels := getRedisLabels(stateFulName, cluster, service.RedisStateFulType, cr.ObjectMeta.Labels)
284288
annotations := generateStatefulSetsAnots(cr.ObjectMeta, cr.Spec.KubernetesConfig.IgnoreAnnotations)
285289
objectMetaInfo := generateObjectMetaInformation(stateFulName, cr.Namespace, labels, annotations)
290+
291+
// Prepare sidecars: combine user-defined sidecars with automatic role detector
292+
sidecars := []common.Sidecar{}
293+
if cr.Spec.Sidecars != nil {
294+
sidecars = append(sidecars, *cr.Spec.Sidecars...)
295+
}
296+
// Always add Redis agent sidecar for Redis Cluster
297+
redisAgentSidecar := generateAgentSidecar(cr)
298+
sidecars = append(sidecars, redisAgentSidecar)
299+
286300
err := CreateOrUpdateStateFul(
287301
ctx,
288302
cl,
@@ -292,7 +306,7 @@ func (service RedisClusterSTS) CreateRedisClusterSetup(ctx context.Context, cr *
292306
redisClusterAsOwner(cr),
293307
generateRedisClusterInitContainerParams(cr),
294308
generateRedisClusterContainerParams(ctx, cl, cr, service.SecurityContext, service.ReadinessProbe, service.LivenessProbe, service.RedisStateFulType, service.Resources),
295-
cr.Spec.Sidecars,
309+
&sidecars,
296310
)
297311
if err != nil {
298312
log.FromContext(ctx).Error(err, "Cannot create statefulset for Redis", "Setup.Type", service.RedisStateFulType)
@@ -390,3 +404,82 @@ func (service RedisClusterService) createOrUpdateClusterNodePortService(ctx cont
390404
}
391405
return nil
392406
}
407+
408+
// generateAgentSidecar creates a Redis agent sidecar configuration for Redis Cluster
409+
// The agent currently performs role detection and may be extended with additional functionality in the future
410+
func generateAgentSidecar(cr *rcvb2.RedisCluster) common.Sidecar {
411+
operatorImage, _ := util.CoalesceEnv("OPERATOR_IMAGE", image.GetOperatorImage())
412+
redisPort := "6379"
413+
if cr.Spec.Port != nil {
414+
redisPort = fmt.Sprintf("%d", *cr.Spec.Port)
415+
}
416+
envVars := []corev1.EnvVar{
417+
{
418+
Name: "POD_NAME",
419+
ValueFrom: &corev1.EnvVarSource{
420+
FieldRef: &corev1.ObjectFieldSelector{
421+
FieldPath: "metadata.name",
422+
},
423+
},
424+
},
425+
{
426+
Name: "POD_NAMESPACE",
427+
ValueFrom: &corev1.EnvVarSource{
428+
FieldRef: &corev1.ObjectFieldSelector{
429+
FieldPath: "metadata.namespace",
430+
},
431+
},
432+
},
433+
}
434+
435+
// Add Redis password environment variable if configured
436+
if cr.Spec.KubernetesConfig.ExistingPasswordSecret != nil {
437+
envVars = append(envVars, corev1.EnvVar{
438+
Name: "REDIS_PASSWORD",
439+
ValueFrom: &corev1.EnvVarSource{
440+
SecretKeyRef: &corev1.SecretKeySelector{
441+
LocalObjectReference: corev1.LocalObjectReference{
442+
Name: *cr.Spec.KubernetesConfig.ExistingPasswordSecret.Name,
443+
},
444+
Key: *cr.Spec.KubernetesConfig.ExistingPasswordSecret.Key,
445+
},
446+
},
447+
})
448+
}
449+
450+
// Default resource requirements for role detector
451+
resources := &corev1.ResourceRequirements{
452+
Requests: corev1.ResourceList{
453+
corev1.ResourceCPU: resource.MustParse("10m"),
454+
corev1.ResourceMemory: resource.MustParse("32Mi"),
455+
},
456+
Limits: corev1.ResourceList{
457+
corev1.ResourceCPU: resource.MustParse("50m"),
458+
corev1.ResourceMemory: resource.MustParse("64Mi"),
459+
},
460+
}
461+
462+
// Build complete command with arguments
463+
command := []string{
464+
"/operator",
465+
"agent",
466+
"server",
467+
"--redis-addr=127.0.0.1:" + redisPort,
468+
"--detect-interval=10s",
469+
}
470+
471+
if cr.Spec.KubernetesConfig.ExistingPasswordSecret != nil {
472+
command = append(command, "--redis-password=$(REDIS_PASSWORD)")
473+
}
474+
475+
return common.Sidecar{
476+
Name: "agent",
477+
Image: operatorImage,
478+
ImagePullPolicy: corev1.PullIfNotPresent,
479+
Command: command,
480+
EnvVars: &envVars,
481+
Resources: resources,
482+
// SecurityContext can be omitted - the container image already runs as non-root
483+
// and inherits pod-level security context if needed
484+
}
485+
}

0 commit comments

Comments
 (0)