Skip to content

Commit

Permalink
schema: Introduce an IPv6 CIDR for the vm network
Browse files Browse the repository at this point in the history
When using the masquerade binding method, an internal IPv6 network is used
for the pod-vm communication.
This change introduces the ability to customize this network address in
scenarios where the default one cannot be used.

Signed-off-by: Edward Haas <[email protected]>
  • Loading branch information
EdDev committed Apr 13, 2021
1 parent cff7b80 commit 635265f
Show file tree
Hide file tree
Showing 8 changed files with 66 additions and 23 deletions.
4 changes: 4 additions & 0 deletions api/openapi-spec/swagger.json
Original file line number Diff line number Diff line change
Expand Up @@ -10765,6 +10765,10 @@
"description": "Represents the stock pod network interface.",
"type": "object",
"properties": {
"vmIPv6NetworkCIDR": {
"description": "IPv6 CIDR for the vm network. Defaults to fd10:0:2::/120 if not specified.",
"type": "string"
},
"vmNetworkCIDR": {
"description": "CIDR for vm network. Default 10.0.2.0/24 if not specified.",
"type": "string"
Expand Down
12 changes: 6 additions & 6 deletions pkg/virt-launcher/virtwrap/network/podinterface.go
Original file line number Diff line number Diff line change
Expand Up @@ -351,7 +351,7 @@ func getPhase2Binding(vmi *v1.VirtualMachineInstance, iface *v1.Interface, netwo
domain: domain,
podInterfaceName: podInterfaceName,
vmNetworkCIDR: network.Pod.VMNetworkCIDR,
vmIpv6NetworkCIDR: "", // TODO add ipv6 cidr to PodNetwork schema
vmIPv6NetworkCIDR: network.Pod.VMIPv6NetworkCIDR,
bridgeInterfaceName: fmt.Sprintf("k6t-%s", podInterfaceName),
storeFactory: storeFactory,
}, nil
Expand Down Expand Up @@ -704,7 +704,7 @@ type MasqueradeBindMechanism struct {
podInterfaceName string
bridgeInterfaceName string
vmNetworkCIDR string
vmIpv6NetworkCIDR string
vmIPv6NetworkCIDR string
gatewayAddr *netlink.Addr
gatewayIpv6Addr *netlink.Addr
storeFactory cache.InterfaceCacheFactory
Expand Down Expand Up @@ -771,13 +771,13 @@ func configureVifV4Addresses(b *MasqueradeBindMechanism, err error) error {
}

func configureVifV6Addresses(b *MasqueradeBindMechanism, err error) error {
if b.vmIpv6NetworkCIDR == "" {
b.vmIpv6NetworkCIDR = api.DefaultVMIpv6CIDR
if b.vmIPv6NetworkCIDR == "" {
b.vmIPv6NetworkCIDR = api.DefaultVMIpv6CIDR
}

defaultGatewayIpv6, vmIpv6, err := Handler.GetHostAndGwAddressesFromCIDR(b.vmIpv6NetworkCIDR)
defaultGatewayIpv6, vmIpv6, err := Handler.GetHostAndGwAddressesFromCIDR(b.vmIPv6NetworkCIDR)
if err != nil {
log.Log.Reason(err).Errorf("failed to get gw and vm available ipv6 addresses from CIDR %s", b.vmIpv6NetworkCIDR)
log.Log.Reason(err).Errorf("failed to get gw and vm available ipv6 addresses from CIDR %s", b.vmIPv6NetworkCIDR)
return err
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2807,6 +2807,9 @@ var CRDsValidation map[string]string = map[string]string{
pod:
description: Represents the stock pod network interface.
properties:
vmIPv6NetworkCIDR:
description: IPv6 CIDR for the vm network. Defaults to fd10:0:2::/120 if not specified.
type: string
vmNetworkCIDR:
description: CIDR for vm network. Default 10.0.2.0/24 if not specified.
type: string
Expand Down Expand Up @@ -4612,6 +4615,9 @@ var CRDsValidation map[string]string = map[string]string{
pod:
description: Represents the stock pod network interface.
properties:
vmIPv6NetworkCIDR:
description: IPv6 CIDR for the vm network. Defaults to fd10:0:2::/120 if not specified.
type: string
vmNetworkCIDR:
description: CIDR for vm network. Default 10.0.2.0/24 if not specified.
type: string
Expand Down Expand Up @@ -7191,6 +7197,9 @@ var CRDsValidation map[string]string = map[string]string{
pod:
description: Represents the stock pod network interface.
properties:
vmIPv6NetworkCIDR:
description: IPv6 CIDR for the vm network. Defaults to fd10:0:2::/120 if not specified.
type: string
vmNetworkCIDR:
description: CIDR for vm network. Default 10.0.2.0/24 if not specified.
type: string
Expand Down Expand Up @@ -9306,6 +9315,9 @@ var CRDsValidation map[string]string = map[string]string{
pod:
description: Represents the stock pod network interface.
properties:
vmIPv6NetworkCIDR:
description: IPv6 CIDR for the vm network. Defaults to fd10:0:2::/120 if not specified.
type: string
vmNetworkCIDR:
description: CIDR for vm network. Default 10.0.2.0/24 if not specified.
type: string
Expand Down
7 changes: 7 additions & 0 deletions staging/src/kubevirt.io/client-go/api/v1/openapi_generated.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions staging/src/kubevirt.io/client-go/api/v1/schema.go
Original file line number Diff line number Diff line change
Expand Up @@ -1348,6 +1348,10 @@ type PodNetwork struct {
// CIDR for vm network.
// Default 10.0.2.0/24 if not specified.
VMNetworkCIDR string `json:"vmNetworkCIDR,omitempty"`

// IPv6 CIDR for the vm network.
// Defaults to fd10:0:2::/120 if not specified.
VMIPv6NetworkCIDR string `json:"vmIPv6NetworkCIDR,omitempty"`
}

// Rng represents the random device passed from host
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

38 changes: 23 additions & 15 deletions tests/network/vmi_networking.go
Original file line number Diff line number Diff line change
Expand Up @@ -627,7 +627,7 @@ var _ = SIGDescribe("[Serial][rfe_id:694][crit:medium][vendor:[email protected]]
return vmi
}

fedoraMasqueradeVMI := func(ports []v1.Port) (*v1.VirtualMachineInstance, error) {
fedoraMasqueradeVMI := func(ports []v1.Port, ipv6NetworkCIDR string) (*v1.VirtualMachineInstance, error) {

networkData, err := libnet.NewNetworkData(
libnet.WithEthernet("eth0",
Expand All @@ -639,25 +639,32 @@ var _ = SIGDescribe("[Serial][rfe_id:694][crit:medium][vendor:[email protected]]
return nil, err
}

net := v1.DefaultPodNetwork()
net.Pod.VMIPv6NetworkCIDR = ipv6NetworkCIDR
vmi := libvmi.NewFedora(
libvmi.WithInterface(libvmi.InterfaceDeviceWithMasqueradeBinding(ports...)),
libvmi.WithNetwork(v1.DefaultPodNetwork()),
libvmi.WithNetwork(net),
libvmi.WithCloudInitNoCloudNetworkData(networkData, false),
)

return vmi, nil
}

configureIpv6 := func(vmi *v1.VirtualMachineInstance) error {
configureIpv6 := func(vmi *v1.VirtualMachineInstance, networkCIDR string) error {
if networkCIDR == "" {
networkCIDR = api.DefaultVMIpv6CIDR
}

err := console.RunCommand(vmi, "dhclient -6 eth0", 30*time.Second)
if err != nil {
return err
}
err = console.RunCommand(vmi, "ip -6 route add fd10:0:2::/120 dev eth0", 5*time.Second)
err = console.RunCommand(vmi, "ip -6 route add "+networkCIDR+" dev eth0", 5*time.Second)
if err != nil {
return err
}
err = console.RunCommand(vmi, "ip -6 route add default via fd10:0:2::1", 5*time.Second)
gateway := gatewayIPFromCIDR(networkCIDR)
err = console.RunCommand(vmi, "ip -6 route add default via "+gateway, 5*time.Second)
if err != nil {
return err
}
Expand Down Expand Up @@ -729,28 +736,28 @@ var _ = SIGDescribe("[Serial][rfe_id:694][crit:medium][vendor:[email protected]]
table.Entry("with custom CIDR [IPv4]", []v1.Port{}, "10.10.10.0/24"),
)

table.DescribeTable("IPv6", func(ports []v1.Port) {
table.DescribeTable("IPv6", func(ports []v1.Port, networkCIDR string) {
libnet.SkipWhenNotDualStackCluster(virtClient)
var serverVMI *v1.VirtualMachineInstance
var clientVMI *v1.VirtualMachineInstance

clientVMI, err = fedoraMasqueradeVMI([]v1.Port{})
clientVMI, err = fedoraMasqueradeVMI([]v1.Port{}, networkCIDR)
Expect(err).ToNot(HaveOccurred())
clientVMI, err = virtClient.VirtualMachineInstance(tests.NamespaceTestDefault).Create(clientVMI)
Expect(err).ToNot(HaveOccurred())
clientVMI = tests.WaitUntilVMIReady(clientVMI, console.LoginToFedora)

Expect(configureIpv6(clientVMI)).To(Succeed(), "failed to configure ipv6 on client vmi")
Expect(configureIpv6(clientVMI, networkCIDR)).To(Succeed(), "failed to configure ipv6 on client vmi")

serverVMI, err = fedoraMasqueradeVMI(ports)
serverVMI, err = fedoraMasqueradeVMI(ports, networkCIDR)
Expect(err).ToNot(HaveOccurred())

serverVMI.Labels = map[string]string{"expose": "server"}
serverVMI, err = virtClient.VirtualMachineInstance(tests.NamespaceTestDefault).Create(serverVMI)
Expect(err).ToNot(HaveOccurred())
serverVMI = tests.WaitUntilVMIReady(serverVMI, console.LoginToFedora)

Expect(configureIpv6(serverVMI)).To(Succeed(), "failed to configure ipv6 on server vmi")
Expect(configureIpv6(serverVMI, networkCIDR)).To(Succeed(), "failed to configure ipv6 on server vmi")

Expect(serverVMI.Status.Interfaces).To(HaveLen(1))
Expect(serverVMI.Status.Interfaces[0].IPs).NotTo(BeEmpty())
Expand All @@ -769,8 +776,9 @@ var _ = SIGDescribe("[Serial][rfe_id:694][crit:medium][vendor:[email protected]]

Expect(verifyClientServerConnectivity(clientVMI, serverVMI, tcpPort, k8sv1.IPv6Protocol)).To(Succeed())
},
table.Entry("with a specific port number [IPv6]", []v1.Port{{Name: "http", Port: 8080}}),
table.Entry("without a specific port number [IPv6]", []v1.Port{}),
table.Entry("with a specific port number [IPv6]", []v1.Port{{Name: "http", Port: 8080}}, ""),
table.Entry("without a specific port number [IPv6]", []v1.Port{}, ""),
table.Entry("with custom CIDR [IPv6]", []v1.Port{}, "fd10:10:10::/120"),
)
})

Expand Down Expand Up @@ -842,7 +850,7 @@ var _ = SIGDescribe("[Serial][rfe_id:694][crit:medium][vendor:[email protected]]
vmi = masqueradeVMI([]v1.Port{}, "")
loginMethod = console.LoginToCirros
} else {
vmi, err = fedoraMasqueradeVMI([]v1.Port{})
vmi, err = fedoraMasqueradeVMI([]v1.Port{}, "")
Expect(err).ToNot(HaveOccurred(), "Error creating fedora masquerade vmi")
loginMethod = console.LoginToFedora
}
Expand All @@ -855,7 +863,7 @@ var _ = SIGDescribe("[Serial][rfe_id:694][crit:medium][vendor:[email protected]]
Expect(err).ToNot(HaveOccurred())

if ipFamily == k8sv1.IPv6Protocol {
err = configureIpv6(vmi)
err = configureIpv6(vmi, api.DefaultVMIpv6CIDR)
Expect(err).ToNot(HaveOccurred(), "failed to configure ipv6 on vmi")
}

Expand Down Expand Up @@ -890,7 +898,7 @@ var _ = SIGDescribe("[Serial][rfe_id:694][crit:medium][vendor:[email protected]]
}, 10)).To(Succeed(), "failed to restart the vmi")
tests.WaitUntilVMIReady(vmi, loginMethod)
if ipFamily == k8sv1.IPv6Protocol {
Expect(configureIpv6(vmi)).To(Succeed(), "failed to configure ipv6 on vmi after restart")
Expect(configureIpv6(vmi, api.DefaultVMIpv6CIDR)).To(Succeed(), "failed to configure ipv6 on vmi after restart")
}
Expect(ping(podIP)).To(Succeed())
},
Expand Down

0 comments on commit 635265f

Please sign in to comment.