No one who uses K8s will be unaware of CNI, but probably most people, most of the time, only care about the installation. Put the binary in
/opt/cni/bin, create the configuration file under
/etc/cni/net.d/, and leave the rest to K8s or containerd, we don’t care and don’t understand the implementation.
CNI, known as Container Network Interface, is a specification used to define container networks. containerernetworking/cni is a CNCF CNI implementation project, including basic bridge, macvlan and other basic network plugins.
Let’s use this as an example to understand how CNI works.
Installing the CNI Plugin
We will install the CNI plugin by downloading and compiling it ourselves.
The contents under
bin/ are the compiled CNI plugins. We can also put it under the standard
Our example configuration file is
/etc/cni/net.d/10-mynet.conf. The contents are as follows.
It is easy to see that our network is named mynet and the network type is bridge, which is both the name of the network type and the name of the network plug-in executable. ipam uses host-local here, which can also be found in the bin/ directory after we compile above.
CNI plug-in invocation rules
CNI plug-ins are invoked directly through exec, not through socket in a C/S way, all parameters are implemented through environment variables, standard input and output, specifically the invocation rules are as follows.
- Run parameters: environment variables
- Network configuration: stdin
- Normal exit: stdout
- Exception exit: stderr
The parameters passed to the CNI plugin are implemented via environment variables starting with CNI_.
CNI_COMMAND: The action to be performed, including
CNI_CONTAINERID: Unique container ID.
CNI_NETNS: Network namespace.
CNI_IFNAME: The name of the network interface created within the container.
CNI_ARGS: Additional parameters passed to the plugin itself, set in the format “FOO=BAR;ABC=123”.
CNI_PATH: The path to find the CNI plugin, in the same format as the PATH environment variable, i.e. Linux uses
:to split multiple paths, Windows uses
;to split them.
CNI defines 4 operations:
VERSION. These are passed to the plugin via the
CNI_COMMAND environment variable.
By general Linux programming convention, success returns 0, failure returns non-zero, and the error message is in the specified format, as shown in the following example.
Here we will create and delete some network interfaces manually to see how CNI works.
Adding a network interface
Create a new network namespace, here we use
ctr-1 as the name of the network namespace.
Set some common environment variables so that you don’t have to set them all over again when adding and removing network devices.
The following will allow you to add network devices to the specified namespace.
Here our network type is
bridge, so the called binary is also
bridge. From the standard output of the
bridge command, we can also see the information about the newly created interface, the IP address assigned to it by the
bridge/host-local plugin is
Let’s also verify this as follows.
Deleting a network interface
Moving on from the above, let’s continue to see how to delete the network interface you just created.
If the deletion is successful, there will be nothing in the standard output, and we can determine if it was successful from the status code returned.
Again, to verify that the interface has been successfully deleted from the specified network namespace.
Don’t forget to delete the network namespace you just created when you’re done testing.