<?xml version="1.0" encoding="utf-8" standalone="yes"?><rssversion="2.0"xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Posts on 1533B4dC0.de</title><link>https://www.1533b4dc0.de/post/</link><description>1533B4dC0.de (Posts)</description><generator>Hugo -- gohugo.io</generator><language>en-us</language><lastBuildDate>Thu, 24 Feb 2022 00:00:00 +0000</lastBuildDate><atom:linkhref="https://www.1533b4dc0.de/post/index.xml"rel="self"type="application/rss+xml"/><item><title>Libvirt & Podman: follow up for Podman 4.0 and netavark</title><link>https://www.1533b4dc0.de/post/libvirt-podman-netavark-follow-up/</link><pubDate>Thu, 24 Feb 2022 00:00:00 +0000</pubDate><guid>https://www.1533b4dc0.de/post/libvirt-podman-netavark-follow-up/</guid><description><p>This is a follow up post to <a href="https://www.1533b4dc0.de/post/libvirt-podman-network-mesh/">&ldquo;Joining libvirt <abbr title="Virtual Machine">VM</abbr>s and Podman container in a common network&rdquo;</a>.
Therefore I won&rsquo;t cover all the basics again and how to configure libvirt because nothing&rsquo;s changed on that side.</p>
</h2><p>Podman 4.0 comes with a completely new network stack replacing the previous <a href="https://www.cni.dev/"><abbr title="Container Network Interface">CNI</abbr></a> stack:</p>
<p>There are <a href="https://www.redhat.com/sysadmin/podman-new-network-stack">great resources</a> that explain the backgrounds of both tools and I don&rsquo;t think I could describe it better than the folks implementing it 😄 so if you&rsquo;re interested have a look at the aforementioned article or the <a href="https://podman.io/releases/2022/02/22/podman-release-v4.0.0.html">release post</a>.</p>
<h2 id="netavark-and-libvirt" >Netavark and libvirt
</h2><p>After reading the announcement I was most curious if I would be able to configure an equivalent setup for Netavark like I described it with Podman 3.x and CNI.</p>
<p><strong>Short answer:</strong> yes, it is possible! 🎉</p>
<p><em>&ldquo;But how?!&rdquo;</em> do you ask?
Well it&rsquo;s pretty much equivalent to the previous solution: you need to create a new Podman network I once more named it <em>&rsquo;libvirt&rsquo;</em>.
To get an idea how the config should look like and where it should placed.
I reused the CLI call from my previous article:</p>
</span></span></code></pre></div><p>The configuration files are now obviously resided in <code>/etc/containers/networks/</code> and my (already modified) <code>libvirt.json</code> now looks like so:</p>
</span></span></code></pre></div><p><em>Side note: I&rsquo;m really happy they dropped the <code>.conflist</code> extension because this way most editors offer really helpful syntax highlighting in the first place!</em></p>
<p>Note that <code>&quot;internal&quot;: false</code> is mandatory. Otherwise I wasn&rsquo;t able to establish communication between VM and container.
I also disabled the Aardvark <abbr title="Domain Name System">DNS</abbr> server and IPv6 support because I don&rsquo;t need it and I also don&rsquo;t expect much benefit of it due to the fact that it can&rsquo;t be aware of the VMs present in the network same as <code>dnsmasq</code> won&rsquo;t be able to resolve containers in the libvirt network.</p>
<p>Having this in place I was again able to reuse the CLI command from my previous article:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>podman run <span style="color:#ae81ff">\
</h2><p>Sometimes the communication between container and VM fails - don&rsquo;t know if I restarted the libvirt network previously or somehow fucked up the container network configuration but a:</p>
</h2><p>I haven&rsquo;t used <em>Netavark</em> and <em>Aardvark</em> a lot, yet.
But I already noticed a few <strong>really awesome</strong> things:</p>
<ul>
<li>the <code>docker-compose</code> support seems to be a lot better now because containers are actually able to talk to each other by <em>service name</em>, something I wasn&rsquo;t able to configure properly in Podman 3.x - at least not rootless.</li>
<li>with <em>Netavark</em> all the Podman configuration is now unified within <code>/etc/containers</code> or <code>$HOME/.config/containers</code> respectively</li>
<li>the new configuration format is a little bit cleaner the the previous one due to the fact that <em>Netavark</em> does not support plugins and with a <code>.json</code> extension editors do help a lot more without requiring extra &ldquo;configuration&rdquo;</li>
</ul></description></item><item><title>Libvirt & Podman: network 'mesh'</title><link>https://www.1533b4dc0.de/post/libvirt-podman-network-mesh/</link><pubDate>Thu, 24 Feb 2022 00:00:00 +0000</pubDate><guid>https://www.1533b4dc0.de/post/libvirt-podman-network-mesh/</guid><description><p><em>Disclaimer: I tested all this with Podman 3.x even though Podman 4.0 is already announced but the <abbr title="Container Network Interface">CNI</abbr> driver is still available with Podman 4.0 and as soon as I get my hands on 4.0 I&rsquo;ll give <strong>Netavark</strong> a try, too!</em></p>
<p>When playing around with containers and <abbr title="Virtual Machine">VM</abbr>s one might ask if it&rsquo;s possible to bring VMs and containers into a common network segment.
I see &lsquo;why the hell would I need a VM anyway when already having containers&rsquo; or something similar I almost see on your face 😜</p>
<p>Well 1st of all, not everything can be solved with containers.
For instance windows applications can be run in Windows containers but I&rsquo;m not aware of how to run a Windows container on my Linux desktop.</p>
<p>But also in pure Linux environments there are cases where a VM is probably a better fit for the problem.
As you might know I&rsquo;m a bit of network 🤓 and I love playing around with &lsquo;weird&rsquo; stuff almost no one else does even think about if not forced to.
So if you try to implement for example your own DHCP server you might want to isolate your experiments (especially at the beginning) to avoid discussion about &ldquo;why&rsquo;s Netflix on the TV not working?!&rdquo; 😄 or also if you try to implement your own &lsquo;firewall&rsquo; with <abbr title="Destination network address translation">DNAT</abbr> support (stay tuned - post&rsquo;s following!).</p>
</h2><p>Okay now that I came around with <em>some</em> arguments - if they&rsquo;re convincing or not is not important - how does this work?</p>
<p>Assuming you&rsquo;ve Libvirt and Podman already installed on your system without any modification and you run</p>
<li>the <code>&lt;mac/&gt;</code> for the bridge interface (of the host)</li>
<li>the <code>&lt;ip/&gt;</code> of the host on the bridge interface
<ul>
<li>an <em>optional</em> <code>&lt;dhcp/&gt;</code> range definition</li>
</ul>
</li>
</ul>
<p>The complete reference for the XML schema can be found <a href="https://libvirt.org/formatnetwork.html">here</a>.</p>
<p>Before we have a closer look how to bring Podman containers into a Libvirt network, let&rsquo;s define a new <code>containers</code> network.
The following snippet contains the definition I&rsquo;ll use:</p>
<li>remove the <code>&lt;forward/&gt;</code> block</li>
<li>change the <code>&lt;name/&gt;</code> and the <code>&lt;uuid/&gt;</code> (with the help of <code>uuidgen</code>)</li>
<li>change the <code>name=&quot;&quot;</code> of the <code>&lt;bridge/&gt;</code></li>
<li>change the <code>address=&quot;&quot;</code> attribute of the <code>&lt;mac/&gt;</code> (use any <a href="https://macaddress.io/mac-address-generator">mac address generator</a>)</li>
<li>change the <code>address=&quot;&quot;</code> attribute of the <code>&lt;ip/&gt;</code> and <code>start=&quot;&quot;</code> and <code>end=&quot;&quot;</code> of the DHCP range accordingly</li>
</ul>
<p>You may use any private network - as far as I can tell it shouldn&rsquo;t matter if you&rsquo;re using a class B, C or D private network as long as you don&rsquo;t have any conflicts with your LAN or any other virtual interfaces of your environment.</p>
<p>When done safe your network definition as <code>.xml</code> file.
To import the configuration you can use <code>virsh net-define</code> like in the following snippet (assuming the network definition is in <code>containers.xml</code>):</p>
</span></span><span style="display:flex;"><span>&gt; Network containers defined from containers.xml
</span></span></code></pre></div><p><em>Note: this only works because the XML already contains an <code>&lt;uuid/&gt;</code>. Otherwise you&rsquo;d have to use <code>virsh net-create</code> and a few more extra steps to make the network actually persistent.</em></p>
<p>If you now check with <code>virsh net-list</code> you&rsquo;d be disappointed because there&rsquo;s no network!
Checking again with <code>virsh net-list --all</code> explains why our <code>containers</code> network wasn&rsquo;t in the output previously because it is by default <em>inactive</em>.
To activate it we&rsquo;ve to start it like so:</p>
</span></span><span style="display:flex;"><span>&gt; Network containers started
</span></span></code></pre></div><p>If you don&rsquo;t mind the extra adapter and wish to use the network frequently in the future you might consider to autostart it:</p>
</h2><p><em>Note: this only works with <strong>rootfull</strong> Podman because rootless Podman does not use CNI but another network stack.</em></p>
<p>A clean Podman installation without any custom network created comes with the default network <code>podman</code>.
Rootfull Podman network configs are by default stored in <code>/etc/cni/net.d</code>.
You should find the default network as <code>87-podman.conflist</code> in the aforementioned directory.</p>
<p>Every Podman network is defined as JSON file.
We will define our own <code>libvirt</code> network to join Podman containers into the previously created Libvirt network.
You can either use <code>podman network create</code> to create the network (at least more or less) or you can copy for example the default network and make some adjustments.</p>
<p>To create the new network from the CLI you can use the following command:</p>
</span></span></code></pre></div><p>Note that I used a different IP range as in the Libvirt network! Otherwise Podman will complain that the IP range is already in use at an adapter.
You can use this command to create the required file in <code>/etc/cni/net.d/</code> but you&rsquo;ve to update the <code>ranges</code> accordingly before creating a container in the network.</p>
<p>Because we&rsquo;ve to edit the <code>.conflist</code> either way copy the default one is also fine.</p>
<p>The <code>.conflist</code> I&rsquo;m using looks like this:</p>
</span></span></code></pre></div><p>Interestingly the <code>rangeStart</code> and <code>rangeEnd</code> are actually IP addresses and not tight to some IP networks but unfortunately there&rsquo;s no equivalent for <code>podman network create</code> hence I update both to a range after the DHCP range of the Libvirt network to make sure that no duplicate IPs are assigned.</p>
<p>I tend to declare the network as <code>host-local</code> but this shouldn&rsquo;t be critical.
The <strong>most important</strong> part is to update the <code>bridge</code> to the same interface like in the Libvirt network definition (in my case <code>conbr0</code>).</p>
<p>After this we&rsquo;re ready to go and you can for instance start a Nginx container in the <code>libvirt</code> network and you should be able to reach it from a VM in the Libvirt network:</p>
</span></span></code></pre></div><p>A nice option for <code>podman run</code> is <code>--ip</code>.
You&rsquo;ve to choose an IP from the previously configured <code>range</code> but you can skip the <code>podman inspect</code> or <code>ip a</code> to get the container IP and the container will have the IP every time you start it, if you like 😉 and speaking of &rsquo;nice&rsquo; <code>podman run</code> options: you do know <code>--replace</code>, don&rsquo;t you?</p></description></item></channel></rss>