SiamCafe · Blog
Multus CNI สำหรับมือใหม่ Step by Step — เพิ่ม
บทความ

Multus CNI สำหรับมือใหม่ Step by Step — เพิ่ม

เผยแพร่ 28 พฤษภาคม 2569

Multus CNI

Multus CNI Meta Plugin Kubernetes Multi-homed Pod Network Interface SR-IOV MACVLAN IPVLAN NetworkAttachmentDefinition Telco 5G NFV Storage Management Production

CNI PluginTypePerformanceIsolationIPAMUse Case
MacvlanL2ดีมากMAC-basedStatic/DHCPDirect LAN access
IPvlanL2/L3ดีมากIP-basedStaticSame MAC needed
BridgeL2ดีBridge-basedStatic/DHCPVM-like networking
SR-IOVHardwareNear bare-metalVF-basedStaticTelco high perf
Host-devicePassthroughดีมากDevice-basedStaticDedicated NIC

Installation

=== Multus CNI Installation ===

Install Multus (thick plugin)

kubectl apply -f https://raw.githubusercontent.com/k8snetworkplumbingwg/multus-cni/master/deployments/multus-daemonset-thick.yml

Verify installation

kubectl get pods -n kube-system | grep multus

kubectl get crd | grep network-attachment

Helm Installation

helm repo add rke2-charts https://rke2-charts.rancher.io

helm install multus rke2-charts/rke2-multus -n kube-system

NetworkAttachmentDefinition — Macvlan

apiVersion: k8s.cni.cncf.io/v1

kind: NetworkAttachmentDefinition

metadata:

name: storage-net

namespace: default

spec:

config: '{

"cniVersion": "0.3.1",

"type": "macvlan",

"master": "eth1",

"mode": "bridge",

"ipam": {

"type": "host-local",

"subnet": "192.168.100.0/24",

"rangeStart": "192.168.100.100",

"rangeEnd": "192.168.100.200",

"gateway": "192.168.100.1"

}

}'

NetworkAttachmentDefinition — SR-IOV

apiVersion: k8s.cni.cncf.io/v1

kind: NetworkAttachmentDefinition

metadata:

name: sriov-net

spec:

config: '{

"cniVersion": "0.3.1",

"type": "sriov",

"vlan": 100,

"ipam": {

"type": "host-local",

"subnet": "10.10.100.0/24"

}

}'

Pod with multiple networks

apiVersion: v1

kind: Pod

metadata:

name: multi-net-pod

annotations:

k8s.v1.cni.cncf.io/networks: storage-net, sriov-net

spec:

containers:

  • name: app

image: nginx

# eth0 = default CNI

# net1 = storage-net (macvlan)

# net2 = sriov-net (sriov)

from dataclasses import dataclass

@dataclass

class NetworkConfig:

name: str

cni_type: str

subnet: str

interface: str

vlan: str

purpose: str

networks = [

NetworkConfig("cluster-net", "Calico (default)", "10.244.0.0/16", "eth0", "N/A", "Pod-to-Pod default"),

NetworkConfig("storage-net", "Macvlan", "192.168.100.0/24", "net1", "100", "Ceph storage traffic"),

NetworkConfig("mgmt-net", "Macvlan", "192.168.200.0/24", "net2", "200", "SSH monitoring"),

NetworkConfig("data-net", "SR-IOV", "10.10.100.0/24", "net3", "300", "High-speed data plane"),

]

print("=== Network Configurations ===")

for n in networks:

print(f" [{n.name}] Type: {n.cni_type}")

print(f" Subnet: {n.subnet} | IF: {n.interface} | VLAN: {n.vlan}")

print(f" Purpose: {n.purpose}")

Multi-homed Pod Design

=== Multi-homed Pod Examples ===

Verify Pod networks

kubectl exec multi-net-pod -- ip addr show

kubectl exec multi-net-pod -- ip route

kubectl get pods multi-net-pod -o jsonpath='{.metadata.annotations.k8s\.v1\.cni\.cncf\.io/network-status}'

Deployment with Multus

apiVersion: apps/v1

kind: Deployment

metadata:

name: storage-app

spec:

replicas: 3

template:

metadata:

annotations:

k8s.v1.cni.cncf.io/networks: |

[

{"name": "storage-net", "interface": "net1"},

{"name": "mgmt-net", "interface": "net2", "ips": ["192.168.200.50"]}

]

spec:

containers:

  • name: app

image: my-storage-app:latest

@dataclass

class PodNetwork:

pod: str

default_ip: str

additional: str

total_interfaces: int

use_case: str

pods = [

PodNetwork("web-server", "10.244.1.10", "N/A (default only)", 1, "Standard web service"),

PodNetwork("ceph-osd", "10.244.1.20", "storage-net: 192.168.100.20", 2, "Storage + cluster"),

PodNetwork("db-replica", "10.244.1.30", "storage-net: 192.168.100.30, mgmt-net: 192.168.200.30", 3, "DB replication + mgmt"),

PodNetwork("5g-upf", "10.244.1.40", "data-net: 10.10.100.40, mgmt-net: 192.168.200.40", 3, "Telco user plane"),

]

print("\n=== Multi-homed Pods ===")

for p in pods:

print(f" [{p.pod}] Default: {p.default_ip} | Interfaces: {p.total_interfaces}")

print(f" Additional: {p.additional}")

print(f" Use Case: {p.use_case}")

Troubleshooting

# === Multus Troubleshooting ===

# Check Multus DaemonSet
# kubectl get ds -n kube-system | grep multus
# kubectl logs -n kube-system ds/kube-multus-ds

# Check NAD
# kubectl get net-attach-def
# kubectl describe net-attach-def storage-net

# Common Issues
# 1. Pod stuck in ContainerCreating
#    → Check Multus logs: kubectl logs -n kube-system -l app=multus
#    → Verify NAD config JSON is valid
#
# 2. No IP assigned on additional interface
#    → Check IPAM config: subnet range exhausted?
#    → Verify master interface exists on node
#
# 3. Cannot reach other pods on additional network
#    → Check VLAN tagging on physical switch
#    → Verify ARP/routing on macvlan bridge mode

@dataclass
class TroubleshootItem:
    issue: str
    symptom: str
    check_command: str
    fix: str

issues = [
    TroubleshootItem("Pod ContainerCreating", "Pod ค้าง ไม่ Running",
        "kubectl describe pod; kubectl logs -n kube-system multus",
        "ตรวจ NAD JSON valid, master interface exists"),
    TroubleshootItem("No IP on net1", "ip addr show net1 ไม่มี IP",
        "kubectl exec pod -- ip addr; check IPAM range",
        "เพิ่ม IP Range หรือตรวจ Subnet Config"),
    TroubleshootItem("Cannot ping across net", "Pod คุยกันไม่ได้บน net เพิ่ม",
        "kubectl exec pod -- ping 192.168.100.x",
        "ตรวจ VLAN Switch, macvlan mode, routing"),
    TroubleshootItem("NAD not found", "net-attach-def not found",
        "kubectl get net-attach-def -n NAMESPACE",
        "สร้าง NAD ใน Namespace เดียวกับ Pod"),
    TroubleshootItem("Performance low", "Throughput ต่ำกว่าที่คาด",
        "iperf3 between pods on additional net",
        "ใช้ SR-IOV แทน macvlan, ตรวจ NIC offload"),
]

print("Troubleshooting Guide:")
for t in issues:
    print(f"  [{t.issue}] {t.symptom}")
    print(f"    Check: {t.check_command}")
    print(f"    Fix: {t.fix}")

เคล็ดลับ

  • Default CNI: ติดตั้ง Default CNI ก่อน Multus เสมอ
  • Macvlan: เริ่มจาก Macvlan ง่ายที่สุดสำหรับมือใหม่
  • SR-IOV: ใช้ SR-IOV สำหรับ High Performance ต้องมี NIC รองรับ
  • VLAN: ตั้ง VLAN บน Physical Switch ให้ตรงกับ NAD Config
  • Test: ใช้ iperf3 ทดสอบ Bandwidth ระหว่าง Pod บน Additional Network

Multus CNI คืออะไร

Meta CNI Plugin Kubernetes หลาย Network Interface Pod SR-IOV MACVLAN IPVLAN Bridge NFV Telco 5G Storage Management Data Control Plane