OpenShift Multus CNI Multiple Network Interfaces
Attach multiple network interfaces to Pods using Multus CNI on OpenShift. Covers NetworkAttachmentDefinitions, SR-IOV, macvlan, IPVLAN, traffic separation
π‘ Quick Answer: Multus CNI is a meta-plugin that attaches multiple network interfaces to Kubernetes Pods. On OpenShift itβs installed by default. Define additional networks via
NetworkAttachmentDefinitionCRDs, then reference them in Pod annotations to getnet1,net2, etc. alongside the defaulteth0.
The Problem
Pods get a single network interface (eth0) by default, but GPU and HPC workloads need multiple:
- GPU fabric (InfiniBand/RDMA) for NCCL inter-node communication
- Storage network for NFS/Lustre/Ceph access
- Management network (default Pod network) for API, monitoring, SSH
- Each network must be isolated β GPU traffic must not cross storage fabric
The Solution
How Multus Works
Without Multus:
Pod β eth0 (OVN/Calico) β one network only
With Multus:
Pod β eth0 (OVN/Calico β default, always present)
β net1 (SR-IOV VF β GPU RDMA fabric)
β net2 (macvlan β storage network)
β net3 (IPVLAN β management VLAN)NetworkAttachmentDefinition (NAD) Examples
# SR-IOV RDMA network (GPU fabric)
apiVersion: k8s.cni.cncf.io/v1
kind: NetworkAttachmentDefinition
metadata:
name: gpu-rdma
namespace: ai-training
annotations:
k8s.v1.cni.cncf.io/resourceName: openshift.io/mellanoxnics
spec:
config: |
{
"cniVersion": "0.3.1",
"name": "gpu-rdma",
"type": "sriov",
"spoofchk": "off",
"trust": "on",
"rdma": true,
"ipam": {
"type": "nv-ipam",
"poolName": "gpu-fabric"
}
}
---
# macvlan for storage network
apiVersion: k8s.cni.cncf.io/v1
kind: NetworkAttachmentDefinition
metadata:
name: storage-net
namespace: ai-training
spec:
config: |
{
"cniVersion": "0.3.1",
"name": "storage-net",
"type": "macvlan",
"master": "ens3f0np0",
"mode": "bridge",
"ipam": {
"type": "whereabouts",
"range": "10.200.0.0/24",
"exclude": ["10.200.0.0/30"]
}
}
---
# IPVLAN for management VLAN
apiVersion: k8s.cni.cncf.io/v1
kind: NetworkAttachmentDefinition
metadata:
name: mgmt-vlan100
namespace: ai-training
spec:
config: |
{
"cniVersion": "0.3.1",
"name": "mgmt-vlan100",
"type": "ipvlan",
"master": "ens4f0np0.100",
"mode": "l2",
"ipam": {
"type": "host-local",
"subnet": "192.168.100.0/24",
"rangeStart": "192.168.100.100",
"rangeEnd": "192.168.100.200"
}
}Pod with Multiple Networks
apiVersion: v1
kind: Pod
metadata:
name: gpu-training
namespace: ai-training
annotations:
k8s.v1.cni.cncf.io/networks: |
[
{
"name": "gpu-rdma",
"interface": "rdma0"
},
{
"name": "storage-net",
"interface": "stor0"
}
]
spec:
containers:
- name: training
image: nvcr.io/nvidia/pytorch:24.07-py3
env:
- name: NCCL_SOCKET_IFNAME
value: "rdma0"
resources:
requests:
nvidia.com/gpu: "8"
openshift.io/mellanoxnics: "1"# Resulting interfaces inside the Pod:
# eth0 β default OVN Pod network (10.244.x.x)
# rdma0 β SR-IOV VF for GPU RDMA (10.100.x.x)
# stor0 β macvlan for storage (10.200.x.x)Simplified Annotation (Comma-Separated)
# Simple format β Multus assigns net1, net2, net3 automatically
metadata:
annotations:
k8s.v1.cni.cncf.io/networks: gpu-rdma, storage-net, mgmt-vlan100
# Results in: eth0, net1 (gpu-rdma), net2 (storage-net), net3 (mgmt-vlan100)Check Network Status
# View assigned networks and IPs
kubectl get pod gpu-training -o jsonpath='{.metadata.annotations.k8s\.v1\.cni\.cncf\.io/network-status}' | jq .
# Output:
# [
# {
# "name": "ovn-kubernetes",
# "interface": "eth0",
# "ips": ["10.244.1.15"],
# "default": true
# },
# {
# "name": "ai-training/gpu-rdma",
# "interface": "rdma0",
# "ips": ["10.100.0.17"]
# },
# {
# "name": "ai-training/storage-net",
# "interface": "stor0",
# "ips": ["10.200.0.105"]
# }
# ]OpenShift: Cluster-Wide NADs
# Available to all namespaces (OpenShift only)
apiVersion: k8s.cni.cncf.io/v1
kind: NetworkAttachmentDefinition
metadata:
name: gpu-rdma
namespace: default # cluster-scoped when in 'default' namespace
annotations:
k8s.v1.cni.cncf.io/resourceName: openshift.io/mellanoxnics
spec:
config: |
{
"cniVersion": "0.3.1",
"name": "gpu-rdma",
"type": "sriov",
"rdma": true,
"ipam": { "type": "nv-ipam", "poolName": "gpu-fabric" }
}CNI Plugin Comparison
Plugin Use Case Layer Performance IPAM
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
sriov GPU RDMA, HPC L2 Best nv-ipam/whereabouts
macvlan Storage, external LAN L2 Good whereabouts/host-local
ipvlan VLANs, L3 routing L2/L3 Good host-local
bridge VM bridging, testing L2 Moderate host-local
host-device Passthrough entire NIC L2 Best staticCommon Issues
βnetwork not foundβ in Pod events
- Cause: NAD is in different namespace than Pod
- Fix: Create NAD in same namespace, or use
defaultnamespace for cluster-wide
Pod stuck Pending β βinsufficient SR-IOV resourcesβ
- Cause: All VFs allocated; NAD has
resourceNameannotation - Fix: Check node capacity:
kubectl describe node | grep mellanoxnics
net1 has no IP address
- Cause: IPAM plugin failed or pool exhausted
- Fix: Check IPAM logs; verify pool range has free IPs
Best Practices
- Use JSON annotation format for custom interface names (
rdma0,stor0) - Separate NADs per fabric β donβt mix GPU and storage in one NAD
- SR-IOV for RDMA β only CNI type that provides hardware-level isolation
- macvlan for storage β simple, no VF overhead, good throughput
- Always check network-status annotation β verifies interfaces were created
- Namespace-scope NADs unless truly cluster-wide
Key Takeaways
- Multus attaches multiple network interfaces to Pods (eth0 + net1, net2, β¦)
- NetworkAttachmentDefinition (NAD) defines each additional network
- SR-IOV NADs need
resourceNameannotation for device plugin integration - Pod annotation
k8s.v1.cni.cncf.io/networksselects which NADs to attach - JSON annotation format allows custom interface names
network-statusannotation shows assigned IPs after Pod creation- OpenShift includes Multus by default; vanilla K8s needs manual install

Recommended
Kubernetes Recipes β The Complete Book100+ production-ready patterns with detailed explanations, best practices, and copy-paste YAML. Everything in one place.
Get the Book βLearn by Doing
CopyPasteLearn β Hands-on Cloud & DevOps CoursesMaster Kubernetes, Ansible, Terraform, and MLOps with interactive, copy-paste-run lessons. Start free.
Browse Courses βπ Deepen Your Skills β Hands-on Courses
Courses by CopyPasteLearn.com β Learn IT by Doing
