Getting Started
Verified against
v1.3.0plus the documented main commit7c27007. Commands assume Linux with Go installed and root for namespace operations.
Prerequisites
- Linux, since CNI configures Linux network namespaces.
- Go 1.21 or newer (
go.mod:3). - Root or
CAP_NET_ADMIN, because creating interfaces and namespaces is privileged.
CNI is a spec, not a prebuilt binary bundle. A minimal working setup needs three things: a driver (cnitool here, or a real runtime), one or more plugin binaries, and a conflist describing the chain.
Install
go install github.com/containernetworking/cni/cnitool@latestcnitool exposes the subcommands add, check, del, gc, and status (cnitool/main.go, cnitool/cmd/*.go). You also need real plugin binaries from the reference repository:
git clone https://github.com/containernetworking/plugins
cd plugins
./build_linux.shThe built binaries land in ./bin. Point CNI_PATH at that directory.
A first working setup
Build a bridge plus host-local IPAM chain and attach a fresh network namespace to it.
Write a conflist. A conflist is JSON, written to
/etc/cni/net.d/10-mynet.conflist. Thenamefield is required;validateConfigrejects an empty name (pkg/skel/skel.go:216-229).json{ "name": "mynet", "cniVersion": "1.0.0", "plugins": [ { "type": "bridge", "bridge": "cni0", "isGateway": true, "ipMasq": true, "ipam": { "type": "host-local", "subnet": "10.22.0.0/16", "routes": [ { "dst": "0.0.0.0/0" } ] } } ] }Create a network namespace for the test.
bashsudo ip netns add testingRun the ADD.
cnitoolreads the conflist namedmynetfrom/etc/cni/net.dand executes the chain against the namespace.bashsudo CNI_PATH=./bin NETCONFPATH=/etc/cni/net.d \ cnitool add mynet /var/run/netns/testing
The command prints the result JSON, including the assigned interface and IP from the 10.22.0.0/16 range.
Verify it works
Check the attachment with the same tool, or inspect the namespace directly.
sudo CNI_PATH=./bin NETCONFPATH=/etc/cni/net.d \
cnitool check mynet /var/run/netns/testing
sudo ip netns exec testing ip addrYou should see an eth0 inside the namespace with an address in the configured subnet. The library also writes the cached result to /var/lib/cni/results/, which DEL and GC later reuse (libcni/api.go:252-257).
Where to go next
Read the spec for the full command and result contract (SPEC.md) and the tool guide for more examples (cnitool docs). For production networking, choose a real data plane such as Calico or Cilium rather than the reference plugins, and let your runtime (kubelet, containerd, CRI-O) drive CNI instead of cnitool.