Multus est un meta-plugin CNI : il ne crée pas lui-même de réseau, mais orchestre plusieurs plugins CNI pour attacher plusieurs interfaces réseau à un même pod. Il délègue l'interface réseau principale à un CNI primaire (Flannel, Calico, Cilium...) et peut attacher autant d'interfaces secondaires que nécessaire via des NetworkAttachmentDefinition.
Développé par Intel et maintenu par le Kubernetes Network Plumbing Working Group (k8snetworkplumbingwg), Multus est la solution de référence pour les workloads nécessitant plusieurs réseaux par pod : telco (5G, NFV), HPC, applications nécessitant isolation entre trafic applicatif et trafic de stockage/management.
Idéal pour : workloads télécoms (CNF, 5G), OpenShift/OKD (Multus est inclus par défaut), applications nécessitant séparation réseau applicatif/stockage/management, SR-IOV avec accès direct au matériel.
Informations essentielles
Origine : Intel / k8snetworkplumbingwg · Licence : Apache 2.0 · Architectures : x86_64, ARM64
Liens : GitHub · Documentation · Releases
Support : Maintenu activement par Intel et le Network Plumbing WG. Inclus par défaut dans OpenShift/OKD.
Fonctionnement
| Interface | Géré par | Configuré via |
|---|---|---|
eth0 (primaire) | CNI principal (Flannel, Calico, Cilium...) | Configuration CNI standard |
net1, net2... (secondaires) | Plugin CNI choisi (macvlan, ipvlan, SR-IOV...) | NetworkAttachmentDefinition CRD |
Prérequis
- Un CNI principal déjà installé et fonctionnel (Flannel, Calico, Cilium...)
- Multus n'est qu'un orchestrateur, il délègue à des CNI existants
Installation
Via manifeste officiel
# Installer Multus (thick plugin - inclut le daemon Multus)
kubectl apply -f https://raw.githubusercontent.com/k8snetworkplumbingwg/multus-cni/master/deployments/multus-daemonset-thick.yml
# Vérifier
kubectl -n kube-system get pods -l app=multus -o wide
# Tous les nœuds doivent avoir un pod multus Running
Définir un réseau secondaire (NetworkAttachmentDefinition)
Le CRD NetworkAttachmentDefinition (NAD) décrit un réseau secondaire et le plugin CNI à utiliser pour le créer.
macvlan (réseau L2 sur l'interface hôte)
# nad-macvlan.yaml
apiVersion: k8s.cni.cncf.io/v1
kind: NetworkAttachmentDefinition
metadata:
name: macvlan-conf
namespace: default
spec:
config: |
{
"cniVersion": "0.3.1",
"name": "macvlan-conf",
"type": "macvlan",
"master": "eth0",
"mode": "bridge",
"ipam": {
"type": "host-local",
"subnet": "192.168.10.0/24",
"rangeStart": "192.168.10.200",
"rangeEnd": "192.168.10.220",
"gateway": "192.168.10.1"
}
}
kubectl apply -f nad-macvlan.yaml
kubectl get network-attachment-definitions
ipvlan (L3, partagé avec l'hôte)
apiVersion: k8s.cni.cncf.io/v1
kind: NetworkAttachmentDefinition
metadata:
name: ipvlan-conf
spec:
config: |
{
"cniVersion": "0.3.1",
"type": "ipvlan",
"master": "eth1",
"mode": "l3",
"ipam": {
"type": "host-local",
"subnet": "10.10.0.0/24"
}
}
Utiliser les réseaux secondaires dans un pod
L'annotation k8s.v1.cni.cncf.io/networks sélectionne les réseaux secondaires à attacher.
apiVersion: v1
kind: Pod
metadata:
name: mon-pod-multi-net
annotations:
# Un seul réseau secondaire
k8s.v1.cni.cncf.io/networks: macvlan-conf
# Ou plusieurs réseaux secondaires
# k8s.v1.cni.cncf.io/networks: macvlan-conf, ipvlan-conf
spec:
containers:
- name: app
image: alpine
command: ["sleep", "3600"]
kubectl apply -f mon-pod.yaml
# Vérifier les interfaces réseau dans le pod
kubectl exec mon-pod-multi-net -- ip addr
# eth0 = réseau primaire (Flannel/Calico/...)
# net1 = interface macvlan secondaire
# Annotations sur le pod montrent l'état de chaque interface
kubectl get pod mon-pod-multi-net -o jsonpath='{.metadata.annotations}'
Avec SR-IOV
SR-IOV CNI s'utilise en complément de Multus pour les Virtual Functions matérielles.
# NAD pour SR-IOV
apiVersion: k8s.cni.cncf.io/v1
kind: NetworkAttachmentDefinition
metadata:
name: sriov-net
annotations:
k8s.v1.cni.cncf.io/resourceName: intel.com/intel_sriov_netdevice
spec:
config: |
{
"cniVersion": "0.3.1",
"name": "sriov-net",
"type": "sriov",
"ipam": {
"type": "host-local",
"subnet": "10.56.217.0/24"
}
}
# Pod utilisant SR-IOV via Multus
metadata:
annotations:
k8s.v1.cni.cncf.io/networks: sriov-net
spec:
containers:
- name: app
resources:
limits:
intel.com/intel_sriov_netdevice: "1"
Mise à jour
# Mettre à jour le DaemonSet
kubectl apply -f https://raw.githubusercontent.com/k8snetworkplumbingwg/multus-cni/master/deployments/multus-daemonset-thick.yml
# Vérifier la version
kubectl -n kube-system get ds multus -o jsonpath='{.spec.template.spec.containers[0].image}'
Troubleshooting
Pod en état ContainerCreating avec Multus
# Décrire le pod pour voir l'erreur CNI
kubectl describe pod <nom>
# Logs du daemon Multus
kubectl -n kube-system logs ds/kube-multus-ds | tail -50
# Vérifier que la NetworkAttachmentDefinition existe
kubectl get network-attachment-definitions -A
# Vérifier que le plugin CNI secondaire est bien installé sur les nœuds
ls /opt/cni/bin/
Interface secondaire absente dans le pod
# Vérifier les annotations de statut sur le pod
kubectl get pod <nom> -o jsonpath='{.metadata.annotations.k8s\.v1\.cni\.cncf\.io/network-status}'
# Doit lister toutes les interfaces attachées
Commandes utiles
# NetworkAttachmentDefinitions
kubectl get network-attachment-definitions -A
kubectl describe network-attachment-definitions <nom>
# État des pods Multus
kubectl -n kube-system get pods -l app=multus
# Logs
kubectl -n kube-system logs ds/kube-multus-ds
# Interfaces dans un pod
kubectl exec <pod> -- ip addr
kubectl get pod <pod> -o jsonpath='{.metadata.annotations.k8s\.v1\.cni\.cncf\.io/network-status}'
Ressources
- GitHub : https://github.com/k8snetworkplumbingwg/multus-cni
- Quickstart : https://github.com/k8snetworkplumbingwg/multus-cni/blob/master/docs/quickstart.md
- NetworkAttachmentDefinition spec : https://github.com/k8snetworkplumbingwg/network-attachment-definition-client
- SR-IOV CNI : https://github.com/k8snetworkplumbingwg/sriov-cni