From cbdd447543742d901862d1e7c018f7ee095f79cc Mon Sep 17 00:00:00 2001 From: Piotr Resztak Date: Sun, 27 Feb 2022 16:56:05 +0100 Subject: [PATCH 1/3] add 'subnet' flag --- cmd/minikube/cmd/start_flags.go | 3 +++ pkg/minikube/config/types.go | 1 + 2 files changed, 4 insertions(+) diff --git a/cmd/minikube/cmd/start_flags.go b/cmd/minikube/cmd/start_flags.go index 3d8a69ce6853..bbfeff2b955e 100644 --- a/cmd/minikube/cmd/start_flags.go +++ b/cmd/minikube/cmd/start_flags.go @@ -121,6 +121,7 @@ const ( kicBaseImage = "base-image" ports = "ports" network = "network" + subnet = "subnet" startNamespace = "namespace" trace = "trace" sshIPAddress = "ssh-ip-address" @@ -249,6 +250,7 @@ func initDriverFlags() { // docker & podman startCmd.Flags().String(listenAddress, "", "IP Address to use to expose ports (docker and podman driver only)") startCmd.Flags().StringSlice(ports, []string{}, "List of ports that should be exposed (docker and podman driver only)") + startCmd.Flags().String(subnet, "", "Subnet to be used on kic cluster. If left empty, minikube will choose subnet address, beginning from 192.168.49.0. (docker and podman driver only)") } // initNetworkingFlags inits the commandline flags for connectivity related flags for start @@ -468,6 +470,7 @@ func generateNewConfigFromFlags(cmd *cobra.Command, k8sVersion string, rtime str MinikubeISO: viper.GetString(isoURL), KicBaseImage: viper.GetString(kicBaseImage), Network: viper.GetString(network), + Subnet: viper.GetString(subnet), Memory: getMemorySize(cmd, drvName), CPUs: getCPUCount(drvName), DiskSize: getDiskSize(), diff --git a/pkg/minikube/config/types.go b/pkg/minikube/config/types.go index 513a61ded6f7..048d2434ffd2 100644 --- a/pkg/minikube/config/types.go +++ b/pkg/minikube/config/types.go @@ -82,6 +82,7 @@ type ClusterConfig struct { ExposedPorts []string // Only used by the docker and podman driver ListenAddress string // Only used by the docker and podman driver Network string // only used by docker driver + Subnet string // only used by the docker and podman driver MultiNodeRequested bool ExtraDisks int // currently only implemented for hyperkit and kvm2 CertExpiration time.Duration From f3c9198134f7054e961912c2df3f4854d7dafe6c Mon Sep 17 00:00:00 2001 From: Piotr Resztak Date: Sun, 27 Feb 2022 16:56:35 +0100 Subject: [PATCH 2/3] add support for 'subnet' flag --- pkg/drivers/kic/kic.go | 2 +- pkg/drivers/kic/oci/network_create.go | 16 ++++++++++++---- pkg/drivers/kic/types.go | 1 + pkg/minikube/registry/drvs/docker/docker.go | 1 + pkg/minikube/registry/drvs/podman/podman.go | 1 + 5 files changed, 16 insertions(+), 5 deletions(-) diff --git a/pkg/drivers/kic/kic.go b/pkg/drivers/kic/kic.go index c0f94908ba9e..89a1e726819a 100644 --- a/pkg/drivers/kic/kic.go +++ b/pkg/drivers/kic/kic.go @@ -92,7 +92,7 @@ func (d *Driver) Create() error { if networkName == "" { networkName = d.NodeConfig.ClusterName } - if gateway, err := oci.CreateNetwork(d.OCIBinary, networkName); err != nil { + if gateway, err := oci.CreateNetwork(d.OCIBinary, networkName, d.NodeConfig.Subnet); err != nil { out.WarningT("Unable to create dedicated network, this might result in cluster IP change after restart: {{.error}}", out.V{"error": err}) } else if gateway != nil { params.Network = networkName diff --git a/pkg/drivers/kic/oci/network_create.go b/pkg/drivers/kic/oci/network_create.go index b928c9a131d8..bc478b9e33e7 100644 --- a/pkg/drivers/kic/oci/network_create.go +++ b/pkg/drivers/kic/oci/network_create.go @@ -31,9 +31,9 @@ import ( "k8s.io/minikube/pkg/network" ) -// firstSubnetAddr subnet to be used on first kic cluster +// defaultFirstSubnetAddr is a first subnet to be used on first kic cluster // it is one octet more than the one used by KVM to avoid possible conflict -const firstSubnetAddr = "192.168.49.0" +const defaultFirstSubnetAddr = "192.168.49.0" // name of the default bridge network, used to lookup the MTU (see #9528) const dockerDefaultBridge = "bridge" @@ -53,8 +53,16 @@ func defaultBridgeName(ociBin string) string { } } +func firstSubnetAddr(subnet string) string { + if subnet == "" { + return defaultFirstSubnetAddr + } + + return subnet +} + // CreateNetwork creates a network returns gateway and error, minikube creates one network per cluster -func CreateNetwork(ociBin string, networkName string) (net.IP, error) { +func CreateNetwork(ociBin, networkName, subnet string) (net.IP, error) { defaultBridgeName := defaultBridgeName(ociBin) if networkName == defaultBridgeName { klog.Infof("skipping creating network since default network %s was specified", networkName) @@ -76,7 +84,7 @@ func CreateNetwork(ociBin string, networkName string) (net.IP, error) { } // retry up to 5 times to create container network - for attempts, subnetAddr := 0, firstSubnetAddr; attempts < 5; attempts++ { + for attempts, subnetAddr := 0, firstSubnetAddr(subnet); attempts < 5; attempts++ { // Rather than iterate through all of the valid subnets, give up at 20 to avoid a lengthy user delay for something that is unlikely to work. // will be like 192.168.49.0/24,..., 192.168.220.0/24 (in increment steps of 9) var subnet *network.Parameters diff --git a/pkg/drivers/kic/types.go b/pkg/drivers/kic/types.go index cabd784321d0..a9fd4c08c8d3 100644 --- a/pkg/drivers/kic/types.go +++ b/pkg/drivers/kic/types.go @@ -64,6 +64,7 @@ type Config struct { KubernetesVersion string // Kubernetes version to install ContainerRuntime string // container runtime kic is running Network string // network to run with kic + Subnet string // subnet to be used on kic cluster ExtraArgs []string // a list of any extra option to pass to oci binary during creation time, for example --expose 8080... ListenAddress string // IP Address to listen to } diff --git a/pkg/minikube/registry/drvs/docker/docker.go b/pkg/minikube/registry/drvs/docker/docker.go index cc6bb558b8e4..c9cae6cad73e 100644 --- a/pkg/minikube/registry/drvs/docker/docker.go +++ b/pkg/minikube/registry/drvs/docker/docker.go @@ -83,6 +83,7 @@ func configure(cc config.ClusterConfig, n config.Node) (interface{}, error) { ContainerRuntime: cc.KubernetesConfig.ContainerRuntime, ExtraArgs: extraArgs, Network: cc.Network, + Subnet: cc.Subnet, ListenAddress: cc.ListenAddress, }), nil } diff --git a/pkg/minikube/registry/drvs/podman/podman.go b/pkg/minikube/registry/drvs/podman/podman.go index f92220db87c9..ad3e6afc421c 100644 --- a/pkg/minikube/registry/drvs/podman/podman.go +++ b/pkg/minikube/registry/drvs/podman/podman.go @@ -96,6 +96,7 @@ func configure(cc config.ClusterConfig, n config.Node) (interface{}, error) { ContainerRuntime: cc.KubernetesConfig.ContainerRuntime, ExtraArgs: extraArgs, ListenAddress: cc.ListenAddress, + Subnet: cc.Subnet, }), nil } From eb19396baacb27bcde6912a0ea5aa6419fc16109 Mon Sep 17 00:00:00 2001 From: Piotr Resztak Date: Sun, 27 Feb 2022 16:57:04 +0100 Subject: [PATCH 3/3] add test for 'subnet' flag --- test/integration/kic_custom_network_test.go | 35 ++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/test/integration/kic_custom_network_test.go b/test/integration/kic_custom_network_test.go index b39233653274..18c92d1c9d41 100644 --- a/test/integration/kic_custom_network_test.go +++ b/test/integration/kic_custom_network_test.go @@ -75,7 +75,7 @@ func TestKicExistingNetwork(t *testing.T) { } // create custom network networkName := "existing-network" - if _, err := oci.CreateNetwork(oci.Docker, networkName); err != nil { + if _, err := oci.CreateNetwork(oci.Docker, networkName, ""); err != nil { t.Fatalf("error creating network: %v", err) } defer func() { @@ -97,6 +97,27 @@ func TestKicExistingNetwork(t *testing.T) { } } +// TestKicCustomSubnet verifies the docker/podman driver works with a custom subnet +func TestKicCustomSubnet(t *testing.T) { + if !KicDriver() { + t.Skip("only runs with docker/podman driver") + } + + profile := UniqueProfileName("custom-subnet") + ctx, cancel := context.WithTimeout(context.Background(), Minutes(5)) + defer Cleanup(t, profile, cancel) + + subnet := "192.168.60.0/24" + startArgs := []string{"start", "-p", profile, fmt.Sprintf("--subnet=%s", subnet)} + c := exec.CommandContext(ctx, Target(), startArgs...) + rr, err := Run(t, c) + if err != nil { + t.Fatalf("%v failed: %v\n%v", rr.Command(), err, rr.Output()) + } + + verifySubnet(ctx, t, profile, subnet) +} + func verifyNetworkExists(ctx context.Context, t *testing.T, networkName string) { c := exec.CommandContext(ctx, "docker", "network", "ls", "--format", "{{.Name}}") rr, err := Run(t, c) @@ -107,3 +128,15 @@ func verifyNetworkExists(ctx context.Context, t *testing.T, networkName string) t.Fatalf("%s network is not listed by [%v]: %v", networkName, c.Args, output) } } + +func verifySubnet(ctx context.Context, t *testing.T, network, subnet string) { + c := exec.CommandContext(ctx, "docker", "network", "inspect", network, "--format", "{{(index .IPAM.Config 0).Subnet}}") + rr, err := Run(t, c) + if err != nil { + t.Fatalf("%v failed: %v\n%v", rr.Command(), err, rr.Output()) + } + + if output := strings.TrimSpace(rr.Output()); !strings.Contains(output, subnet) { + t.Fatalf("%s subnet not match to %v", subnet, output) + } +}