From 3071ec5755002cd30cee6d01921581dc8d5fccfd Mon Sep 17 00:00:00 2001 From: iwilltry42 Date: Sat, 9 May 2020 13:02:02 +0200 Subject: [PATCH] createCluster: add --no-lb flag to disable the load balancer - does not create the load balancer node - exposes the API port on the first master node (master-0) --- cmd/create/createCluster.go | 1 + pkg/cluster/cluster.go | 73 +++++++++++++++++++++---------------- pkg/types/types.go | 11 +++--- 3 files changed, 49 insertions(+), 36 deletions(-) diff --git a/cmd/create/createCluster.go b/cmd/create/createCluster.go index cf1acba8..79c5c07c 100644 --- a/cmd/create/createCluster.go +++ b/cmd/create/createCluster.go @@ -122,6 +122,7 @@ func NewCmdCreateCluster() *cobra.Command { cmd.Flags().BoolVar(&createClusterOpts.WaitForMaster, "wait", false, "Wait for the master(s) to be ready before returning. Use '--timeout DURATION' to not wait forever.") cmd.Flags().DurationVar(&createClusterOpts.Timeout, "timeout", 0*time.Second, "Rollback changes if cluster couldn't be created in specified duration.") cmd.Flags().BoolVar(&updateKubeconfig, "update-kubeconfig", false, "Directly update the default kubeconfig with the new cluster's context") + cmd.Flags().BoolVar(&createClusterOpts.DisableLoadBalancer, "no-lb", false, "Disable the creation of a LoadBalancer in front of the master nodes") /* Image Importing */ cmd.Flags().BoolVar(&createClusterOpts.DisableImageVolume, "no-image-volume", false, "Disable the creation of a volume for importing images") diff --git a/pkg/cluster/cluster.go b/pkg/cluster/cluster.go index 705ce266..fca1b5da 100644 --- a/pkg/cluster/cluster.go +++ b/pkg/cluster/cluster.go @@ -169,6 +169,12 @@ func CreateCluster(ctx context.Context, cluster *k3d.Cluster, runtime k3drt.Runt if cluster.InitNode != nil { log.Infoln("Creating initializing master node") cluster.InitNode.Args = append(cluster.InitNode.Args, "--cluster-init") + + // in case the LoadBalancer was disabled, expose the API Port on the initializing master node + if cluster.CreateClusterOpts.DisableLoadBalancer { + cluster.InitNode.Ports = append(cluster.InitNode.Ports, fmt.Sprintf("%s:%s:%s/tcp", cluster.ExposeAPI.Host, cluster.ExposeAPI.Port, k3d.DefaultAPIPort)) + } + if err := nodeSetup(cluster.InitNode, masterCount); err != nil { return err } @@ -216,6 +222,9 @@ func CreateCluster(ctx context.Context, cluster *k3d.Cluster, runtime k3drt.Runt // skip the init node here if node == cluster.InitNode { continue + } else if masterCount == 0 && cluster.CreateClusterOpts.DisableLoadBalancer { + // if this is the first master node and the master loadbalancer is disabled, expose the API Port on this master node + node.Ports = append(node.Ports, fmt.Sprintf("%s:%s:%s/tcp", cluster.ExposeAPI.Host, cluster.ExposeAPI.Port, k3d.DefaultAPIPort)) } time.Sleep(1 * time.Second) // FIXME: arbitrary wait for one second to avoid race conditions of masters registering @@ -255,41 +264,43 @@ func CreateCluster(ctx context.Context, cluster *k3d.Cluster, runtime k3drt.Runt * Auxiliary Containers */ // *** MasterLoadBalancer *** - if !useHostNet { // masterlb not supported in hostnetwork mode due to port collisions with master node - // Generate a comma-separated list of master/server names to pass to the LB container - servers := "" - for _, node := range cluster.Nodes { - if node.Role == k3d.MasterRole { - log.Debugf("Node NAME: %s", node.Name) - if servers == "" { - servers = node.Name - } else { - servers = fmt.Sprintf("%s,%s", servers, node.Name) + if !cluster.CreateClusterOpts.DisableLoadBalancer { + if !useHostNet { // masterlb not supported in hostnetwork mode due to port collisions with master node + // Generate a comma-separated list of master/server names to pass to the LB container + servers := "" + for _, node := range cluster.Nodes { + if node.Role == k3d.MasterRole { + log.Debugf("Node NAME: %s", node.Name) + if servers == "" { + servers = node.Name + } else { + servers = fmt.Sprintf("%s,%s", servers, node.Name) + } } } - } - // Create LB as a modified node with loadbalancerRole - lbNode := &k3d.Node{ - Name: fmt.Sprintf("%s-%s-masterlb", k3d.DefaultObjectNamePrefix, cluster.Name), - Image: k3d.DefaultLBImage, - Ports: []string{fmt.Sprintf("%s:%s:%s/tcp", cluster.ExposeAPI.Host, cluster.ExposeAPI.Port, k3d.DefaultAPIPort)}, - Env: []string{ - fmt.Sprintf("SERVERS=%s", servers), - fmt.Sprintf("PORT=%s", k3d.DefaultAPIPort), - }, - Role: k3d.LoadBalancerRole, - Labels: k3d.DefaultObjectLabels, // TODO: createLoadBalancer: add more expressive labels - Network: cluster.Network.Name, + // Create LB as a modified node with loadbalancerRole + lbNode := &k3d.Node{ + Name: fmt.Sprintf("%s-%s-masterlb", k3d.DefaultObjectNamePrefix, cluster.Name), + Image: k3d.DefaultLBImage, + Ports: []string{fmt.Sprintf("%s:%s:%s/tcp", cluster.ExposeAPI.Host, cluster.ExposeAPI.Port, k3d.DefaultAPIPort)}, + Env: []string{ + fmt.Sprintf("SERVERS=%s", servers), + fmt.Sprintf("PORT=%s", k3d.DefaultAPIPort), + }, + Role: k3d.LoadBalancerRole, + Labels: k3d.DefaultObjectLabels, // TODO: createLoadBalancer: add more expressive labels + Network: cluster.Network.Name, + } + cluster.Nodes = append(cluster.Nodes, lbNode) // append lbNode to list of cluster nodes, so it will be considered during rollback + log.Infof("Creating LoadBalancer '%s'", lbNode.Name) + if err := CreateNode(lbNode, runtime); err != nil { + log.Errorln("Failed to create loadbalancer") + return err + } + } else { + log.Infoln("Hostnetwork selected -> Skipping creation of Master LoadBalancer") } - cluster.Nodes = append(cluster.Nodes, lbNode) // append lbNode to list of cluster nodes, so it will be considered during rollback - log.Infof("Creating LoadBalancer '%s'", lbNode.Name) - if err := CreateNode(lbNode, runtime); err != nil { - log.Errorln("Failed to create loadbalancer") - return err - } - } else { - log.Infoln("Hostnetwork selected -> Skipping creation of Master LoadBalancer") } return nil } diff --git a/pkg/types/types.go b/pkg/types/types.go index 8e2010bd..df1945f3 100644 --- a/pkg/types/types.go +++ b/pkg/types/types.go @@ -98,11 +98,12 @@ const DefaultAPIHost = "0.0.0.0" // CreateClusterOpts describe a set of options one can set when creating a cluster type CreateClusterOpts struct { - DisableImageVolume bool - WaitForMaster bool - Timeout time.Duration - K3sServerArgs []string - K3sAgentArgs []string + DisableImageVolume bool + WaitForMaster bool + Timeout time.Duration + DisableLoadBalancer bool + K3sServerArgs []string + K3sAgentArgs []string } // ClusterNetwork describes a network which a cluster is running in