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)
pull/212/head
iwilltry42 4 years ago
parent 82b2d0e241
commit 3071ec5755
No known key found for this signature in database
GPG Key ID: 7BA57AD1CFF16110
  1. 1
      cmd/create/createCluster.go
  2. 73
      pkg/cluster/cluster.go
  3. 11
      pkg/types/types.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")

@ -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,
}
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
// 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")
}
} else {
log.Infoln("Hostnetwork selected -> Skipping creation of Master LoadBalancer")
}
return nil
}

@ -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

Loading…
Cancel
Save