====== Network Instances ====== A Network Instance (NI) is a virtual network created inside an edge node for application workloads. It is the bridge between a physical port on the node and the virtual NICs of your VMs and containers. Every app interface must be connected to a network instance -- an app cannot send or receive traffic without one. Network instances are **node-scoped objects** -- they are created on a specific edge node (or cluster), not in the project at large. If you want the same network topology on five nodes, you create five sets of network instances. However, this can be fully automated w/ Terraform or by using Project level deployment policies. What does not change is a Network Instance has a 1:1 mapping with an edge node. They are created locally. ===== Network Instance Kinds ===== There are two kinds used in EVE-KVM deployments: ^ Kind ^ Value ^ Description ^ When to use ^ | **Switch** | ''NETWORK_INSTANCE_KIND_SWITCH'' | A Layer-2 bridge that connects app NICs directly to a physical port. The app is on the same L2 segment as whatever is plugged into that port. No NAT, no DHCP from EVE-OS. | WAN interfaces, firewall outside ports, apps that need direct L2 access to the physical network | | **Local** | ''NETWORK_INSTANCE_KIND_LOCAL'' | A virtual network with EVE-OS acting as router and DHCP server. Apps get IPs from a defined pool. Traffic is NAT'd through the uplink port. | LAN segments behind a firewall, management networks, any isolated app-to-app network | The fundamental difference: * **Switch NI**: EVE-OS is transparent. The app's NIC is on the physical wire. The app must handle its own IP (from upstream DHCP or static). Used for the "outside" of a firewall VM. * **Local NI**: EVE-OS owns the subnet. EVE-OS runs DHCP and NAT. Apps get IPs from the defined range. Used for the "inside" of a firewall VM or for isolated app networks. ===== DHCP Type ===== ^ type value ^ Description ^ | ''NETWORK_INSTANCE_DHCP_TYPE_UNSPECIFIED'' | No DHCP from EVE-OS. Required for Switch NI. The physical network or the app handles addressing. | | ''NETWORK_INSTANCE_DHCP_TYPE_V4'' | EVE-OS runs a DHCPv4 server for this Local NI and assigns IPs from the defined range. | | ''NETWORK_INSTANCE_DHCP_TYPE_V6'' | EVE-OS runs a DHCPv6 server. | Switch NIs always use ''DHCP_TYPE_UNSPECIFIED'' -- EVE-OS has no IP management role on a switch NI. ===== port Field ===== The ''port'' field specifies which **physical port label** on the edge node this NI is attached to: * For Switch NIs connected to a physical uplink (WAN, trunk): set ''port'' to the physical port label (e.g. ''eth0'', ''eth1'') * For Switch NIs used as internal segments between apps (no physical uplink): set ''port = ""'' -- the NI exists only inside the node * For Local NIs: set ''port'' to the uplink port the NAT'd traffic exits through (e.g. ''eth0'', or a VLAN subinterface like ''eth0.253'') Port labels (''eth0'', ''eth1'', etc.) are defined in the edge node's hardware model/adapter configuration. They match the labels assigned to physical NICs in the node's IO adapter list. ===== Terraform Examples ===== ==== WAN Switch NI (firewall outside interface) ==== A switch NI attached to ''eth0'' -- the physical WAN port. The firewall VM's outside NIC connects here and gets its WAN IP directly from the upstream provider (DHCP or static configured inside the firewall). EVE-OS is fully transparent on this path. resource "zedcloud_network_instance" "tf_stnd_wan_1" { name = "TF-STND-WAN" title = "TF-STND-WAN" kind = "NETWORK_INSTANCE_KIND_SWITCH" type = "NETWORK_INSTANCE_DHCP_TYPE_UNSPECIFIED" port = "eth0" device_id = zedcloud_edgenode.demo_en_stnd_sjc_1.id } Notes: * ''port = "eth0"'' -- this NI is bridged to the physical WAN port of the node * ''DHCP_TYPE_UNSPECIFIED'' -- EVE-OS does not participate in IP assignment * The firewall VM's ''eth0'' interface connects here and handles WAN addressing itself (typically DHCP from the ISP or a static IP configured in the firewall) * Traffic on this NI bypasses EVE-OS NAT and ACL enforcement at the bridge level -- the firewall VM owns the policy ==== Internal Switch NI (firewall inside / DMZ -- no physical port) ==== A switch NI with no physical port attachment. This is a pure internal L2 segment that exists only between VMs on the same node. Used for the LAN and DMZ ports of a firewall VM, connecting the firewall's inside interface to downstream VMs. resource "zedcloud_network_instance" "tf_stnd_ni_1" { name = "TF-STND-NI-1" title = "TF-STND-NI-1" kind = "NETWORK_INSTANCE_KIND_SWITCH" type = "NETWORK_INSTANCE_DHCP_TYPE_UNSPECIFIED" port = "" device_id = zedcloud_edgenode.demo_en_stnd_sjc_1.id } resource "zedcloud_network_instance" "tf_stnd_ni_2" { name = "TF-STND-NI-2" title = "TF-STND-NI-2" kind = "NETWORK_INSTANCE_KIND_SWITCH" type = "NETWORK_INSTANCE_DHCP_TYPE_UNSPECIFIED" port = "" device_id = zedcloud_edgenode.demo_en_stnd_sjc_1.id } Notes: * ''port = ""'' -- no physical port. This NI is an internal virtual wire between VMs. * The firewall VM's LAN interface (''eth1'') connects to ''TF-STND-NI-1''. A downstream Ubuntu VM also connects to ''TF-STND-NI-1''. The firewall routes and NATTs between NI-1 and the WAN switch NI. * A second internal segment (''TF-STND-NI-2'') acts as the DMZ -- separate L2 broadcast domain from the LAN * Each internal switch NI is its own isolated L2 domain. VMs on different switch NIs cannot talk to each other without a routing VM (the firewall) between them. ==== Local NI with EVE-OS DHCP and NAT ==== A local NI where EVE-OS acts as the router, DHCP server, and NAT gateway. Apps connected here get IPs from the defined pool and can reach external networks via NAT through the uplink port. Used when you need isolated app networks without deploying a dedicated router VM. resource "zedcloud_network_instance" "tf_cl1_lan_local_1" { name = "TF-CL1-LOCAL-LAN1" title = "TF-CL1-LOCAL-LAN1" kind = "NETWORK_INSTANCE_KIND_LOCAL" type = "NETWORK_INSTANCE_DHCP_TYPE_V4" port = "eth0" device_id = zedcloud_edgenode.demo_en_stnd_sjc_1.id ip { subnet = "10.33.0.0/24" gateway = "10.33.0.1" dns = ["1.1.1.1"] ntp = "64.246.132.14" domain = "" dhcp_range { start = "10.33.0.20" end = "10.33.0.50" } } } Notes: * ''port = "eth0"'' -- NAT'd traffic exits through this uplink port * EVE-OS creates a virtual router at ''10.33.0.1'' and runs a DHCP server assigning addresses from ''.20'' to ''.50'' * Apps connected to this NI automatically get IPs, gateway, DNS, and NTP from EVE-OS * EVE-OS performs NAT (masquerade) so app traffic appears to come from the node's ''eth0'' IP on the physical network * This NI is also where the patch envelope metadata server is reachable at ''169.254.169.254'' ==== Local NI on a VLAN Subinterface ==== A local NI built on a VLAN-tagged subinterface. Common in environments where the node's physical port carries tagged traffic and each VLAN is a separate network segment. Here ''eth0.253'' is VLAN 253 on physical port ''eth0''. resource "zedcloud_network_instance" "tf_demo_sriov_ni_local_ni_1" { name = "TF-SRIOV-DEMO-LOCAL-NI-NET" title = "TF-SRIOV-DEMO-LOCAL-NI-NET" kind = "NETWORK_INSTANCE_KIND_LOCAL" type = "NETWORK_INSTANCE_DHCP_TYPE_V4" port = "eth0.253" device_id = zedcloud_edgenode.demo_en_advantech_1.id ip { subnet = "10.1.0.0/24" gateway = "10.1.0.1" dns = ["1.1.1.1"] ntp = "64.246.132.14" domain = "" dhcp_range { start = "10.1.0.20" end = "10.1.0.50" } } } ''eth0.253'' is a VLAN subinterface -- EVE-OS tags outbound traffic on ''eth0'' with VLAN ID 253 and strips the tag on inbound. The upstream switch must have VLAN 253 configured as a trunk on the port connected to ''eth0''. ==== Switch NI on a VLAN Subinterface ==== A switch NI built on a VLAN subinterface for management access. Apps connected here get direct L2 access to the VLAN 253 segment: resource "zedcloud_network_instance" "tf_demo_sriov_ni_1" { name = "TF-ADV-NI-1" title = "TF-ADV-NI-1" kind = "NETWORK_INSTANCE_KIND_SWITCH" type = "NETWORK_INSTANCE_DHCP_TYPE_UNSPECIFIED" port = "eth0.253" device_id = zedcloud_edgenode.demo_en_advantech_1.id } ===== Typical Topology: Firewall VM + Downstream VMs ===== This is the most common EVE-KVM deployment pattern -- a firewall or virtual router VM controlling traffic between external and internal segments, with downstream VMs behind it: # WAN -- firewall outside interface, bridged to physical WAN port resource "zedcloud_network_instance" "wan" { name = "WAN-NI" kind = "NETWORK_INSTANCE_KIND_SWITCH" type = "NETWORK_INSTANCE_DHCP_TYPE_UNSPECIFIED" port = "eth0" # physical WAN uplink device_id = zedcloud_edgenode.node_1.id } # LAN -- firewall inside interface, internal segment, no physical port resource "zedcloud_network_instance" "lan" { name = "LAN-NI" kind = "NETWORK_INSTANCE_KIND_SWITCH" type = "NETWORK_INSTANCE_DHCP_TYPE_UNSPECIFIED" port = "" # internal only, no physical uplink device_id = zedcloud_edgenode.node_1.id } # DMZ -- optional second internal segment resource "zedcloud_network_instance" "dmz" { name = "DMZ-NI" kind = "NETWORK_INSTANCE_KIND_SWITCH" type = "NETWORK_INSTANCE_DHCP_TYPE_UNSPECIFIED" port = "" device_id = zedcloud_edgenode.node_1.id } Then in the app instances: * Firewall VM: ''eth0'' -> WAN-NI, ''eth1'' -> LAN-NI, ''eth2'' -> DMZ-NI * Ubuntu VM 1: ''enp1s0'' -> LAN-NI (sits behind the firewall on the LAN) * Ubuntu VM 2: ''enp1s0'' -> DMZ-NI (sits in the DMZ) The firewall VM owns all routing and security policy between segments. EVE-OS is transparent on switch NIs -- it just bridges packets. ===== ip block Reference ===== ^ Field ^ Description ^ | ''subnet'' | The network in CIDR notation (e.g. ''10.33.0.0/24'') | | ''gateway'' | EVE-OS gateway IP -- this is the IP EVE-OS assigns to the virtual router interface (e.g. ''10.33.0.1'') | | ''dns'' | List of DNS servers EVE-OS advertises to apps via DHCP | | ''ntp'' | NTP server IP advertised to apps via DHCP | | ''domain'' | DNS search domain (optional, can be empty) | | ''dhcp_range.start'' | First IP in the pool EVE-OS will assign to apps | | ''dhcp_range.end'' | Last IP in the pool | The gateway IP (''10.33.0.1'' in the examples) must be within the subnet but outside the DHCP range. EVE-OS creates a virtual interface at this IP and routes/NATs traffic through it. ===== ZCLI ===== # Switch NI on WAN port zcli network-instance create TF-STND-WAN \ --edge-node=demo-en-stnd-sjc-1 \ --kind=switch \ --ip-type=v4 \ --port=eth0 # Internal switch NI (no port) zcli network-instance create TF-STND-NI-1 \ --edge-node=demo-en-stnd-sjc-1 \ --kind=switch \ --ip-type=v4 # Local NI with DHCP zcli network-instance create TF-LOCAL-LAN \ --edge-node=demo-en-stnd-sjc-1 \ --kind=local \ --ip-type=v4 \ --port=eth0 \ --subnet=10.33.0.0/24 \ --gateway=10.33.0.1 \ --nameserver=1.1.1.1 \ --dhcp-range=10.33.0.20-10.33.0.50 # Show NIs on a node zcli network-instance show --edge-node=demo-en-stnd-sjc-1 ===== API ===== # Switch NI POST /v1/networkinstances { "name": "TF-STND-WAN", "kind": "NETWORK_INSTANCE_KIND_SWITCH", "ipType": "NETWORK_INSTANCE_DHCP_TYPE_UNSPECIFIED", "port": "eth0", "deviceId": "", "projectId": "" } # Local NI POST /v1/networkinstances { "name": "TF-LOCAL-LAN", "kind": "NETWORK_INSTANCE_KIND_LOCAL", "ipType": "NETWORK_INSTANCE_DHCP_TYPE_V4", "port": "eth0", "deviceId": "", "projectId": "", "ip": { "subnet": "10.33.0.0/24", "gateway": "10.33.0.1", "dns": ["1.1.1.1"], "dhcpRange": { "start": "10.33.0.20", "end": "10.33.0.50" } } } ===== What Happens on the Edge Node ===== ==== Switch NI ==== - EVE-OS creates a Linux bridge (e.g. ''bn1'') and adds the specified physical port (or VLAN subinterface) as a bridge member - When an app interface is connected to this NI, EVE-OS creates a TAP interface and adds it to the bridge - Packets flow: physical NIC <-> bridge <-> TAP interface <-> VM or container - EVE-OS does not assign IPs, run DHCP, or NAT on this path -- it is a transparent L2 bridge - If ''port = ""``, the bridge has no external port -- it is an internal segment only accessible to VMs on the same node that are connected to it - ACL rules defined in the app bundle still apply at the TAP interface level (via iptables/nftables on the host) ==== Local NI ==== - EVE-OS creates a Linux bridge and a virtual router interface at the gateway IP (e.g. ''10.33.0.1'') - EVE-OS starts a DHCP server process (dnsmasq) for this NI and assigns IPs from the defined range to connecting apps - NAT/masquerade rules are installed so app traffic appears to originate from the node's uplink IP on the external network - EVE-OS also serves the metadata server at ''169.254.169.254'' from this NI (used by patch envelopes and app metadata) - Each local NI has its own isolated routing table -- EVE-OS uses policy routing (''ip rule'') to route packets based on source IP, so different NIs stay isolated even if their subnets don't overlap with the main routing table ===== Common Patterns ===== ^ Pattern ^ NI Setup ^ | Single-NIC node, apps need internet | 1x Local NI on the single port. EVE-OS NATs app traffic. | | Firewall VM (3-NIC) | 1x Switch WAN (eth0), 2x Switch internal (port="") for LAN + DMZ | | Router-on-a-stick VM | 1x Switch NI with physical port -- VM handles subinterface VLANs internally | | Isolated app test network | 1x Local NI (port="") -- no external connectivity, apps can talk to each other | | SR-IOV node -- management only | 1x Local or Switch NI for the management virtual NIC. SR-IOV data NICs need no NI. | | Multi-VLAN uplink | Multiple NIs each on a different VLAN subinterface (eth0.100, eth0.200, eth0.300) | ===== Related Resources ===== * [[03a_networks|Networks (EVE Control Plane)]] * [[07_edge_apps|Edge Apps]] * [[07b_app_instances|App Instances]]