<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Networking on Nick&#39;s Tech Blog</title>
    <link>https://www.nicktriller.com/tags/networking/</link>
    <description>Recent content in Networking on Nick&#39;s Tech Blog</description>
    
    <language>en</language>
    <lastBuildDate>Mon, 01 Aug 2022 00:00:00 +0000</lastBuildDate>
    
        <atom:link href="https://www.nicktriller.com/tags/networking/index.xml" rel="self" type="application/rss+xml" />
    
    
    <item>
      <title>Talk on CNI at CNCF Amsterdam</title>
      <link>https://www.nicktriller.com/blog/meetup-talk-cni-from-the-ground-up/</link>
      <pubDate>Mon, 01 Aug 2022 00:00:00 +0000</pubDate>
      
      <guid>https://www.nicktriller.com/blog/meetup-talk-cni-from-the-ground-up/</guid>
      
        <description>&lt;p&gt;On June 22nd, I gave my first meetup talk at the
&lt;a href=&#34;https://www.meetup.com/dutch-cloud-native/&#34;&gt;Dutch Kubernetes &amp;amp; Cloud Native meetup&lt;/a&gt; in Amsterdam:
&amp;ldquo;CNI from the ground up&amp;rdquo;.&lt;/p&gt;

&lt;link rel=&#34;stylesheet&#34; href=&#34;https://www.nicktriller.com/css/hugo-easy-gallery.css&#34; /&gt;
&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;https://www.nicktriller.com/images/2022/cncf_amsterdam.jpg&#34; /&gt;
    &lt;/div&gt;
    &lt;a href=&#34;https://www.nicktriller.com/images/2022/cncf_amsterdam.jpg&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;h2 id=&#34;why-cni&#34;&gt;Why CNI?&lt;/h2&gt;
&lt;p&gt;Pod networking is something everyone depends on and almost nobody looks at.
You install Calico or Cilium, pods get IP addresses, and they can reach each other.
It works, so there is no reason to ask how.&lt;/p&gt;
&lt;p&gt;That was true for me as well until I read the
&lt;a href=&#34;https://github.com/containernetworking/cni/blob/main/SPEC.md&#34;&gt;CNI specification&lt;/a&gt; and realized how small it is.
There is no daemon, no API server and no gRPC service.
A CNI plugin is an executable that the container runtime invokes once per container.
The network configuration arrives on stdin, the parameters arrive as environment variables, and the plugin
prints a JSON result to stdout.
That is the entire interface.&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:100%&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;https://www.nicktriller.com/images/2022/cni_talk.png&#34; alt=&#34;How the runtime invokes the plugin: config on stdin, parameters as environment variables, result on stdout&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;https://www.nicktriller.com/images/2022/cni_talk.png&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;How the runtime invokes the plugin: config on stdin, parameters as environment variables, result on stdout&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;This makes for a good talk topic: a piece of infrastructure that looks like magic from the outside
and turns out to be approachable once you look inside.&lt;/p&gt;
&lt;h2 id=&#34;toycni&#34;&gt;toycni&lt;/h2&gt;
&lt;p&gt;Instead of walking through someone else&amp;rsquo;s implementation, I wrote my own:
&lt;a href=&#34;https://github.com/Nick-Triller/toycni&#34;&gt;toycni&lt;/a&gt;, a CNI plugin in about 250 lines of Go.&lt;/p&gt;
&lt;p&gt;For the &lt;code&gt;ADD&lt;/code&gt; command, it&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;creates a Linux bridge on the node if it doesn&amp;rsquo;t exist yet and assigns the first IP of the node&amp;rsquo;s pod subnet to it,&lt;/li&gt;
&lt;li&gt;delegates IP allocation to the &lt;code&gt;host-local&lt;/code&gt; IPAM plugin, which is just another binary to execute,&lt;/li&gt;
&lt;li&gt;creates a veth pair, moves one end into the container&amp;rsquo;s network namespace and attaches the other end to the bridge,&lt;/li&gt;
&lt;li&gt;assigns the allocated IP to the container interface and sets the bridge as the default gateway,&lt;/li&gt;
&lt;li&gt;prints the result as JSON.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;code&gt;DEL&lt;/code&gt; releases the IP and relies on the runtime deleting the network namespace, which removes the veth pair with it.&lt;/p&gt;
&lt;p&gt;The implementation shells out to &lt;code&gt;ip&lt;/code&gt; instead of using netlink.
That is not how a production plugin should be written, but it means every step maps to a command the
audience can run themselves afterwards.&lt;/p&gt;
&lt;p&gt;The demo ran on a two node kubeadm cluster in &lt;a href=&#34;https://github.com/canonical/multipass&#34;&gt;multipass&lt;/a&gt; VMs.
Each node got its own pod subnet, a static route to the other node&amp;rsquo;s subnet and an iptables masquerade rule
for traffic leaving the cluster.
Those last two pieces are where real CNI plugins spend most of their complexity.
toycni gets away with static routes only because the demo cluster has exactly two nodes that never change.&lt;/p&gt;
&lt;h2 id=&#34;how-it-went&#34;&gt;How it went&lt;/h2&gt;
&lt;p&gt;Around 50 people attended.
Speaking with some of them afterwards, I got very positive feedback about both the content and the
presentation style, which was a relief for a first talk.
Unfortunately the recording failed due to technical issues, so only the
&lt;a href=&#34;https://docs.google.com/presentation/d/17arLHXOlOKsXsuKKbDSE-cFqpJN5yhTkAFQQsgkqbtU/&#34;&gt;slides&lt;/a&gt; and the code remain.&lt;/p&gt;
&lt;p&gt;Preparing the talk taught me more than giving it did.
Writing a plugin that actually has to work in a cluster forces you to understand the parts of the
specification you would otherwise skim over.
I can recommend it as a way to learn a topic, even without a talk at the end of it.&lt;/p&gt;
</description>
      
    </item>
    
  </channel>
</rss>
