From 26a0bb65837f728ad2ca39efc55501bf059d7dfe Mon Sep 17 00:00:00 2001 From: Enrico Candino Date: Mon, 24 Feb 2025 12:08:58 +0100 Subject: [PATCH] Added ServiceCIDR lookup, and changed default (#263) * added serviceCIDR lookup * fix log * fix comment * swap serviceCIDR lookup --- pkg/controller/cluster/agent/agent.go | 2 +- pkg/controller/cluster/cluster.go | 93 ++++++++++++++++++++++++++- 2 files changed, 91 insertions(+), 4 deletions(-) diff --git a/pkg/controller/cluster/agent/agent.go b/pkg/controller/cluster/agent/agent.go index e1a511d7..142cbaad 100644 --- a/pkg/controller/cluster/agent/agent.go +++ b/pkg/controller/cluster/agent/agent.go @@ -48,7 +48,7 @@ func ensureObject(ctx context.Context, cfg *Config, obj ctrlruntimeclient.Object if result != controllerutil.OperationResultNone { key := client.ObjectKeyFromObject(obj) - log.Info(fmt.Sprintf("ensuring %T", obj), "key", key, "result, result") + log.Info(fmt.Sprintf("ensuring %T", obj), "key", key, "result", result) } return err diff --git a/pkg/controller/cluster/cluster.go b/pkg/controller/cluster/cluster.go index 582d706a..a17a64b2 100644 --- a/pkg/controller/cluster/cluster.go +++ b/pkg/controller/cluster/cluster.go @@ -4,6 +4,7 @@ import ( "context" "errors" "fmt" + "net" "reflect" "strings" "time" @@ -39,8 +40,8 @@ const ( maxConcurrentReconciles = 1 - defaultClusterCIDR = "10.44.0.0/16" - defaultClusterServiceCIDR = "10.45.0.0/16" + defaultClusterCIDR = "10.42.0.0/16" + defaultClusterServiceCIDR = "10.43.0.0/16" defaultStoragePersistentSize = "1G" memberRemovalTimeout = time.Minute * 1 ) @@ -175,7 +176,19 @@ func (c *ClusterReconciler) reconcileCluster(ctx context.Context, cluster *v1alp cluster.Status.ServiceCIDR = cluster.Spec.ServiceCIDR if cluster.Status.ServiceCIDR == "" { - cluster.Status.ServiceCIDR = defaultClusterServiceCIDR + log.Info("serviceCIDR not set") + + serviceCIDR, err := c.lookupServiceCIDR(ctx) + if err != nil { + log.Error(err, "error while looking up Cluster ServiceCIDR") + } + + // update Status ServiceCIDR + if serviceCIDR == "" { + log.Info("setting default ServiceCIDR") + serviceCIDR = defaultClusterServiceCIDR + } + cluster.Status.ServiceCIDR = serviceCIDR } service, err := c.ensureClusterService(ctx, cluster) @@ -413,3 +426,77 @@ func (c *ClusterReconciler) validate(cluster *v1alpha1.Cluster) error { } return nil } + +// lookupServiceCIDR attempts to determine the cluster's service CIDR. +// It first attempts to create a failing Service (with an invalid cluster IP)and extracts the expected CIDR from the resulting error. +// If that fails, it searches the 'kube-apiserver' Pod's arguments for the --service-cluster-ip-range flag. +func (c *ClusterReconciler) lookupServiceCIDR(ctx context.Context) (string, error) { + log := ctrl.LoggerFrom(ctx) + + // Try to look for the serviceCIDR creating a failing service. + // The error should contain the expected serviceCIDR + + log.Info("looking up serviceCIDR from a failing service creation") + + failingSvc := v1.Service{ + ObjectMeta: metav1.ObjectMeta{Name: "fail", Namespace: "default"}, + Spec: v1.ServiceSpec{ClusterIP: "1.1.1.1"}, + } + + if err := c.Client.Create(ctx, &failingSvc); err != nil { + splittedErrMsg := strings.Split(err.Error(), "The range of valid IPs is ") + + if len(splittedErrMsg) > 1 { + serviceCIDR := strings.TrimSpace(splittedErrMsg[1]) + log.Info("found serviceCIDR from failing service creation: " + serviceCIDR) + + // validate serviceCIDR + _, serviceCIDRAddr, err := net.ParseCIDR(serviceCIDR) + if err != nil { + return "", err + } + return serviceCIDRAddr.String(), nil + } + } + + // Try to look for the the kube-apiserver Pod, and look for the '--service-cluster-ip-range' flag. + + log.Info("looking up serviceCIDR from kube-apiserver pod") + + matchingLabels := ctrlruntimeclient.MatchingLabels(map[string]string{ + "component": "kube-apiserver", + "tier": "control-plane", + }) + listOpts := &ctrlruntimeclient.ListOptions{Namespace: "kube-system"} + matchingLabels.ApplyToList(listOpts) + + var podList v1.PodList + if err := c.Client.List(ctx, &podList, listOpts); err != nil { + if !apierrors.IsNotFound(err) { + return "", err + } + } + + if len(podList.Items) > 0 { + apiServerPod := podList.Items[0] + apiServerArgs := apiServerPod.Spec.Containers[0].Args + + for _, arg := range apiServerArgs { + if strings.HasPrefix(arg, "--service-cluster-ip-range=") { + serviceCIDR := strings.TrimPrefix(arg, "--service-cluster-ip-range=") + log.Info("found serviceCIDR from kube-apiserver pod: " + serviceCIDR) + + // validate serviceCIDR + _, serviceCIDRAddr, err := net.ParseCIDR(serviceCIDR) + if err != nil { + log.Error(err, "serviceCIDR is not valid") + break + } + return serviceCIDRAddr.String(), nil + } + } + } + + log.Info("cannot find serviceCIDR from lookup") + return "", nil +}