diff --git a/cmd/kind/create/cluster/createcluster.go b/cmd/kind/create/cluster/createcluster.go index 23603b8f3c..7717c1750f 100644 --- a/cmd/kind/create/cluster/createcluster.go +++ b/cmd/kind/create/cluster/createcluster.go @@ -32,6 +32,7 @@ import ( type flagpole struct { Name string + Network string Config string ImageName string Retain bool @@ -51,6 +52,7 @@ func NewCommand() *cobra.Command { }, } cmd.Flags().StringVar(&flags.Name, "name", cluster.DefaultName, "cluster context name") + cmd.Flags().StringVar(&flags.Network, "network", "", "container network to use for cluster") cmd.Flags().StringVar(&flags.Config, "config", "", "path to a kind config file") cmd.Flags().StringVar(&flags.ImageName, "image", "", "node docker image to use for booting the cluster") cmd.Flags().BoolVar(&flags.Retain, "retain", false, "retain nodes for debugging when cluster creation fails") @@ -86,7 +88,7 @@ func runE(flags *flagpole, cmd *cobra.Command, args []string) error { } // create a cluster context and create the cluster - ctx := cluster.NewContext(flags.Name) + ctx := cluster.NewContext(flags.Name, cluster.WithNetwork(flags.Network)) if flags.ImageName != "" { // Apply image override to all the Nodes defined in Config // TODO(fabrizio pandini): this should be reconsidered when implementing diff --git a/pkg/cluster/context.go b/pkg/cluster/context.go index ecda19ab4d..6014c181f9 100644 --- a/pkg/cluster/context.go +++ b/pkg/cluster/context.go @@ -54,12 +54,16 @@ const DefaultName = "kind" // NewContext returns a new cluster management context // if name is "" the default name will be used -func NewContext(name string) *Context { +func NewContext(name string, options ...Option) *Context { if name == "" { name = DefaultName } + var c contextConfig + for _, opt := range options { + opt(&c) + } return &Context{ - ClusterMeta: meta.NewClusterMeta(name), + ClusterMeta: meta.NewClusterMeta(name, c.network), } } @@ -207,3 +211,17 @@ func (c *Context) CollectLogs(dir string) error { } return logs.Collect(nodes, dir) } + +type contextConfig struct { + network string +} + +// Option allows optional configuration of the cluster context. +type Option func(*contextConfig) + +// WithNetwork sets the container network to be used when creating a cluster. +func WithNetwork(network string) func(*contextConfig) { + return func(c *contextConfig) { + c.network = network + } +} diff --git a/pkg/cluster/internal/create/createcontext.go b/pkg/cluster/internal/create/createcontext.go index 78d8bac808..528cd1e6fe 100644 --- a/pkg/cluster/internal/create/createcontext.go +++ b/pkg/cluster/internal/create/createcontext.go @@ -126,11 +126,11 @@ func (cc *Context) ProvisionNodes() (nodeList map[string]*nodes.Node, err error) switch configNode.Role { case config.ExternalLoadBalancerRole: - node, err = nodes.CreateExternalLoadBalancerNode(name, configNode.Image, cc.ClusterLabel()) + node, err = nodes.CreateExternalLoadBalancerNode(name, configNode.Image, cc.Network(), cc.ClusterLabel()) case config.ControlPlaneRole: - node, err = nodes.CreateControlPlaneNode(name, configNode.Image, cc.ClusterLabel()) + node, err = nodes.CreateControlPlaneNode(name, configNode.Image, cc.Network(), cc.ClusterLabel()) case config.WorkerRole: - node, err = nodes.CreateWorkerNode(name, configNode.Image, cc.ClusterLabel()) + node, err = nodes.CreateWorkerNode(name, configNode.Image, cc.Network(), cc.ClusterLabel()) } if err != nil { return nodeList, err diff --git a/pkg/cluster/internal/meta/meta.go b/pkg/cluster/internal/meta/meta.go index 95a3603d6e..98ab185b39 100644 --- a/pkg/cluster/internal/meta/meta.go +++ b/pkg/cluster/internal/meta/meta.go @@ -29,13 +29,15 @@ import ( // cluster metadata // See: NewClusterMeta type ClusterMeta struct { - name string + name string + network string } // NewClusterMeta returns a new cluster meta -func NewClusterMeta(name string) *ClusterMeta { +func NewClusterMeta(name, network string) *ClusterMeta { return &ClusterMeta{ - name: name, + name: name, + network: network, } } @@ -44,6 +46,11 @@ func (c *ClusterMeta) Name() string { return c.name } +// Network returns the cluster's container network +func (c *ClusterMeta) Network() string { + return c.network +} + // KubeConfigPath returns the path to where the Kubeconfig would be placed // by kind based on the configuration. func (c *ClusterMeta) KubeConfigPath() string { diff --git a/pkg/cluster/nodes/create.go b/pkg/cluster/nodes/create.go index 068e61bad9..3ec9065e8f 100644 --- a/pkg/cluster/nodes/create.go +++ b/pkg/cluster/nodes/create.go @@ -48,18 +48,22 @@ func getPort() (int, error) { // CreateControlPlaneNode creates a contol-plane node // and gets ready for exposing the the API server -func CreateControlPlaneNode(name, image, clusterLabel string) (node *Node, err error) { +func CreateControlPlaneNode(name, image, network, clusterLabel string) (node *Node, err error) { // gets a random host port for the API server port, err := getPort() if err != nil { return nil, errors.Wrap(err, "failed to get port for API server") } - node, err = createNode(name, image, clusterLabel, config.ControlPlaneRole, + extraArgs := []string{ // publish selected port for the API server "--expose", fmt.Sprintf("%d", port), "-p", fmt.Sprintf("%d:%d", port, kubeadm.APIServerPort), - ) + } + if network != "" { + extraArgs = append(extraArgs, "--network", network) + } + node, err = createNode(name, image, clusterLabel, config.ControlPlaneRole, extraArgs...) if err != nil { return node, err } @@ -72,18 +76,22 @@ func CreateControlPlaneNode(name, image, clusterLabel string) (node *Node, err e // CreateExternalLoadBalancerNode creates an external loab balancer node // and gets ready for exposing the the API server and the load balancer admin console -func CreateExternalLoadBalancerNode(name, image, clusterLabel string) (node *Node, err error) { +func CreateExternalLoadBalancerNode(name, image, network, clusterLabel string) (node *Node, err error) { // gets a random host port for control-plane load balancer port, err := getPort() if err != nil { return nil, errors.Wrap(err, "failed to get port for control-plane load balancer") } - node, err = createNode(name, image, clusterLabel, config.ExternalLoadBalancerRole, + extraArgs := []string{ // publish selected port for the control plane "--expose", fmt.Sprintf("%d", port), "-p", fmt.Sprintf("%d:%d", port, haproxy.ControlPlanePort), - ) + } + if network != "" { + extraArgs = append(extraArgs, "--network", network) + } + node, err = createNode(name, image, clusterLabel, config.ExternalLoadBalancerRole, extraArgs...) if err != nil { return node, err } @@ -95,8 +103,12 @@ func CreateExternalLoadBalancerNode(name, image, clusterLabel string) (node *Nod } // CreateWorkerNode creates a worker node -func CreateWorkerNode(name, image, clusterLabel string) (node *Node, err error) { - node, err = createNode(name, image, clusterLabel, config.WorkerRole) +func CreateWorkerNode(name, image, network, clusterLabel string) (node *Node, err error) { + var extraArgs []string + if network != "" { + extraArgs = []string{"--network", network} + } + node, err = createNode(name, image, clusterLabel, config.WorkerRole, extraArgs...) if err != nil { return node, err }