Merge pull request #13730 from presztak/subnet_flag

Add 'subnet' flag for docker/podman driver
pull/13891/head
Sharif Elgamal 2022-03-30 16:02:54 -07:00 committed by GitHub
commit 31d1fdae3b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 54 additions and 6 deletions

View File

@ -121,6 +121,7 @@ const (
kicBaseImage = "base-image" kicBaseImage = "base-image"
ports = "ports" ports = "ports"
network = "network" network = "network"
subnet = "subnet"
startNamespace = "namespace" startNamespace = "namespace"
trace = "trace" trace = "trace"
sshIPAddress = "ssh-ip-address" sshIPAddress = "ssh-ip-address"
@ -251,6 +252,7 @@ func initDriverFlags() {
// docker & podman // docker & podman
startCmd.Flags().String(listenAddress, "", "IP Address to use to expose ports (docker and podman driver only)") 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().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 // initNetworkingFlags inits the commandline flags for connectivity related flags for start
@ -470,6 +472,7 @@ func generateNewConfigFromFlags(cmd *cobra.Command, k8sVersion string, rtime str
MinikubeISO: viper.GetString(isoURL), MinikubeISO: viper.GetString(isoURL),
KicBaseImage: viper.GetString(kicBaseImage), KicBaseImage: viper.GetString(kicBaseImage),
Network: viper.GetString(network), Network: viper.GetString(network),
Subnet: viper.GetString(subnet),
Memory: getMemorySize(cmd, drvName), Memory: getMemorySize(cmd, drvName),
CPUs: getCPUCount(drvName), CPUs: getCPUCount(drvName),
DiskSize: getDiskSize(), DiskSize: getDiskSize(),

View File

@ -92,7 +92,7 @@ func (d *Driver) Create() error {
if networkName == "" { if networkName == "" {
networkName = d.NodeConfig.ClusterName 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}) 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 { } else if gateway != nil {
params.Network = networkName params.Network = networkName

View File

@ -31,9 +31,9 @@ import (
"k8s.io/minikube/pkg/network" "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 // 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) // name of the default bridge network, used to lookup the MTU (see #9528)
const dockerDefaultBridge = "bridge" 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 // 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) defaultBridgeName := defaultBridgeName(ociBin)
if networkName == defaultBridgeName { if networkName == defaultBridgeName {
klog.Infof("skipping creating network since default network %s was specified", networkName) 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 // 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. // 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) // will be like 192.168.49.0/24,..., 192.168.220.0/24 (in increment steps of 9)
var subnet *network.Parameters var subnet *network.Parameters

View File

@ -64,6 +64,7 @@ type Config struct {
KubernetesVersion string // Kubernetes version to install KubernetesVersion string // Kubernetes version to install
ContainerRuntime string // container runtime kic is running ContainerRuntime string // container runtime kic is running
Network string // network to run with kic 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... 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 ListenAddress string // IP Address to listen to
} }

View File

@ -82,6 +82,7 @@ type ClusterConfig struct {
ExposedPorts []string // Only used by the docker and podman driver ExposedPorts []string // Only used by the docker and podman driver
ListenAddress 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 Network string // only used by docker driver
Subnet string // only used by the docker and podman driver
MultiNodeRequested bool MultiNodeRequested bool
ExtraDisks int // currently only implemented for hyperkit and kvm2 ExtraDisks int // currently only implemented for hyperkit and kvm2
CertExpiration time.Duration CertExpiration time.Duration

View File

@ -87,6 +87,7 @@ func configure(cc config.ClusterConfig, n config.Node) (interface{}, error) {
ContainerRuntime: cc.KubernetesConfig.ContainerRuntime, ContainerRuntime: cc.KubernetesConfig.ContainerRuntime,
ExtraArgs: extraArgs, ExtraArgs: extraArgs,
Network: cc.Network, Network: cc.Network,
Subnet: cc.Subnet,
ListenAddress: cc.ListenAddress, ListenAddress: cc.ListenAddress,
}), nil }), nil
} }

View File

@ -96,6 +96,7 @@ func configure(cc config.ClusterConfig, n config.Node) (interface{}, error) {
ContainerRuntime: cc.KubernetesConfig.ContainerRuntime, ContainerRuntime: cc.KubernetesConfig.ContainerRuntime,
ExtraArgs: extraArgs, ExtraArgs: extraArgs,
ListenAddress: cc.ListenAddress, ListenAddress: cc.ListenAddress,
Subnet: cc.Subnet,
}), nil }), nil
} }

View File

@ -75,7 +75,7 @@ func TestKicExistingNetwork(t *testing.T) {
} }
// create custom network // create custom network
networkName := "existing-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) t.Fatalf("error creating network: %v", err)
} }
defer func() { 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) { func verifyNetworkExists(ctx context.Context, t *testing.T, networkName string) {
c := exec.CommandContext(ctx, "docker", "network", "ls", "--format", "{{.Name}}") c := exec.CommandContext(ctx, "docker", "network", "ls", "--format", "{{.Name}}")
rr, err := Run(t, c) 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) 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)
}
}