Senior LevelDocker & Deployment
How do you build a Custom CNI Plugin adhering to CNI specifications (ADD, DEL, CHECK)?
❓ Interview Prompt: Explain CNI plugin binary specification — ADD/DEL/CHECK operations, veth pair creation, IPAM delegation, and route configuration.
A CNI Plugin is an executable binary called by the container runtime (containerd) to configure networking for a new container/pod. The CNI spec defines three operations:
CNI Operations:
1
ADD: Called when a container is created. Plugin must:
•
Create a
veth pair (virtual ethernet cable connecting pod to host).•
Assign an IP address (via IPAM plugin like
host-local or dhcp).•
Configure routes (pod can reach internet, other pods, host).
•
Return JSON result with IPs, routes, interfaces.
2
DEL: Called when a container is deleted. Plugin must:
•
Delete the veth pair.
•
Release the IP address back to IPAM pool.
•
Remove any firewall/routing rules.
3
CHECK (CNI 0.4+): Verify that the container's networking is still configured correctly. Return error if misconfigured.
Environment Variables (set by runtime, read by plugin):
•
CNI_COMMAND: ADD, DEL, or CHECK.•
CNI_CONTAINERID: Container's namespace-unique ID.•
CNI_NETNS: Path to container's network namespace (/proc/<pid>/ns/net).•
CNI_IFNAME: Interface name in container (usually eth0).Binary Location:
CNI plugins are installed to /opt/cni/bin/ on each node. Configuration is in /etc/cni/net.d/.
Code Implementation Example
bash
#!/bin/bash
# Minimal CNI plugin (bash — real plugins are Go/Rust for performance)
# /opt/cni/bin/my-simple-cni
set -e
# Read CNI config from stdin
STDIN=$(cat)
SUBNET=$(echo $STDIN | python3 -c "import sys,json; d=json.load(sys.stdin); print(d.get('subnet','10.244.0.0/24'))")
case $CNI_COMMAND in
ADD)
# Get network namespace for the container
NETNS=$CNI_NETNS
IFNAME=$CNI_IFNAME
# Create veth pair: one end in host, one in pod
ip link add "${CNI_CONTAINERID:0:15}" type veth peer name "$IFNAME" netns "$NETNS"
# Assign IP from subnet (simplified — real plugins use IPAM)
NEXT_IP="10.244.1.$(( RANDOM % 200 + 10 ))"
# Configure pod side of veth
ip netns exec "$NETNS" ip addr add "${NEXT_IP}/24" dev "$IFNAME"
ip netns exec "$NETNS" ip link set "$IFNAME" up
ip netns exec "$NETNS" ip route add default via 10.244.1.1
# Output CNI result JSON
echo "{"cniVersion":"0.4.0","ips":[{"address":"${NEXT_IP}/24","gateway":"10.244.1.1"}]}"
;;
DEL)
# Remove veth pair (deletes both ends)
ip link del "${CNI_CONTAINERID:0:15}" 2>/dev/null || true
;;
CHECK)
# Verify interface exists in container namespace
ip netns exec "$CNI_NETNS" ip link show "$CNI_IFNAME" > /dev/null
;;
esac💡Minimal bash CNI plugin: ADD creates veth pair + assigns IP + configures routes; DEL removes veth; CHECK verifies existence.
🎯 Interview Key Takeaway
CNI plugins are executables called by the runtime with CNI_COMMAND (ADD/DEL/CHECK). ADD creates veth pair, assigns IP via IPAM, configures routes. Real plugins are Go for performance and use standard IPAM libs.
#CNI#Custom Plugin#Networking#veth#IPAM#Senior
Back to all Docker & Deployment Questions→