Assigning a Virtual Machine (VM) to a VPC and Subnet typically involves integrating VM’s network interface using Multus CNI with a Kube-OVN network attachment definition (NAD). Assigning a Virtual Machine (VM) to a VPC and Subnet involves a few key steps:
If you require isolated network spaces for different tenants or environments, you’ll first define a Vpc resource. This acts as a logical router for your Subnets.
apiVersion: kubeovn.io/v1
kind: Vpc
metadata:
name: my-vpc # Name of your VPC
spec:
# Optional: You can specify which namespaces are allowed to use this VPC.
# If left empty, all namespaces can use it.
# namespaces:
# - my-namespace
# - my-namespace-1
Next, you create a Subnet resource, associating it with your Vpc (or the default ovn-cluster VPC if you’re not using a custom VPC). You also define the CIDR range and, crucially, the Namespaces that will use this Subnet.
apiVersion: kubeovn.io/v1
kind: Subnet
metadata:
name: my-vm-subnet # Name of your Subnet
spec:
# Associate this subnet with your VPC. If omitted, it defaults to 'ovn-cluster'.
vpc: my-vpc
cidrBlock: 10.10.0.0/24 # The IP range for this subnet
gateway: 10.10.0.1 # The gateway IP for this subnet (Kube-OVN often sets this automatically)
namespaces:
- vm-namespace # The Namespace where your VMs will reside
Ensure the Namespace you defined in your Subnet exists.
apiVersion: v1
kind: Namespace
metadata:
name: vm-namespace
While Kube-OVN can work directly by binding a Namespace to a Subnet, using a NetworkAttachmentDefinition (NAD) with Multus provides more explicit control, especially if your VM needs multiple network interfaces or a specific CNI configuration.
apiVersion: k8s.cni.cncf.io/v1
kind: NetworkAttachmentDefinition
metadata:
name: vm-network # Name of the NAD
namespace: vm-namespace # Must be in the same namespace as the VMs using it
spec:
config: |
{
"cniVersion": "0.3.1",
"name": "vm-network",
"type": "kube-ovn",
"server_socker": "/run/openvswitch/kube-ovn-daemon.sock",
"netAttachDefName": "vm-namespace/vm-network"
}
Note: For a VM to automatically pick up the correct Subnet via the Namespace binding, you often don’t strictly
need a NetworkAttachmentDefinition for the primary interface if the Namespace is directly linked to the Subnet. However,
it’s crucial for secondary interfaces or explicit network definitions.
When defining your VirtualMachine (or VirtualMachinePool), you ensure it’s created in the vm-namespace that is
bound to your my-vm-subnet.
If your vm-namespace is explicitly listed in the spec.namespaces of my-vm-subnet, any VM (or Pod) created in
vm-namespace will automatically get an IP from my-vm-subnet.
If you’re using a NetworkAttachmentDefinition (NAD) or need to explicitly control which subnet is used, especially
for secondary interfaces, you’d use Multus annotations on your VM definition.
apiVersion: kubevirt.io/v1
kind: VirtualMachine
metadata:
name: my-kubeovn-vm-multus
namespace: vm-namespace
annotations:
# Reference the NetworkAttachmentDefinition for the primary interface
# The format is <namespace>/<nad-name>
k8s.v1.cni.cncf.io/networks: vm-network
# Optional: For static IP assignment from the subnet
# ovn.kubernetes.io/ip_address: 10.10.0.10
spec:
runStrategy: Always
template:
spec:
domain:
devices:
disks:
- name: containerdisk
disk:
bus: virtio
- name: cloudinitdisk
disk:
bus: virtio
interfaces:
- name: primary-nic
# This interface will use the network defined by the NAD
bridge: {} # Or masquerade: {}
# Example for a secondary NIC on a different Kube-OVN Subnet/NAD
# - name: secondary-nic
# bridge: {}
resources:
requests:
memory: 2Gi
volumes:
- name: containerdisk
containerDisk:
image: kubevirt/fedora-cloud-container-disk-demo
- name: cloudinitdisk
cloudInitNoCloud:
userData: |
#cloud-config
Important Kube-OVN Annotations for VMs/Pods:
ovn.kubernetes.io/logical_switch: Explicitly assigns the workload to a specific Kube-OVN logical switch (which
corresponds to a Subnet). This overrides the Namespace’s default subnet.
ovn.kubernetes.io/ip_address: Assigns a specific static IP address from the subnet. Make sure this IP is excluded from
the subnet’s dynamic IP range (excludeIps in the Subnet definition) to avoid conflicts.
ovn.kubernetes.io/network_attachment: When using Multus, this annotation on the NetworkAttachmentDefinition’s config
can specify the Kube-OVN provider or other details if you have multiple Kube-OVN deployments or specific requirements.