QA
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→

More Docker & Deployment Interview Questions

Beginner LevelDocker & Deployment

How do Docker Multi-Stage Builds minimize image size and improve security?

Beginner LevelDocker & Deployment

What is the difference between a Docker Container and a Virtual Machine (VM)?

Beginner LevelDocker & Deployment

What is the difference between a Docker Image and a Docker Container?