Create cni plugin from scratch with go part 1

CNI or Container Network Interface is one of componect requerment to running kubernetes cluster,CNI is responsibility to connected kubernetes cluster ie: connection between pods,connection between pods with diffrent node.

Usualy if you using public cloud the CNI already configurated (not very sure,i’m never use public cloud #cmiiw)


I’m pretty sure if you was using one of those CNI

But in this time i’m will not talk/compare/benchmark about those CNI (compare/benchmark without knowing the basic of technology was dumb and waste your time), yep just like usually i will talk how to create it from scratch.

Before we jump to the code better if we know what is standar of kubernetes network model

As you can see kubernetes network model need two requerments

  • pod can communicate with another pods whitout NAT
  • agents can communicate with pods

Ok for now let’s take this as note


Before you continue to read this post better if you see my kubernetes topology

Create CNI plugin config

first we need to config file for CNI plugin

nano /etc/cni/net.d/10-humanz-cni-plugin.conf
    "cniVersion": "0.3.1",
    "name": "humanz-cni",
    "type": "humanz-cni",
    "bridge": "humanz-cni0",
    "subnet": "100.100.X.0/24"

the cni plugin config file was formated in json and in that file was filled with cni config,like the name of cni,version,bridge,network and subnet (make sure the subnet was same with –pod-network-cidr when you deploye kubernetes)

populate that plugin on all kubernetes cluster but with different subnet


Create cni plugin

clone my repo and build it,after that copy the binary file to /opt/cni/bin/humanz-cni in all kube cluster

go build -o /opt/cni/bin/humanz-cni .

after that tail the log

tail -f /var/log/humanz_cni.log

meanwhile tail the log let create a pods


As you can see the pod was created, now let’s try to ping it

root@ubuntu-nested-1:~/ingress# ping -c 3
PING ( 56(84) bytes of data.

--- ping statistics ---
3 packets transmitted, 0 received, 100% packet loss, time 2032ms

root@ubuntu-nested-1:~/ingress# curl

huh it’s fail,why?

the ping was from ubuntu-nested-1 and the pod was hosted on ubuntu-nested-3,let’s check the ip route

root@ubuntu-nested-1:~# ip route
default via dev enp1s0 proto dhcp src metric 100 dev humanz-cni0 proto kernel scope link src dev docker0 proto kernel scope link src linkdown dev enp1s0 proto kernel scope link src dev enp1s0 proto dhcp scope link src metric 100 dev virbr0 proto kernel scope link src linkdown dev enp8s0 proto kernel scope link src 

As you can see,there is no route table to which is subnet of ubuntu-nested-3.

Now let’s add the route table

root@ubuntu-nested-1:~# ip route add via dev enp8s0
root@ubuntu-nested-3:# ip route add via dev enp3s0

let’s try to ping&curl again

root@ubuntu-nested-1:~# ping -c 3
PING ( 56(84) bytes of data.
64 bytes from icmp_seq=1 ttl=63 time=0.290 ms
64 bytes from icmp_seq=2 ttl=63 time=0.365 ms
64 bytes from icmp_seq=3 ttl=63 time=0.084 ms

--- ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2050ms
rtt min/avg/max/mdev = 0.084/0.246/0.365/0.119 ms
root@ubuntu-nested-1:~# curl

And yes,it’s working fine