<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Virtualisation on Zwindler's Reflection</title><link>https://blog.zwindler.fr/en/tags/virtualisation/</link><description>Recent content in Virtualisation on Zwindler's Reflection</description><generator>Hugo -- gohugo.io</generator><language>en</language><copyright>Licensed under CC BY-SA 4.0</copyright><lastBuildDate>Sun, 30 Mar 2025 12:30:00 +0200</lastBuildDate><atom:link href="https://blog.zwindler.fr/en/tags/virtualisation/index.xml" rel="self" type="application/rss+xml"/><item><title>Proxmox VE 8 Tutorial - SDN in VXLAN Mode with Machines on the Internet</title><link>https://blog.zwindler.fr/en/2025/03/30/proxmox-ve-8-tutorial-sdn-in-vxlan-mode-with-machines-on-the-internet/</link><pubDate>Sun, 30 Mar 2025 12:30:00 +0200</pubDate><guid>https://blog.zwindler.fr/en/2025/03/30/proxmox-ve-8-tutorial-sdn-in-vxlan-mode-with-machines-on-the-internet/</guid><description>&lt;img src="https://blog.zwindler.fr/2025/03/vxlan2.webp" alt="Featured image of post Proxmox VE 8 Tutorial - SDN in VXLAN Mode with Machines on the Internet" /&gt;&lt;h2 id="preamble"&gt;Preamble
&lt;/h2&gt;&lt;p&gt;This tutorial is a kind of &lt;em&gt;special edition&lt;/em&gt; in my series of articles on Proxmox VE 8.&lt;/p&gt;
&lt;p&gt;In the &lt;a class="link" href="https://blog.zwindler.fr/en/2025/03/25/deploying-a-proxmox-ve-8-cluster-on-dedicated-servers-3/4/" &gt;third part which came out a few days ago&lt;/a&gt;, we stopped at a cluster of remote machines on the Internet.&lt;/p&gt;
&lt;p&gt;They&amp;rsquo;re not in the same LAN, and to be honest, they&amp;rsquo;re even about 100ms apart (and it works very well).&lt;/p&gt;
&lt;p&gt;At the end of the article, it works, we have a single network on our two machines, with a functional IPAM and DHCP on both sides. But still, virtual machines on different hosts can&amp;rsquo;t talk to each other directly and it&amp;rsquo;s still a bit unfortunate not to have gone all the way.&lt;/p&gt;
&lt;p&gt;Rather than rewriting that part, I decided to make a small aside where I finish the work and test the VXLAN function of the Proxmox VE SDN, because YES, it can work all the way.&lt;/p&gt;
&lt;h2 id="prerequisites"&gt;Prerequisites
&lt;/h2&gt;&lt;p&gt;I&amp;rsquo;m assuming you already have two (or more) machines within the same Proxmox VE 8 cluster.&lt;/p&gt;
&lt;p&gt;If not, you&amp;rsquo;re in for reading my series of articles (currently being written) on the subject (have fun!):&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://blog.zwindler.fr/en/2025/01/27/deploying-a-proxmox-ve-8-cluster-on-dedicated-servers-1/2/" &gt;Deploying a Proxmox VE 8 Cluster on Dedicated Servers (1/4)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;These machines are not in the same LAN (otherwise no need to bother with VXLAN, the &lt;a class="link" href="https://blog.zwindler.fr/en/2025/03/25/deploying-a-proxmox-ve-8-cluster-on-dedicated-servers-3/4/" &gt;Simple SDN can be enough, as we did in part 3&lt;/a&gt;)&lt;/p&gt;
&lt;h2 id="problem"&gt;Problem
&lt;/h2&gt;&lt;p&gt;What we want to do is create an SDN that goes through the Internet, to the point that virtual machines believe they&amp;rsquo;re on the same LAN.&lt;/p&gt;
&lt;p&gt;We can&amp;rsquo;t do this with Simple SDN, VMs on one host can&amp;rsquo;t contact VMs on another distant host on the Internet, even being in the same Simple SDN and with the same addressing plan.&lt;/p&gt;
&lt;p&gt;But if we read a bit further in the &lt;a class="link" href="https://pve.proxmox.com/pve-docs/chapter-pvesdn.html" target="_blank" rel="noopener"
&gt;PVE documentation on SDN&lt;/a&gt;, we see that this is precisely the use case highlighted for using VXLAN type SDNs:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The VXLAN plugin establishes a tunnel (overlay) on top of an existing network (underlay). This encapsulates layer 2 Ethernet frames within layer 4 UDP datagrams&amp;hellip;
[&amp;hellip;]
You can, for example, create a VXLAN overlay network on top of public internet, appearing to the VMs as if they share the same local Layer 2 network&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Small issue however, in reality, you&amp;rsquo;d better not do it, because frames are not encrypted, and on the Internet, it&amp;rsquo;s really not the best idea in the world&amp;hellip;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Warning VXLAN on its own does does not provide any encryption. When joining multiple sites via VXLAN, make sure to establish a secure connection between the site, for example by using a site-to-site VPN.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;As an alternative, we could have gone directly with the most complete/complex version of the Proxmox VE SDN: &lt;strong&gt;EVPN Zones&lt;/strong&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The EVPN zone creates a routable Layer 3 network, capable of spanning across multiple clusters. This is achieved by establishing a VPN and utilizing BGP as the routing protocol.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;But I don&amp;rsquo;t want to mess with BGP here and I want to keep things simple. However, it&amp;rsquo;s probably the &amp;ldquo;cleanest&amp;rdquo; option for a production setup.&lt;/p&gt;
&lt;h2 id="vxlan-then-but-with-a-vpn"&gt;VXLAN Then, But with a VPN
&lt;/h2&gt;&lt;p&gt;I won&amp;rsquo;t overthink it, we&amp;rsquo;ll set up a small VPN with wireguard manually. There are tons of VPN tools on the market and tons of tools to make life easier. If you want more info on Wireguard, I&amp;rsquo;m sure you&amp;rsquo;ll find plenty, I&amp;rsquo;m just putting the bare minimum here so it &amp;ldquo;just works&amp;rdquo;.&lt;/p&gt;
&lt;p&gt;On both servers, install wireguard, which should be in the default debian repositories:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;apt update &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; apt install -y wireguard
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Generate a key pair &lt;strong&gt;on each machine&lt;/strong&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;wg genkey &lt;span class="p"&gt;|&lt;/span&gt; tee privatekey &lt;span class="p"&gt;|&lt;/span&gt; wg pubkey &amp;gt; publickey
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;A little mental gymnastics, we&amp;rsquo;re going to write a configuration file with for each server, the private key of the server (file &lt;code&gt;privatekey&lt;/code&gt;) we&amp;rsquo;re on, but the public key (file &lt;code&gt;publickey&lt;/code&gt;) &lt;strong&gt;of the remote server&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;(When you think about it, it&amp;rsquo;s obvious, but I prefer to insist)&lt;/p&gt;
&lt;p&gt;And you obviously need to change addresses and network interfaces depending on which server you&amp;rsquo;re on so as not to have conflicts.&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;vi /etc/wireguard/wg0.conf
[Interface]
Address = 10.10.30.1/24
ListenPort = 51820
PrivateKey = &amp;lt;local server private key&amp;gt;
PostUp = iptables -A FORWARD -i wg0 -j ACCEPT
PostUp = iptables -t nat -A POSTROUTING -o &amp;lt;network interface name&amp;gt; -j MASQUERADE
PostDown = iptables -D FORWARD -i wg0 -j ACCEPT
PostDown = iptables -t nat -D POSTROUTING -o &amp;lt;network interface name&amp;gt; -j MASQUERADE
[Peer]
PublicKey = &amp;lt;remote server public key&amp;gt;
Endpoint = &amp;lt;remote server public IP&amp;gt;:51820
AllowedIPs = 10.10.30.2/32
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Note: you can also add more nodes to the VPN, just add more &amp;ldquo;Peer&amp;rdquo; sections.&lt;/p&gt;
&lt;p&gt;Finish by starting the VPN and verifying that nodes talk to each other:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;systemctl &lt;span class="nb"&gt;enable&lt;/span&gt; wg-quick@wg0 --now
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ping 10.10.30.1
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ping 10.10.30.2
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="sdn-configuration"&gt;SDN Configuration
&lt;/h2&gt;&lt;p&gt;Normally, if you followed the previous articles, you already have the prerequisites, but for those who haven&amp;rsquo;t, I&amp;rsquo;ll repeat that in the /etc/network/interfaces file, it&amp;rsquo;s necessary to add at the end of the file the following line (followed by a small &lt;code&gt;systemctl restart networking&lt;/code&gt;)&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;source /etc/network/interfaces.d/*
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Then, in the Datacenter menu, open the SDN submenu.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://blog.zwindler.fr/2025/03/sdn1.avif"
loading="lazy"
&gt;&lt;/p&gt;
&lt;p&gt;In the SDN/Zones menu, add a &amp;ldquo;VXLan&amp;rdquo; type zone. Two important points here:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;we need to fill in the list of all &amp;ldquo;peers&amp;rdquo;, here the IPs of our VPNs so 10.10.30.1 and 10.10.30.2&lt;/li&gt;
&lt;li&gt;we&amp;rsquo;ll need to adjust the MTU. By default, a frame is 1500. Except that wireguard for its encapsulation has reduced the MTU to 1420 and VXLAN encapsulation takes 50. So we need to set 1370 to best avoid fragmentation, at worst, dropped packets&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src="https://blog.zwindler.fr/2025/03/vxlan2.avif"
loading="lazy"
&gt;&lt;/p&gt;
&lt;p&gt;If you just read the previous article, you&amp;rsquo;ll notice that here, there&amp;rsquo;s no &amp;ldquo;checkbox&amp;rdquo; to enable DHCP on the zone. Unfortunately, that&amp;rsquo;s because it&amp;rsquo;s not available yet.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Currently only Simple Zones have support for automatic DHCP&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Source: &lt;a class="link" href="https://pve.proxmox.com/pve-docs/chapter-pvesdn.html#pvesdn_config_dhcp" target="_blank" rel="noopener"
&gt;pve.proxmox.com/pve-docs/chapter-pvesdn.html#pvesdn_config_dhcp&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src="https://blog.zwindler.fr/2025/02/hulk_sad.gif"
loading="lazy"
&gt;&lt;/p&gt;
&lt;p&gt;Once you&amp;rsquo;ve validated, go to the SDN/VNets submenu, click the &amp;ldquo;Create&amp;rdquo; button to create a virtual network, then select it once created to create a subnet.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://blog.zwindler.fr/2025/03/vxlan4.avif"
loading="lazy"
&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src="https://blog.zwindler.fr/2025/03/vxlan5.avif"
loading="lazy"
&gt;&lt;/p&gt;
&lt;p&gt;Once again, don&amp;rsquo;t forget to check the DHCP section, to declare the range for our future DHCP.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://blog.zwindler.fr/2025/03/vxlan6.avif"
loading="lazy"
&gt;&lt;/p&gt;
&lt;p&gt;Once we&amp;rsquo;ve validated everything, we see that next to all these new things we&amp;rsquo;ve just created, there&amp;rsquo;s an icon with two yellow arrows and a &amp;ldquo;New&amp;rdquo; status.&lt;/p&gt;
&lt;p&gt;To deploy these changes, we need to go back to the SDN menu from the beginning, and click Apply. Two &amp;ldquo;vxlan1&amp;rdquo; lines (one for each server, actually) should appear.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://blog.zwindler.fr/2025/03/vxlan7.avif"
loading="lazy"
&gt;&lt;/p&gt;
&lt;h2 id="is-that-all"&gt;Is That All?
&lt;/h2&gt;&lt;p&gt;Yes, that&amp;rsquo;s all, honestly, I really should have pushed a bit more before posting my previous article&amp;hellip;&lt;/p&gt;
&lt;p&gt;To convince yourself, just pop two LXC containers (without DHCP 🥲), one on each server, and see if they ping each other.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://blog.zwindler.fr/2025/03/vxlan-test.avif"
loading="lazy"
&gt;&lt;/p&gt;
&lt;p&gt;It works!&lt;/p&gt;
&lt;p&gt;Well&amp;hellip; all that&amp;rsquo;s left is to migrate all my existing machines to the VXLAN vnet to finally have a cluster where VMs can see each other!!&lt;/p&gt;</description></item><item><title>Deploying a Proxmox VE 8 Cluster on Dedicated Servers (3/4)</title><link>https://blog.zwindler.fr/en/2025/03/25/deploying-a-proxmox-ve-8-cluster-on-dedicated-servers-3/4/</link><pubDate>Tue, 25 Mar 2025 12:30:00 +0200</pubDate><guid>https://blog.zwindler.fr/en/2025/03/25/deploying-a-proxmox-ve-8-cluster-on-dedicated-servers-3/4/</guid><description>&lt;img src="https://blog.zwindler.fr/2025/03/sdn2.webp" alt="Featured image of post Deploying a Proxmox VE 8 Cluster on Dedicated Servers (3/4)" /&gt;&lt;p&gt;Note - this article is part of a series:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://blog.zwindler.fr/en/2025/01/27/deploying-a-proxmox-ve-8-cluster-on-dedicated-servers-1/2/" &gt;Deploying a Proxmox VE 8 Cluster on Dedicated Servers (1/4)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://blog.zwindler.fr/en/2025/02/17/deploying-a-proxmox-ve-8-cluster-on-dedicated-servers-2/3/" &gt;Deploying a Proxmox VE 8 Cluster on Dedicated Servers (2/4)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://blog.zwindler.fr/en/2025/03/25/deploying-a-proxmox-ve-8-cluster-on-dedicated-servers-3/4/" &gt;Deploying a Proxmox VE 8 Cluster on Dedicated Servers (3/4)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://blog.zwindler.fr/en/2025/03/30/proxmox-ve-8-tutorial-sdn-in-vxlan-mode-with-machines-on-the-internet/" &gt;Special Edition - SDN in VXLAN Mode with Machines on the Internet&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;And &lt;em&gt;at least&lt;/em&gt; one more to come&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="picking-up-where-we-left-off-first-steps-in-the-ui"&gt;Picking Up Where We Left Off: First Steps in the UI
&lt;/h2&gt;&lt;p&gt;In the previous tutorial (which I invite you to read, if you haven&amp;rsquo;t already, otherwise this won&amp;rsquo;t be clear), we configured storage, networking, and deployed our first virtual machine to make sure everything works. But there&amp;rsquo;s still quite a bit to explore, including clustering, the Proxmox VE SDN, the built-in firewall, backups, monitoring&amp;hellip;&lt;/p&gt;
&lt;p&gt;So we&amp;rsquo;re picking up where we left off, and we&amp;rsquo;re going to install another server (hard to make a cluster with a single machine).&lt;/p&gt;
&lt;p&gt;This server was reinstalled with the same procedures as the server I&amp;rsquo;m talking about in parts 1 and 2, except that we don&amp;rsquo;t need to create the bridge (vmbr0) because we&amp;rsquo;re going to use the SDN!!&lt;/p&gt;
&lt;p&gt;Ideally, all machines in the cluster should have the same storage pools since I remind you, this configuration is supposed to be common to all servers, as it&amp;rsquo;s managed at the &amp;ldquo;Datacenter&amp;rdquo; level of our cluster (even if you can configure exceptions).&lt;/p&gt;
&lt;h2 id="creating-the-cluster"&gt;Creating the Cluster
&lt;/h2&gt;&lt;p&gt;Clustering Proxmox VE machines is a topic I&amp;rsquo;ve covered extensively on the blog, to the point that some of you know me mainly for these articles ;-):&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://blog.zwindler.fr/2019/07/22/proxmox-en-5-min-ansible-tinc/" &gt;A Proxmox VE Cluster in 5 Minutes with Ansible&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://blog.zwindler.fr/2019/08/20/cluster-proxmox-ve-v6-cette-fois-ci/" &gt;Proxmox VE Cluster, v6 this time!&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://blog.zwindler.fr/2019/10/11/un-cluster-proxmox-ve-avec-seulement-2-machines/" &gt;A Proxmox VE Cluster with Only 2 Machines!&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://blog.zwindler.fr/2017/09/19/tutoriel-demonter-proprement-cluster-proxmox-ve/" &gt;[Tutorial] Properly Dismantling a Proxmox VE Cluster&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;So I won&amp;rsquo;t spend too much time on it. Just know that:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;it&amp;rsquo;s easier to do since version 6 because there&amp;rsquo;s no longer a need to set up a VPN between servers (corosync v3)&lt;/li&gt;
&lt;li&gt;it can be done from the command line&lt;/li&gt;
&lt;li&gt;in any case, you need to log in as root &lt;strong&gt;with password&lt;/strong&gt; when clustering&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Very briefly then, we go to the first server, in the &lt;strong&gt;Server View&lt;/strong&gt; at the top left, we select our &lt;strong&gt;Datacenter&lt;/strong&gt;, then in the &lt;strong&gt;Cluster&lt;/strong&gt; menu.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://blog.zwindler.fr/2025/02/create-cluster-1.avif"
loading="lazy"
&gt;&lt;/p&gt;
&lt;p&gt;Click on the &lt;strong&gt;Create Cluster&lt;/strong&gt; button.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://blog.zwindler.fr/2025/02/create-cluster-2.avif"
loading="lazy"
&gt;&lt;/p&gt;
&lt;p&gt;Note: here, it&amp;rsquo;s simple, I only have one network card, so there&amp;rsquo;s no doubt about which interface to use. However, in the case of a server with more interfaces and more bridges (or VPNs as we had to do until PVE 6), you need to choose carefully which interface is used for clustering.&lt;/p&gt;
&lt;p&gt;We validate the form:&lt;/p&gt;
&lt;p&gt;&lt;img src="https://blog.zwindler.fr/2025/02/create-cluster-3.avif"
loading="lazy"
&gt;&lt;/p&gt;
&lt;p&gt;From this point on, the server is no longer in &amp;ldquo;standalone&amp;rdquo; mode and has additional systemd services.&lt;/p&gt;
&lt;p&gt;We notably have a /etc/pve folder that is synchronized between all nodes (the famous &lt;a class="link" href="https://pve.proxmox.com/wiki/Proxmox_Cluster_File_System_%28pmxcfs%29" target="_blank" rel="noopener"
&gt;Proxmox Cluster File System&lt;/a&gt;) with the configuration of each node and the configuration files of virtual machines. We also have the corosync software, which will regularly contact all cluster nodes to ensure everyone is alive/reachable.&lt;/p&gt;
&lt;h2 id="joining-the-cluster"&gt;Joining the Cluster
&lt;/h2&gt;&lt;p&gt;If we go back to the &amp;ldquo;Cluster&amp;rdquo; menu, we now have information displayed about our cluster, namely its number of nodes (here just one, normal). Click on the &lt;strong&gt;Join information&lt;/strong&gt; button.&lt;/p&gt;
&lt;p&gt;A popup opens with several pieces of information to copy-paste that will be requested in the menu of the other server, the one that will join the cluster:&lt;/p&gt;
&lt;p&gt;&lt;img src="https://blog.zwindler.fr/2025/02/create-cluster-4.avif"
loading="lazy"
&gt;&lt;/p&gt;
&lt;p&gt;So we connect to the graphical interface of our second Proxmox VE server (my Atom in the example), we go to the same menu, but instead of creating a new cluster, we click on the &lt;strong&gt;Join Cluster&lt;/strong&gt; button:&lt;/p&gt;
&lt;p&gt;&lt;img src="https://blog.zwindler.fr/2025/03/join-cluster.avif"
loading="lazy"
&gt;&lt;/p&gt;
&lt;p&gt;Normally a little scare, once the node joins the cluster, you&amp;rsquo;ll lose control of the web interface and get a &amp;ldquo;401&amp;rdquo; error message. This is &amp;ldquo;normal&amp;rdquo;, when the server enters the cluster, services are restarted and we switch from standalone mode to clustered mode&amp;hellip;&lt;/p&gt;
&lt;p&gt;&lt;img src="https://blog.zwindler.fr/2025/03/join-cluster2.avif"
loading="lazy"
&gt;&lt;/p&gt;
&lt;p&gt;Don&amp;rsquo;t panic, an F5 should fix the issue (or connect to the &amp;ldquo;first&amp;rdquo; server of the cluster).&lt;/p&gt;
&lt;p&gt;We now have a nice cluster :)&lt;/p&gt;
&lt;p&gt;&lt;img src="https://blog.zwindler.fr/2025/03/pve-cluster.avif"
loading="lazy"
&gt;&lt;/p&gt;
&lt;h2 id="split-brain"&gt;Split Brain
&lt;/h2&gt;&lt;p&gt;Note however that in my example, we only have 2 nodes, which is more than discouraged when making a Linux cluster (actually, a cluster in general). If the network link ever goes down between our two machines, they&amp;rsquo;ll have no way of knowing if it&amp;rsquo;s a network problem (&lt;em&gt;also known as split brain&lt;/em&gt;) or a node failure.&lt;/p&gt;
&lt;p&gt;To avoid breaking everything by restarting VMs on both sides (the most catastrophic case in a split brain), when quorum is no longer reached, Proxmox VE puts nodes without a majority in (almost) &amp;ldquo;read-only&amp;rdquo; mode.&lt;/p&gt;
&lt;p&gt;And in case it&amp;rsquo;s not clear, quorum is half the nodes +1, so here: 2/2+1 = 2&amp;hellip; so as soon as we lose one of the two nodes, we lose quorum.&lt;/p&gt;
&lt;p&gt;So if we ever cut a node or the communication between the two, your still active VMs will continue to work (I debated this on LinkedIn a few days ago).&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;However&lt;/strong&gt;, it will be impossible to modify the cluster configuration, start or create VMs, etc.&lt;/p&gt;
&lt;p&gt;The only thing we can possibly do that isn&amp;rsquo;t &amp;ldquo;read only&amp;rdquo; is stop VMs, because that doesn&amp;rsquo;t induce any risk for data consistency. But you won&amp;rsquo;t be able to turn them back on, you&amp;rsquo;ve been warned&amp;hellip;&lt;/p&gt;
&lt;p&gt;For the record, the LinkedIn debate was &amp;ldquo;does ProxmoxVE cut all VMs in case of split brain&amp;rdquo; and the answer is obviously &lt;strong&gt;no&lt;/strong&gt;. However, most actions are indeed blocked.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://blog.zwindler.fr/2025/03/quorum-ko1.avif"
loading="lazy"
&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src="https://blog.zwindler.fr/2025/03/quorum-ko2.avif"
loading="lazy"
&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;In any case&lt;/strong&gt;, to avoid this, the best thing is to have an odd number of nodes so that split brain can never happen, or possibly add a complementary vote using an instance serving only as an arbiter as explained in my old 2019 article or in the official documentation:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://blog.zwindler.fr/2019/10/11/un-cluster-proxmox-ve-avec-seulement-2-machines/" target="_blank" rel="noopener"
&gt;A Proxmox VE Cluster with Only 2 Machines!&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://pve.proxmox.com/wiki/Cluster_Manager#_corosync_external_vote_support" target="_blank" rel="noopener"
&gt;Proxmox Wiki - Corosync External Vote Support&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="sdn-configuration"&gt;SDN Configuration
&lt;/h2&gt;&lt;p&gt;OK, cool, we have a two-machine cluster. But in the current configuration, the VM we created in the previous part can&amp;rsquo;t easily migrate from one server to another. Indeed, we attached it to a Linux bridge (vmbr0) that has its own network addressing plan.&lt;/p&gt;
&lt;p&gt;In case of migration, we would potentially need to start the machine, change the IP address, review iptables/firewall rules. That&amp;rsquo;s what I was doing until now, and in the case of a DR plan for a lab infra and a personal blog, it&amp;rsquo;s &amp;ldquo;OK&amp;rdquo;.&lt;/p&gt;
&lt;p&gt;A big new feature in version 8.1 is the activation of an &amp;ldquo;SDN&amp;rdquo; (Software Defined Network) module that has been in testing by developers and some early adopters since version 6.X, which will allow us to manage this centrally from the interface. If you want to read the official documentation, it&amp;rsquo;s here:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://pve.proxmox.com/pve-docs/chapter-pvesdn.html" target="_blank" rel="noopener"
&gt;pve.proxmox.com/pve-docs/chapter-pvesdn.html&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The only prerequisite we&amp;rsquo;re missing is dnsmasq for DHCP, and the documentation tells us to run the following commands on our machines:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;apt update
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;apt install dnsmasq
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# disable default instance&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;systemctl disable --now dnsmasq
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;And in the /etc/network/interfaces file, it&amp;rsquo;s also necessary to add at the end of the file the line (followed by a small &lt;code&gt;systemctl restart networking&lt;/code&gt;)&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;source /etc/network/interfaces.d/*
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;In the Datacenter menu, open the SDN submenu. Note that SDNs are already declared, but these are actually the default networks we declared in previous articles:&lt;/p&gt;
&lt;p&gt;&lt;img src="https://blog.zwindler.fr/2025/03/sdn1.avif"
loading="lazy"
&gt;&lt;/p&gt;
&lt;p&gt;In the SDN/Zones menu, add a &amp;ldquo;Simple&amp;rdquo; type zone. There are more complex zones that will be useful in production contexts with non-trivial LANs (VLAN, VXLan) but in our case, Simple is sufficient.&lt;/p&gt;
&lt;p&gt;Note: don&amp;rsquo;t forget to check the &lt;strong&gt;advanced&lt;/strong&gt; box to enable DHCP. &lt;strong&gt;YES we&amp;rsquo;re finally going to have DHCP for our virtual machines and containers&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://blog.zwindler.fr/2025/03/sdn2.avif"
loading="lazy"
&gt;&lt;/p&gt;
&lt;p&gt;Once you&amp;rsquo;ve validated, go to the SDN/VNets submenu, click the &amp;ldquo;Create&amp;rdquo; button to create a virtual network, then select it once created to create a subnet.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://blog.zwindler.fr/2025/03/sdn3.avif"
loading="lazy"
&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src="https://blog.zwindler.fr/2025/03/sdn4.avif"
loading="lazy"
&gt;&lt;/p&gt;
&lt;p&gt;Once again, don&amp;rsquo;t forget to check the DHCP section, to declare the range for our future DHCP.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://blog.zwindler.fr/2025/03/sdn5.avif"
loading="lazy"
&gt;&lt;/p&gt;
&lt;p&gt;Once we&amp;rsquo;ve validated everything, we see that next to all these new things we&amp;rsquo;ve just created, there&amp;rsquo;s an icon with two yellow arrows and a &amp;ldquo;New&amp;rdquo; status.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://blog.zwindler.fr/2025/03/sdn6.avif"
loading="lazy"
&gt;&lt;/p&gt;
&lt;p&gt;To deploy these changes, we need to go back to the SDN menu from the beginning, and click Apply. Two &amp;ldquo;sdn1&amp;rdquo; lines (one for each server, actually) should appear.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://blog.zwindler.fr/2025/03/sdn7.avif"
loading="lazy"
&gt;&lt;/p&gt;
&lt;p&gt;Fun fact, the Proxmox VE SDN will add iptables rules that should look familiar if you&amp;rsquo;ve followed the previous articles:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;#version:5
auto vnet1
iface vnet1
address 10.10.20.1/24
post-up iptables -t nat -A POSTROUTING -s &amp;#39;10.10.20.0/24&amp;#39; -o vmbr0 -j SNAT --to-source 203.0.113.1
post-down iptables -t nat -D POSTROUTING -s &amp;#39;10.10.20.0/24&amp;#39; -o vmbr0 -j SNAT --to-source 203.0.113.1
post-up iptables -t raw -I PREROUTING -i fwbr+ -j CT --zone 1
post-down iptables -t raw -D PREROUTING -i fwbr+ -j CT --zone 1
bridge_ports none
bridge_stp off
bridge_fd 0
ip-forward on
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;And if now, I recreate another virtual machine, but this time instead of &lt;strong&gt;vmbr0&lt;/strong&gt;, I choose &lt;strong&gt;vnet1&lt;/strong&gt;, I don&amp;rsquo;t need to enter the IP address (since I have the SDN serving DHCP) and it has Internet access without additional configuration.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://blog.zwindler.fr/2025/03/sdn8.avif"
loading="lazy"
&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src="https://blog.zwindler.fr/2025/03/sdn9.avif"
loading="lazy"
&gt;&lt;/p&gt;
&lt;p&gt;With this configuration however (SDN in &lt;strong&gt;Simple Zone&lt;/strong&gt; mode), it still won&amp;rsquo;t be possible to have virtual machines communicate with each other. That will be possible with more complex configurations:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;You can, for example, create a VXLAN overlay network on top of public internet, appearing to the VMs as if they share the same local Layer 2 network&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://pve.proxmox.com/pve-docs/chapter-pvesdn.html#pvesdn_zone_plugin_vxlan" target="_blank" rel="noopener"
&gt;VXLan Zones&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://pve.proxmox.com/pve-docs/chapter-pvesdn.html#pvesdn_zone_plugin_evpn" target="_blank" rel="noopener"
&gt;EVPN Zones&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Note: I&amp;rsquo;ve explored VXLANs since then, and &lt;a class="link" href="https://blog.zwindler.fr/en/2025/03/30/proxmox-ve-8-tutorial-sdn-in-vxlan-mode-with-machines-on-the-internet/" &gt;I wrote a complementary article here&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id="conclusion"&gt;Conclusion
&lt;/h2&gt;&lt;p&gt;I still haven&amp;rsquo;t finished this series, because I still have things to say about SDN replication and Proxmox VE firewalling, backups, monitoring, but once again, I&amp;rsquo;m already exceeding 12,000 characters. So it&amp;rsquo;s time to publish the article and start writing the next one.&lt;/p&gt;
&lt;p&gt;And in the meantime, have fun :)&lt;/p&gt;</description></item><item><title>Deploying a Proxmox VE 8 Cluster on Dedicated Servers (2/3)</title><link>https://blog.zwindler.fr/en/2025/02/17/deploying-a-proxmox-ve-8-cluster-on-dedicated-servers-2/3/</link><pubDate>Mon, 17 Feb 2025 10:30:00 +0200</pubDate><guid>https://blog.zwindler.fr/en/2025/02/17/deploying-a-proxmox-ve-8-cluster-on-dedicated-servers-2/3/</guid><description>&lt;img src="https://blog.zwindler.fr/2025/02/proxmox8.webp" alt="Featured image of post Deploying a Proxmox VE 8 Cluster on Dedicated Servers (2/3)" /&gt;&lt;p&gt;Note - this article is part of a series:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://blog.zwindler.fr/en/2025/01/27/deploying-a-proxmox-ve-8-cluster-on-dedicated-servers-1/2/" &gt;Deploying a Proxmox VE 8 Cluster on Dedicated Servers (1/4)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://blog.zwindler.fr/en/2025/02/17/deploying-a-proxmox-ve-8-cluster-on-dedicated-servers-2/3/" &gt;Deploying a Proxmox VE 8 Cluster on Dedicated Servers (2/4)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://blog.zwindler.fr/en/2025/03/25/deploying-a-proxmox-ve-8-cluster-on-dedicated-servers-3/4/" &gt;Deploying a Proxmox VE 8 Cluster on Dedicated Servers (3/4)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://blog.zwindler.fr/en/2025/03/30/proxmox-ve-8-tutorial-sdn-in-vxlan-mode-with-machines-on-the-internet/" &gt;Special Edition - SDN in VXLAN Mode with Machines on the Internet&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;And &lt;em&gt;at least&lt;/em&gt; one more to come&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="picking-up-where-we-left-off-first-steps-in-the-ui"&gt;Picking Up Where We Left Off: First Steps in the UI
&lt;/h2&gt;&lt;p&gt;In the previous tutorial (which I invite you to read, if you haven&amp;rsquo;t already, otherwise this won&amp;rsquo;t be clear), we chose a dedicated physical server from a provider like OVHCloud or Hetzner. We then installed Proxmox VE in the latest version (8.x), configured some basic security options, added users and groups.&lt;/p&gt;
&lt;p&gt;Now we can try connecting to the UI. The first thing that should strike you (💥 ouch!) is that the administration page is in HTTPS with a self-signed certificate. We&amp;rsquo;ll start by fixing that.&lt;/p&gt;
&lt;p&gt;Something quite frustrating with Proxmox VE (but it&amp;rsquo;s probably for &amp;ldquo;good reasons&amp;rdquo; that I don&amp;rsquo;t know) is that some operations can&amp;rsquo;t be done in the UI if you connect with the admin account zwindler@pve that we created in the previous blog post.&lt;/p&gt;
&lt;p&gt;This is typically true for updates, clustering, and configuration and&amp;hellip; for &lt;strong&gt;certificate configuration&lt;/strong&gt; (non-exhaustive list). So here, we&amp;rsquo;ll have to connect as root@pam for now and not as zwindler@pve&amp;hellip;&lt;/p&gt;
&lt;p&gt;&lt;img src="https://blog.zwindler.fr/2025/02/auth-pam.avif"
loading="lazy"
&gt;&lt;/p&gt;
&lt;p&gt;Note that there are (for now) 2 &amp;ldquo;realms&amp;rdquo;, Linux PAM (for root) and Proxmox VE Auth (for admin).&lt;/p&gt;
&lt;p&gt;&lt;img src="https://blog.zwindler.fr/2025/02/auth-pve.avif"
loading="lazy"
&gt;&lt;/p&gt;
&lt;p&gt;In the right bar, we find our server, which is for now alone in its datacenter (we&amp;rsquo;ll come back to this later). There are several views in the Proxmox VE UI, some things are hard to find if you don&amp;rsquo;t have this in mind. Here, I&amp;rsquo;m in the &amp;ldquo;server view&amp;rdquo;, probably the most classic if you come from the VMware world. In this menu, you&amp;rsquo;ll find your hypervisors and we can interact with each of them, how they are configured.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://blog.zwindler.fr/2025/02/pve-first-login.avif"
loading="lazy"
&gt;&lt;/p&gt;
&lt;p&gt;Once our server is selected, we have the main menu displaying many menus. Select &lt;strong&gt;System / Certificates&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://blog.zwindler.fr/2025/02/pve-certs-01.avif"
loading="lazy"
&gt;&lt;/p&gt;
&lt;p&gt;We&amp;rsquo;re in luck, Proxmox VE comes with a module to automatically order &lt;a class="link" href="https://letsencrypt.org/" target="_blank" rel="noopener"
&gt;Let&amp;rsquo;s Encrypt&lt;/a&gt; certificates. If you have your own certificate that works too (button &lt;strong&gt;Upload Custom Certificate&lt;/strong&gt;), of course, but I&amp;rsquo;ll assume you don&amp;rsquo;t have one, like me.&lt;/p&gt;
&lt;p&gt;In the ACME section, click on &lt;strong&gt;Add ACME Account&lt;/strong&gt; to register your email and accept the Let&amp;rsquo;s Encrypt Terms Of Service (TOS).&lt;/p&gt;
&lt;p&gt;&lt;img src="https://blog.zwindler.fr/2025/02/pve-certs-02.avif"
loading="lazy"
&gt;&lt;/p&gt;
&lt;p&gt;From there, add our server&amp;rsquo;s FQDN by clicking the &lt;strong&gt;Add&lt;/strong&gt; button under ACME. The button was grayed out until we added an account.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://blog.zwindler.fr/2025/02/pve-certs-03.avif"
loading="lazy"
&gt;&lt;/p&gt;
&lt;p&gt;Now we can finally order the certificate by clicking on &lt;strong&gt;Order Certificates Now&lt;/strong&gt;. If everything goes well, the certificate will be correctly delivered by Let&amp;rsquo;s Encrypt, and the pve-proxy server (which serves the Proxmox VE UI frontend) should restart, and your web page refresh, with a proper certificate this time :).&lt;/p&gt;
&lt;p&gt;&lt;img src="https://blog.zwindler.fr/2025/02/pve-certs-04.avif"
loading="lazy"
&gt;&lt;/p&gt;
&lt;h2 id="storage--zfs"&gt;Storage / ZFS
&lt;/h2&gt;&lt;p&gt;If you read my blog often and I tell you that I&amp;rsquo;m an unconditional fan of ZFS, you won&amp;rsquo;t be surprised.&lt;/p&gt;
&lt;p&gt;And if you read the previous article carefully, you&amp;rsquo;ll remember that we reduced the default partition of the OVHcloud template in LVM to be able to create a nice ZFS partition. But if we go to the storage view, it&amp;rsquo;s unfortunately not visible.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://blog.zwindler.fr/2025/02/hulk_sad.gif"
loading="lazy"
&gt;&lt;/p&gt;
&lt;p&gt;Small UI subtlety, the menu to add storage is found at the Datacenter level and not in the server configuration itself. In theory, storage management must be identical on all servers in the same DC in Proxmox VE, even if we can override this principle and set up exceptions for many versions already.&lt;/p&gt;
&lt;p&gt;In &lt;strong&gt;Datacenter / Storage&lt;/strong&gt;, click &lt;strong&gt;Add&lt;/strong&gt;, then ZFS in the dropdown menu:&lt;/p&gt;
&lt;p&gt;&lt;img src="https://blog.zwindler.fr/2025/02/storage-01.avif"
loading="lazy"
&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src="https://blog.zwindler.fr/2025/02/storage-02.avif"
loading="lazy"
&gt;&lt;/p&gt;
&lt;p&gt;On ZFS type storage, we can only store &amp;ldquo;Disk images&amp;rdquo; and &amp;ldquo;Containers&amp;rdquo;, which won&amp;rsquo;t help us if we also want to store ISOs, templates, or backups.&lt;/p&gt;
&lt;p&gt;We can settle for storing them on the default &amp;ldquo;local&amp;rdquo; storage.&lt;/p&gt;
&lt;p&gt;But we can also &amp;ldquo;cheat&amp;rdquo; by connecting to the server via SSH, creating a folder (/tank/data in my example), then creating a new Directory type storage that has no restriction on data types.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://blog.zwindler.fr/2025/02/storage-03.avif"
loading="lazy"
&gt;&lt;/p&gt;
&lt;h2 id="lets-talk-about-zfs"&gt;Let&amp;rsquo;s Talk About ZFS
&lt;/h2&gt;&lt;p&gt;I&amp;rsquo;ve banged my head countless times with people who persist in saying nonsense about ZFS, even after explaining it to them.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;no, you don&amp;rsquo;t need ECC RAM to store things on ZFS. First, it&amp;rsquo;s a recommendation (probably a bit zealous) made by people who designed an extremely robust filesystem. Many production systems run with ZFS without ECC RAM. Second, it&amp;rsquo;s especially true if you do deduplication, because losing a block can have catastrophic consequences in such cases&amp;hellip;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;no, ZFS doesn&amp;rsquo;t require 1 GB of RAM per TB of disk, again, that&amp;rsquo;s only if you enable deduplication (to store the correspondence tables between hashes and blocks).&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;On the other hand, what is accurate is that by default, ZFS will try to use 50% of the available RAM on your server and use it as cache. In many administration software, including Proxmox VE, this value will be way too high for us, because RAM is a precious resource on a hypervisor.&lt;/p&gt;
&lt;p&gt;That doesn&amp;rsquo;t mean this feature is useless. Having cache when you have unused RAM is always good. So, we&amp;rsquo;ll reduce this value to avoid resource conflicts between optimizing our storage performance and the number of VMs we can host.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Restrict to 512MB&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="m"&gt;536870912&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; sudo tee -a /sys/module/zfs/parameters/zfs_arc_max
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Restrict to 4GB&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="m"&gt;4294967296&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; sudo tee -a /sys/module/zfs/parameters/zfs_arc_max
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Note: this command will need to be persisted one way or another&lt;/p&gt;
&lt;h2 id="networking"&gt;Networking
&lt;/h2&gt;&lt;p&gt;Well&amp;hellip; I tried to postpone as long as possible when we get to networking (because I hate it) but at some point, we&amp;rsquo;ll have to get to it&amp;hellip;&lt;/p&gt;
&lt;p&gt;By default, our Proxmox VE server is installed with a Linux bridge that will allow us to share network between our server&amp;rsquo;s physical interface and our virtual machines.&lt;/p&gt;
&lt;p&gt;This setup works well on your local network with DHCP and your own local IPv4 LAN or if you have an IP range (whether v6 or v4) and something to assign them to virtual machines.&lt;/p&gt;
&lt;p&gt;Unfortunately in my case, I only have one IPv4 (I could enable IPv6 but I&amp;rsquo;d have other issues and I prefer to keep it simple here). If I create VMs and assign them to the bridge, they won&amp;rsquo;t get an IP and won&amp;rsquo;t have Internet access.&lt;/p&gt;
&lt;p&gt;There are several ways to connect virtual machines to the external network. If you have time, I recommend reading carefully the Proxmox VE Wiki which has a very good page listing the different possibilities.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://pve.proxmox.com/wiki/Network_Configuration" target="_blank" rel="noopener"
&gt;pve.proxmox.com/wiki/Network_Configuration&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In the previous articles on &lt;a class="link" href="https://blog.zwindler.fr/2017/07/11/deploiment-de-proxmox-ve-5-sur-un-serveur-dedie-part-1" &gt;Proxmox VE 5&lt;/a&gt; then &lt;a class="link" href="https://blog.zwindler.fr/2020/03/02/deploiement-de-proxmox-ve-6-pfsense-sur-un-serveur-dedie/" &gt;Proxmox VE 6&lt;/a&gt;, we did complicated stuff with multiple bridges, DMZ, pfSense firewalling, and a hellish iptables script.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://blog.zwindler.fr/2017/07/proxmox-install_simple-infra-map.avif"
loading="lazy"
&gt;&lt;/p&gt;
&lt;p&gt;Just thinking about it, I&amp;rsquo;m already exhausted.&lt;/p&gt;
&lt;p&gt;Fortunately, there has been a built-in firewall in Proxmox VE for several versions now, as well as an SDN that I&amp;rsquo;ve never taken the time to explore and I think this is the right tutorial to do it :).&lt;/p&gt;
&lt;p&gt;So we&amp;rsquo;ll refer to the official documentation, and choose the &amp;ldquo;Masquerading (NAT) with iptables&amp;rdquo; mode, but with a simpler setup compared to before.&lt;/p&gt;
&lt;h2 id="danger-zone"&gt;Danger Zone
&lt;/h2&gt;&lt;p&gt;Network interface configuration can theoretically be done directly from the UI rather than modifying configuration files (/etc/network/interfaces). In the server view, go to the &lt;strong&gt;System / Network&lt;/strong&gt; menu:&lt;/p&gt;
&lt;p&gt;&lt;img src="https://blog.zwindler.fr/2025/02/pve-network-1.avif"
loading="lazy"
&gt;&lt;/p&gt;
&lt;p&gt;Here, you can see I wasn&amp;rsquo;t making things up, and we do have a bridge with our physical interface (here enp1s0).&lt;/p&gt;
&lt;p&gt;(We even have an IPv6 range, oh my 🙈 I have no excuse&amp;hellip; ANYWAY, let&amp;rsquo;s pretend we didn&amp;rsquo;t see that.)&lt;/p&gt;
&lt;p&gt;We&amp;rsquo;re now at the fun part where we can easily cut ourselves off. I&amp;rsquo;ve done it often enough and had to go into rescue mode&amp;hellip;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;fun fun fun fun&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The idea here is to remove the interface from the bridge, configure the network directly on it, and give a local network for our VMs on the bridge, while adding iptables rules for masquerading.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://blog.zwindler.fr/2025/02/pve-network-2.avif"
loading="lazy"
&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src="https://blog.zwindler.fr/2025/02/pve-network-3.avif"
loading="lazy"
&gt;&lt;/p&gt;
&lt;p&gt;As long as we don&amp;rsquo;t click the &lt;strong&gt;Apply Configuration&lt;/strong&gt; button, we&amp;rsquo;re not &amp;ldquo;at risk&amp;rdquo;.&lt;/p&gt;
&lt;p&gt;The problem with the UI is that we&amp;rsquo;ll only be able to modify the IPs, gateways, and interfaces on the bridge or not. But to do the masquerading and have our virtual machines access the Internet, we need to add the famous iptables rules I&amp;rsquo;m talking about just before and we can&amp;rsquo;t do it from the UI.&lt;/p&gt;
&lt;p&gt;We&amp;rsquo;ll need to add the last five lines in the vmbr0 configuration&amp;hellip;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;cat /etc/network/interfaces
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;[&lt;/span&gt;...&lt;span class="o"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;auto vmbr0
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;iface vmbr0 inet static
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; address 10.10.10.1/24
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; bridge-ports none
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; bridge-stp off
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; bridge-fd &lt;span class="m"&gt;0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# add for masquerading to work&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; post-up &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt; &amp;gt; /proc/sys/net/ipv4/ip_forward
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; post-up iptables -t nat -A POSTROUTING -s &lt;span class="s1"&gt;&amp;#39;10.10.10.0/24&amp;#39;&lt;/span&gt; -o enp1s0 -j MASQUERADE
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; post-down iptables -t nat -D POSTROUTING -s &lt;span class="s1"&gt;&amp;#39;10.10.10.0/24&amp;#39;&lt;/span&gt; -o enp1s0 -j MASQUERADE
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; post-up iptables -t raw -I PREROUTING -i fwbr+ -j CT --zone &lt;span class="m"&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; post-down iptables -t raw -D PREROUTING -i fwbr+ -j CT --zone &lt;span class="m"&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;Warning&lt;/strong&gt;: the most important point is to verify that the output interface (-o) has the correct name. Here, my physical interface connected to the Internet is &lt;strong&gt;enp1s0&lt;/strong&gt;, but if yours has a different name, you need to adapt.&lt;/p&gt;
&lt;p&gt;From my point of view, the UI is still not completely useless, because it allows us to make the most delicate change (IP swap) with the visual diff and the &amp;ldquo;apply config&amp;rdquo; button. The post-up scripts are unlikely to cut off our access.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://blog.zwindler.fr/2025/02/pve-network-4.avif"
loading="lazy"
&gt;&lt;/p&gt;
&lt;h2 id="first-test"&gt;First Test
&lt;/h2&gt;&lt;p&gt;We&amp;rsquo;re far from done (it won&amp;rsquo;t fit in this article anyway, so might as well rush through&amp;hellip;). But I&amp;rsquo;m sure you&amp;rsquo;re eager to launch a VM and we should have something functional, though incomplete.&lt;/p&gt;
&lt;p&gt;So we&amp;rsquo;ll do a quick test of our setup to verify that we have a minimally functional hypervisor (meaning without clustering, without SDN, without firewall, without monitoring, without backup&amp;hellip; without anything, really).&lt;/p&gt;
&lt;p&gt;I started playing around with &lt;a class="link" href="https://blog.zwindler.fr/recherche/?keyword=talos" target="_blank" rel="noopener"
&gt;Talos Linux&lt;/a&gt; as a Linux distribution for Kubernetes. To keep it simple, I&amp;rsquo;ll launch the install of a Talos Node. If it manages to enroll in the Omni interface, it means I have a functional hypervisor, network included.&lt;/p&gt;
&lt;p&gt;Once the ISO is generated on my Omni site (the SaaS control plane from Sidero Labs, the publisher of Talos Linux), we can push it to our Proxmox VE.&lt;/p&gt;
&lt;p&gt;To do this, from our server (so not at the Datacenter level), we select a storage pool that accepts ISO images (if you remember correctly, our ZFS pool doesn&amp;rsquo;t support it by default), choose &lt;strong&gt;ISO Images&lt;/strong&gt;, and click &lt;strong&gt;Upload&lt;/strong&gt; to upload the ISO.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://blog.zwindler.fr/2025/02/iso.avif"
loading="lazy"
&gt;&lt;/p&gt;
&lt;p&gt;Once uploaded, we can now click the blue button at the top right &lt;strong&gt;Create VM&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://blog.zwindler.fr/2025/02/proxmox-create-01.avif"
loading="lazy"
&gt;&lt;/p&gt;
&lt;p&gt;From there, the VM creation wizard should take over. It&amp;rsquo;s going to be a bit verbose, but all menus are useful when you start to know Proxmox VE well. I&amp;rsquo;ll give you the minimum though:&lt;/p&gt;
&lt;p&gt;In the first menu, we won&amp;rsquo;t choose which node to install the VM on since for now we only have one&amp;hellip; However, we&amp;rsquo;ll have to give it a unique ID (100 by default) for the entire cluster. Ideally, we also give it a little name. I opted for talos02 (because I already have a talos01 on another server, see how original I am?).&lt;/p&gt;
&lt;p&gt;Finally, I checked the &amp;ldquo;Start at boot&amp;rdquo; box, that&amp;rsquo;s the kind of annoying thing when you forget to set it and the hypervisor reboots (it happens)&amp;hellip;&lt;/p&gt;
&lt;p&gt;You can give tags to your VMs, they&amp;rsquo;ll have nice colored badges to distinguish them :)&lt;/p&gt;
&lt;p&gt;&lt;img src="https://blog.zwindler.fr/2025/02/create-vm-1.avif"
loading="lazy"
&gt;&lt;/p&gt;
&lt;p&gt;In the second menu (OS), we need to indicate two things. First, that we want to use the ISO we just retrieved/uploaded to boot our machine (you need to choose the right storage pool, by default &amp;ldquo;local&amp;rdquo; is selected). We also need to give the OS type for driver compatibility reasons for virtual devices. It&amp;rsquo;s been a long time since we really needed that, &amp;ldquo;6.X - 2.6&amp;rdquo; works for all recent Linux (kernel 2.6 release was in 2003!).&lt;/p&gt;
&lt;p&gt;&lt;img src="https://blog.zwindler.fr/2025/02/create-vm-2.avif"
loading="lazy"
&gt;&lt;/p&gt;
&lt;p&gt;I skip System, in Disks, we add a disk on the right pool (so not local, but the one on ZFS). For my 32 GB Talos VM, that&amp;rsquo;s more than enough&amp;hellip; Note that there are many important options here for everything related to read/write &amp;ldquo;optimization&amp;rdquo;, but we&amp;rsquo;re well beyond the scope of this article.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://blog.zwindler.fr/2025/02/create-vm-3.avif"
loading="lazy"
&gt;&lt;/p&gt;
&lt;p&gt;I skip CPU and memory, the important thing is to give it at least 2 cores and 2 GB of RAM (at least). You can also optimize CPU performance by enabling the right flags, but again, we&amp;rsquo;re beyond the purpose of the article so I won&amp;rsquo;t insist.&lt;/p&gt;
&lt;p&gt;In the network section, we just make sure we&amp;rsquo;re connected to the right bridge (normally if you followed the article, we only have one, &lt;strong&gt;vmbr0&lt;/strong&gt;, so we can&amp;rsquo;t go wrong).&lt;/p&gt;
&lt;p&gt;&lt;img src="https://blog.zwindler.fr/2025/02/create-vm-4.avif"
loading="lazy"
&gt;&lt;/p&gt;
&lt;p&gt;And we verify everything is OK. Protip, to save five seconds in your life, click &amp;ldquo;Start after created&amp;rdquo;, which will start the VM as soon as possible after creation.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://blog.zwindler.fr/2025/02/create-vm-5.avif"
loading="lazy"
&gt;&lt;/p&gt;
&lt;h2 id="its-alive"&gt;It&amp;rsquo;s Alive?
&lt;/h2&gt;&lt;p&gt;At this point, the VM should automatically boot from the Talos CD and the OS should install on the disk. Once ready, the machine will try to enroll on my Omni control plane.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;And that&amp;rsquo;s when disaster strikes&amp;hellip;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Because yes, I haven&amp;rsquo;t configured DHCP or SDN. So we have to manually configure the virtual network card (which isn&amp;rsquo;t great), by pressing F3 in the console.&lt;/p&gt;
&lt;p&gt;(And suffering a bit of QWERTY, but that&amp;rsquo;s how you recognize a good sysadmin normally: they can do QWERTY in consoles)&lt;/p&gt;
&lt;p&gt;&lt;img src="https://blog.zwindler.fr/2025/02/talos02-config.avif"
loading="lazy"
&gt;&lt;/p&gt;
&lt;p&gt;Once the network is configured, the machine should almost instantly start configuring itself&amp;hellip;&lt;/p&gt;
&lt;p&gt;&lt;img src="https://blog.zwindler.fr/2025/02/talos02-booted.avif"
loading="lazy"
&gt;&lt;/p&gt;
&lt;p&gt;&amp;hellip; and enroll in Omni:&lt;/p&gt;
&lt;p&gt;&lt;img src="https://blog.zwindler.fr/2025/02/omni.avif"
loading="lazy"
&gt;&lt;/p&gt;
&lt;p&gt;Victory!!&lt;/p&gt;
&lt;h2 id="well"&gt;Well&amp;hellip;
&lt;/h2&gt;&lt;p&gt;Well&amp;hellip; yes, we have a functional VM. But I aspire to go a bit further before really declaring victory.&lt;/p&gt;
&lt;p&gt;As I said above, we had to configure our VM&amp;rsquo;s network by hand, and we don&amp;rsquo;t yet have clustering, firewalling, SDN, monitoring, or backup&amp;hellip; But we&amp;rsquo;re comfortably scratching 16,000 characters for this blog post, so it&amp;rsquo;s time to hang up and say &amp;ldquo;see you next time&amp;rdquo;.&lt;/p&gt;
&lt;p&gt;And in the meantime, have fun :)&lt;/p&gt;</description></item><item><title>Deploying a Proxmox VE 8 Cluster on Dedicated Servers (1/2)</title><link>https://blog.zwindler.fr/en/2025/01/27/deploying-a-proxmox-ve-8-cluster-on-dedicated-servers-1/2/</link><pubDate>Mon, 27 Jan 2025 20:00:00 +0000</pubDate><guid>https://blog.zwindler.fr/en/2025/01/27/deploying-a-proxmox-ve-8-cluster-on-dedicated-servers-1/2/</guid><description>&lt;img src="https://blog.zwindler.fr/2025/02/proxmox8.webp" alt="Featured image of post Deploying a Proxmox VE 8 Cluster on Dedicated Servers (1/2)" /&gt;&lt;p&gt;Note - this article is part of a series:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://blog.zwindler.fr/en/2025/01/27/deploying-a-proxmox-ve-8-cluster-on-dedicated-servers-1/2/" &gt;Deploying a Proxmox VE 8 Cluster on Dedicated Servers (1/4)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://blog.zwindler.fr/en/2025/02/17/deploying-a-proxmox-ve-8-cluster-on-dedicated-servers-2/3/" &gt;Deploying a Proxmox VE 8 Cluster on Dedicated Servers (2/4)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://blog.zwindler.fr/en/2025/03/25/deploying-a-proxmox-ve-8-cluster-on-dedicated-servers-3/4/" &gt;Deploying a Proxmox VE 8 Cluster on Dedicated Servers (3/4)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://blog.zwindler.fr/en/2025/03/30/proxmox-ve-8-tutorial-sdn-in-vxlan-mode-with-machines-on-the-internet/" &gt;Special Edition - SDN in VXLAN Mode with Machines on the Internet&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;And &lt;em&gt;at least&lt;/em&gt; one more to come&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="introduction"&gt;Introduction
&lt;/h2&gt;&lt;p&gt;Those who follow the &amp;ldquo;lore&amp;rdquo; of this blog know that I&amp;rsquo;m somewhat known in the Sunday tinkerer community for having written (or co-written) several tutorials on Proxmox VE. I&amp;rsquo;m thinking in particular of two article series on &lt;a class="link" href="https://blog.zwindler.fr/2017/07/11/deploiment-de-proxmox-ve-5-sur-un-serveur-dedie-part-1/" target="_blank" rel="noopener"
&gt;Proxmox VE 5&lt;/a&gt;, then &lt;a class="link" href="https://blog.zwindler.fr/2020/03/02/deploiement-de-proxmox-ve-6-pfsense-sur-un-serveur-dedie/" target="_blank" rel="noopener"
&gt;Proxmox VE 6&lt;/a&gt;, to create a virtualization cluster from scratch with Proxmox VE (and pfSense at the time).&lt;/p&gt;
&lt;p&gt;This is a new iteration of these tutorials, this time based on Proxmox VE 8, with quite a few things changing and new approaches.&lt;/p&gt;
&lt;p&gt;The ultimate goal of this article series is to have a virtualization platform with Proxmox VE. This platform will be composed of several machines (ideally 3, but 2 works too), secured, monitored, highly available, and backed up.&lt;/p&gt;
&lt;p&gt;You&amp;rsquo;ll need to follow several articles to achieve this.&lt;/p&gt;
&lt;h2 id="starting-assumptions"&gt;Starting Assumptions
&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;1-&lt;/strong&gt; I&amp;rsquo;m assuming you don&amp;rsquo;t have machines to do this at home and don&amp;rsquo;t want or can&amp;rsquo;t afford to invest in a homelab (&lt;a class="link" href="https://blog.zwindler.fr/recherche/?keyword=homelab" &gt;even though it can be a lot of fun, it requires investment&lt;/a&gt;). However, if you have machines at home, a large part of this article remains valid, once the machines are installed.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;2-&lt;/strong&gt; Since Proxmox VE is a virtualization platform, I&amp;rsquo;m also assuming you want &lt;strong&gt;dedicated&lt;/strong&gt; (physical) machines and not virtual machines, precisely to be able to virtualize entire OSes without too many problems (even though we always have the &amp;ldquo;nested virt&amp;rdquo; option, it&amp;rsquo;s less ideal).&lt;/p&gt;
&lt;p&gt;Note: if you don&amp;rsquo;t need virtualization (example: no Windows or special OS), Proxmox VE is a great containerization platform, particularly thanks to LXC, which allows you to create Linux containers with a full OS, that you can manage exactly like a VM but with much better performance (and some limitations due to kernel sharing, but it&amp;rsquo;s often sufficient). You can read &lt;a class="link" href="https://blog.zwindler.fr/recherche/?keyword=lxc" &gt;my articles on LXC&lt;/a&gt; if you&amp;rsquo;re interested.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;3-&lt;/strong&gt; I&amp;rsquo;d like to draw your attention to the fact that many actions could have been scripted or managed via &amp;ldquo;infrastructure as code&amp;rdquo;. It&amp;rsquo;s more in tune with the times, because it&amp;rsquo;s more robust and reliable. However, the point of this article is to do it &amp;ldquo;by hand&amp;rdquo; to understand what we&amp;rsquo;re doing, step by step, not just provide you with a &amp;ldquo;turnkey&amp;rdquo; infrastructure that you won&amp;rsquo;t know how to manage at the first hiccup.&lt;/p&gt;
&lt;p&gt;If you&amp;rsquo;re looking for more industrial methods to deploy virtualization clusters, you&amp;rsquo;ll surely find plenty on the Internet, from other bloggers (some French, some are even friends).&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;ve actually done the exercise myself several times with Ansible or &lt;a class="link" href="https://blog.zwindler.fr/recherche/?keyword=rudder" &gt;Rudder&lt;/a&gt; in the past, for example here (note: this code is obsolete):&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://blog.zwindler.fr/2019/07/22/proxmox-en-5-min-ansible-tinc/" &gt;A Proxmox VE cluster in 5 minutes with Ansible&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://github.com/zwindler/ansible-proxmoxve/tree/master" target="_blank" rel="noopener"
&gt;github.com/zwindler/ansible-proxmoxve&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Now that the objective and context is clear for everyone, we can begin :)&lt;/p&gt;
&lt;h2 id="choosing-the-machines"&gt;Choosing the Machines
&lt;/h2&gt;&lt;p&gt;Since we said we&amp;rsquo;re not self-hosting, we need to find a host that offers physical machines. Ideally, something not too expensive would be nice to start with.&lt;/p&gt;
&lt;p&gt;So we&amp;rsquo;re going to look for inexpensive machines BUT with support for VT-x / AMD-v instructions, which is pretty much all CPUs that still work today EXCEPT Atoms and ARM machines like Raspberry.&lt;/p&gt;
&lt;p&gt;Basically, that leaves us with Kimsufi at OVHCloud, Dedibox at Scaleway, and machines at Hetzner.&lt;/p&gt;
&lt;p&gt;At Hetzner for €45, you get an i5 gen13, 64 GB of RAM and 2 NVMe SSDs.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://blog.zwindler.fr/2025/02/hetzner.avif"
loading="lazy"
&gt;&lt;/p&gt;
&lt;p&gt;At OVHcloud, with a bit of luck, you can find machines around €15-20 per month with older hardware, but more than sufficient for what we&amp;rsquo;re going to do.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://blog.zwindler.fr/2025/02/ovhcloud.avif"
loading="lazy"
&gt;&lt;/p&gt;
&lt;p&gt;At Scaleway, the entry-level offer is centered on Atom Avoton or very old Xeons. The Avoton C2750 remains a valid option, as it&amp;rsquo;s an octa-core that supports VT-x (unlike the C2350, beware!). But well, it&amp;rsquo;s 2013 hardware 💀&amp;hellip;&lt;/p&gt;
&lt;p&gt;&lt;img src="https://blog.zwindler.fr/2025/02/scaleway.avif"
loading="lazy"
&gt;&lt;/p&gt;
&lt;p&gt;For the purposes of this article, I optimized costs and went with the OVHcloud server I present just above (KS-GAME-LE), unfortunately only available in Canada :(. But 8 threads and 16 GB of RAM for €12 including tax per month, that&amp;rsquo;s really not expensive.&lt;/p&gt;
&lt;p&gt;Two downsides:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;ridiculously small storage for virtualization (only 240 GB, a single disk)&lt;/li&gt;
&lt;li&gt;latency - almost 100 ms from my place, compared to 11 ms for my other machine at Scaleway&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;64 bytes from proxmox.example.org (203.0.113.78): icmp_seq=1 ttl=53 time=98.0 ms
64 bytes from proxmox.example.org (203.0.113.78): icmp_seq=2 ttl=53 time=97.5 ms
64 bytes from proxmox.example.org (203.0.113.78): icmp_seq=3 ttl=53 time=97.6 ms
64 bytes from proxmox.example.org (203.0.113.78): icmp_seq=4 ttl=53 time=97.7 ms
64 bytes from proxmox.example.org (203.0.113.78): icmp_seq=5 ttl=53 time=97.7 ms
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="os-installation"&gt;OS Installation
&lt;/h2&gt;&lt;p&gt;Once ordered, the server is relatively quickly available in your &amp;ldquo;OVH manager&amp;rdquo;. We have a fairly intuitive menu to directly install Proxmox VE 8, almost up to date (the provided images are rebuilt very regularly with all updates).&lt;/p&gt;
&lt;p&gt;To start the installation, click on the &amp;ldquo;&amp;hellip;&amp;rdquo; in the Operating System (OS) section, then select install from an OVH template&lt;/p&gt;
&lt;p&gt;&lt;img src="https://blog.zwindler.fr/2025/02/install01.avif"
loading="lazy"
&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src="https://blog.zwindler.fr/2025/02/install02.avif"
loading="lazy"
&gt;&lt;/p&gt;
&lt;p&gt;Scroll through the list of OS types, select Virtualization, then Proxmox VE 8 (while we&amp;rsquo;re at it). I also checked the &amp;ldquo;Customize partition configuration&amp;rdquo; box, because by default, OVH&amp;rsquo;s installation uses &amp;ldquo;LVM thick&amp;rdquo; type storage for most of the disk space, while we&amp;rsquo;ll use advanced ZFS features later:&lt;/p&gt;
&lt;p&gt;&lt;img src="https://blog.zwindler.fr/2025/02/install03.avif"
loading="lazy"
&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src="https://blog.zwindler.fr/2025/02/install04.avif"
loading="lazy"
&gt;&lt;/p&gt;
&lt;p&gt;Before validating the installation, don&amp;rsquo;t forget to change its name (Custom hostname) to avoid having to do it post-install, then add a public SSH key:&lt;/p&gt;
&lt;p&gt;&lt;img src="https://blog.zwindler.fr/2025/02/install05.avif"
loading="lazy"
&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src="https://blog.zwindler.fr/2025/02/install06.avif"
loading="lazy"
&gt;&lt;/p&gt;
&lt;h2 id="first-post-installation-tasks-upgrade-and-reboot"&gt;First Post-Installation Tasks: Upgrade and Reboot
&lt;/h2&gt;&lt;p&gt;There&amp;rsquo;s a whole series of things to do when you&amp;rsquo;ve just installed a machine, especially on Proxmox VE, and we&amp;rsquo;ll try to resist the urge to &amp;ldquo;quickly&amp;rdquo; connect to the graphical interface.&lt;/p&gt;
&lt;p&gt;Anyway, we won&amp;rsquo;t be able to connect to the Proxmox VE graphical interface&amp;hellip;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Really???&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Yes, because while we can normally connect with the &lt;code&gt;root&lt;/code&gt; user of our Linux, we won&amp;rsquo;t be able to in the case of OVHcloud, simply because we DON&amp;rsquo;T have the root password. Good thing we added an SSH key ;)&lt;/p&gt;
&lt;p&gt;We&amp;rsquo;ll come back to it later, we have more urgent things to do.&lt;/p&gt;
&lt;p&gt;The first thing I did was immediately add a type A DNS record so that my machine&amp;rsquo;s IP corresponds to an FQDN. For this article, I&amp;rsquo;ll refer to it as follows:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;hostname: myPVEhost&lt;/li&gt;
&lt;li&gt;FQDN: proxmox.example.org&lt;/li&gt;
&lt;li&gt;IP: 203.0.113.159&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src="https://blog.zwindler.fr/2025/02/dns_ovh.avif"
loading="lazy"
&gt;&lt;/p&gt;
&lt;p&gt;So we connect to our freshly installed machine&amp;rsquo;s IP via SSH (root@IPmachine) and we&amp;rsquo;ll take the opportunity to do some cleanup.&lt;/p&gt;
&lt;p&gt;The first thing to do is update the server, ideally followed by a reboot:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;apt update &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; apt upgrade -y &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; reboot
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Once the server is back to life, we reconnect and enable automatic updates in one way or another. The simplest is to use &lt;code&gt;unattended-upgrades&lt;/code&gt; if it&amp;rsquo;s not installed by default (it may already be there) but there are more sophisticated tools.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;apt install unattended-upgrades
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="its-for-security"&gt;It&amp;rsquo;s for Security
&lt;/h2&gt;&lt;p&gt;Once that&amp;rsquo;s done, I recommend installing CrowdSec right away. Here, I simply based myself on the official crowdsec documentation, to add the detection engine, the remediation component (here via &lt;code&gt;iptables&lt;/code&gt;):&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://doc.crowdsec.net/u/getting_started/installation/linux" target="_blank" rel="noopener"
&gt;CrowdSec.net - Linux Installation&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;curl -s https://install.crowdsec.net &lt;span class="p"&gt;|&lt;/span&gt; sudo sh
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;apt install crowdsec
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# verify that the crowdsec service is working&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;systemctl status crowdsec
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;● crowdsec.service - Crowdsec agent
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; Loaded: loaded &lt;span class="o"&gt;(&lt;/span&gt;/lib/systemd/system/crowdsec.service&lt;span class="p"&gt;;&lt;/span&gt; enabled&lt;span class="p"&gt;;&lt;/span&gt; preset: enabled&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; Active: active &lt;span class="o"&gt;(&lt;/span&gt;running&lt;span class="o"&gt;)&lt;/span&gt; since Sun 2025-01-26 21:04:26 UTC&lt;span class="p"&gt;;&lt;/span&gt; 1min 56s ago
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; Process: &lt;span class="m"&gt;73830&lt;/span&gt; &lt;span class="nv"&gt;ExecStartPre&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;/usr/bin/crowdsec -c /etc/crowdsec/config.yaml -t -error &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;code&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;exited, &lt;span class="nv"&gt;status&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;0/SUCCESS&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; Main PID: &lt;span class="m"&gt;73862&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;crowdsec&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; Tasks: &lt;span class="m"&gt;13&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;limit: 19059&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; Memory: 33.1M
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; CPU: 2.571s
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; CGroup: /system.slice/crowdsec.service
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ├─73862 /usr/bin/crowdsec -c /etc/crowdsec/config.yaml
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; └─73877 journalctl --follow -n &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="nv"&gt;_SYSTEMD_UNIT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;ssh.service
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Jan &lt;span class="m"&gt;26&lt;/span&gt; 21:04:23 myPVEhost systemd&lt;span class="o"&gt;[&lt;/span&gt;1&lt;span class="o"&gt;]&lt;/span&gt;: Starting crowdsec.service - Crowdsec agent...
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Jan &lt;span class="m"&gt;26&lt;/span&gt; 21:04:26 myPVEhost systemd&lt;span class="o"&gt;[&lt;/span&gt;1&lt;span class="o"&gt;]&lt;/span&gt;: Started crowdsec.service - Crowdsec agent.
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# install the remediation engine&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;apt install crowdsec-firewall-bouncer
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Once Crowdsec is operational, we can add the &amp;ldquo;fulljackz/proxmox&amp;rdquo; collection, which we&amp;rsquo;ll need to modify (thanks to Julien Louis&amp;rsquo;s great article on his slash-root.fr blog), which will listen to the webUI logs to detect any brute force and ban those who try:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://app.crowdsec.net/hub/author/fulljackz/collections/proxmox" target="_blank" rel="noopener"
&gt;https://app.crowdsec.net/hub/author/fulljackz/collections/proxmox&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://slash-root.fr/crowdsec-proteger-lauthentification-proxmox/" target="_blank" rel="noopener"
&gt;slash-root.fr - CrowdSec: Protect Proxmox authentication&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;cscli collections install fulljackz/proxmox
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;[&lt;/span&gt;...&lt;span class="o"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;INFO Enabled fulljackz/proxmox
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;INFO Run &lt;span class="s1"&gt;&amp;#39;sudo systemctl reload crowdsec&amp;#39;&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; the new configuration to be effective.
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The pattern listened to by the proxmox parser is no longer correct with new versions&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-console" data-lang="console"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;Jan 26 21:23:14 myPVEhost pvedaemon[1250]: authentication failure; rhost=::ffff:203.0.113.159.78 user=coucou@pve msg=no such user (&amp;#39;coucou@pve&amp;#39;)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;We see here that Julien added the &amp;ldquo;::ffff:&amp;rdquo; prefix in the &lt;strong&gt;PVE_AUTH_FAIL&lt;/strong&gt; variable of the &lt;code&gt;/etc/crowdsec/parsers/s01-parse/proxmox-logs.yaml&lt;/code&gt; file, but when I look at the test cases provided in the collection, it seems like it&amp;rsquo;s not necessary&amp;hellip;&lt;/p&gt;
&lt;p&gt;In any case, we&amp;rsquo;ll create a &lt;code&gt;/etc/crowdsec/acquis.d/proxmox.yaml&lt;/code&gt; file so that CrowdSec can start analyzing our logs:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;mkdir -p /etc/crowdsec/acquis.d/
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;cat &amp;gt; /etc/crowdsec/acquis.d/proxmox.yaml &lt;span class="s"&gt;&amp;lt;&amp;lt;EOF
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;journalctl_filter:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; - _SYSTEMD_UNIT=pvedaemon.service
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;labels:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; type: syslog
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;EOF&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;We finish by reloading crowdsec and watching &lt;del&gt;the world burn&lt;/del&gt; script kiddies get blocked.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;systemctl reload crowdsec
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;cscli alerts list
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;╭────┬────────────────────┬───────────────────────────┬─────────┬──────────────────────────────────────────────────────────────┬───────────┬─────────────────────────────────────────╮
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ ID │ value │ reason │ country │ as │ decisions │ created_at │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;├────┼────────────────────┼───────────────────────────┼─────────┼──────────────────────────────────────────────────────────────┼───────────┼─────────────────────────────────────────┤
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ &lt;span class="m"&gt;2&lt;/span&gt; │ Ip:203.0.113.222 │ crowdsecurity/ssh-slow-bf │ IR │ &lt;span class="m"&gt;202468&lt;/span&gt; Gloubi Bo ulgua Co. &lt;span class="o"&gt;(&lt;/span&gt; Private Joint Stock&lt;span class="o"&gt;)&lt;/span&gt; │ ban:1 │ 2025-01-26 22:31:15.366187524 +0000 UTC │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;╰────┴────────────────────┴───────────────────────────┴─────────┴──────────────────────────────────────────────────────────────┴───────────┴─────────────────────────────────────────╯
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="nagging-popup"&gt;Nagging Popup
&lt;/h2&gt;&lt;p&gt;Among the little annoying things shipped by default with Proxmox VE, there used to be the fact that Proxmox VE had enterprise apt repositories on all installations, and it was necessary to manually disable them before being able to do updates.&lt;/p&gt;
&lt;p&gt;It was super annoying and the Proxmox VE developers heard (a little) their community and removed this requirement&amp;hellip; to replace it with a popup.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://blog.zwindler.fr/2025/02/nagging_popup.avif"
loading="lazy"
&gt;&lt;/p&gt;
&lt;p&gt;Now, a popup, I&amp;rsquo;m fine with that! It&amp;rsquo;s important to reward developers&amp;rsquo; work and support them. But is it really necessary to do it &lt;strong&gt;at every login&lt;/strong&gt; AND &lt;strong&gt;every time we refresh the list of packages to update&lt;/strong&gt;?&lt;/p&gt;
&lt;p&gt;This is obviously a rhetorical question.&lt;/p&gt;
&lt;p&gt;Obviously, many people have found several methods to disable the responsible JS code. Big up to &lt;a class="link" href="https://blog.zwindler.fr/authors/fabio/" target="_blank" rel="noopener"
&gt;fabio&lt;/a&gt; for his version that works well.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sed -Ezi.bak &lt;span class="s2"&gt;&amp;#34;s/(function\(orig_cmd\) \{)/\1\n\torig_cmd\(\);\n\treturn;/g&amp;#34;&lt;/span&gt; /usr/share/javascript/proxmox-widget-toolkit/proxmoxlib.js &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; systemctl restart pveproxy.service
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Note: if like me you&amp;rsquo;ve already connected once, you&amp;rsquo;ll also need to clear the cache otherwise the popup will remain&amp;hellip;&lt;/p&gt;
&lt;h2 id="creating-groups-and-users-for-the-graphical-interface"&gt;Creating Groups and Users for the Graphical Interface
&lt;/h2&gt;&lt;blockquote&gt;
&lt;p&gt;Ok ok, we&amp;rsquo;ve done a lot of stuff, can we connect now???&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Yes yes, we can. Anyway, I&amp;rsquo;m already at almost 15,000 characters, this article is way too long, we need to wrap up.&lt;/p&gt;
&lt;p&gt;Last step in this article, we&amp;rsquo;ll create an administrator to connect to the UI and a user that we&amp;rsquo;ll use later for monitoring.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# you&amp;#39;re not **really** obligated to call the admin &amp;#34;zwindler&amp;#34; you know?&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;pveum group add admin -comment &lt;span class="s2"&gt;&amp;#34;System Administrators&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;pveum acl modify / -group admin -role Administrator
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;pveum useradd zwindler@pve
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;pveum usermod zwindler@pve -group admin
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;pveum passwd zwindler@pve
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# our monitoring user&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;pveum groupadd monitoring -comment &lt;span class="s1"&gt;&amp;#39;Monitoring group&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;pveum aclmod / -group monitoring -role PVEAuditor
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;pveum useradd pve_exporter@pve
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;pveum usermod pve_exporter@pve -group monitoring
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;pveum passwd pve_exporter@pve
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Alright, you&amp;rsquo;ve waited long enough, you can connect to your Proxmox VE! Go to:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;https://@IPmachine:8006
or&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://proxmox.example.org:8006" target="_blank" rel="noopener"
&gt;https://proxmox.example.org:8006&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Note: for now, the certificate is self-signed and the browser will show an error. We can accept to ignore the problem for now.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://blog.zwindler.fr/2025/02/pve_login.avif"
loading="lazy"
&gt;&lt;/p&gt;
&lt;p&gt;Don&amp;rsquo;t forget to change the &amp;ldquo;realm&amp;rdquo; from PAM (unix users, which we&amp;rsquo;re not using here) to &amp;ldquo;Proxmox&amp;rdquo; to be able to use the administrator we just created.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://blog.zwindler.fr/2025/02/proxmox8.avif"
loading="lazy"
&gt;&lt;/p&gt;
&lt;p&gt;See you soon for the next part. And in the meantime, have fun!&lt;/p&gt;</description></item><item><title>Should we have containers ?</title><link>https://blog.zwindler.fr/en/2016/08/25/should-we-have-containers/</link><pubDate>Thu, 25 Aug 2016 16:00:21 +0000</pubDate><guid>https://blog.zwindler.fr/en/2016/08/25/should-we-have-containers/</guid><description>&lt;img src="https://blog.zwindler.fr/2016/08/Fullvirt_containers.webp" alt="Featured image of post Should we have containers ?" /&gt;&lt;h2 id="a-more-complete-answer-to-why-do-we-have-containers-by-fntlnz"&gt;A more complete answer to « Why do we have containers » by fntlnz
&lt;/h2&gt;&lt;p&gt;2 days ago, I stumbled apon &lt;em&gt;fntlnz&lt;/em&gt; article &lt;a class="link" href="https://web.archive.org/web/20161026190150/http://blog.fntlnz.wtf/post/why-containers/" target="_blank" rel="noopener"
&gt;Why do we have containers. (dead link, using Internet Archive)&lt;/a&gt; The article had been reposted by Docker official Twitter account and the first thing that struck me was the displayed image : a schema comparing full virtualization, para virtualization and linux containers.&lt;/p&gt;
&lt;p&gt;And of course, I say this because I didn’t entirely agree with it ;-). But then I read the article and I found many good points.&lt;/p&gt;
&lt;p&gt;So I decided to write « Should we have containers ? » as an answer to develop my remarks a little.&lt;/p&gt;
&lt;h2 id="full-virtualization-vs-paravirtualization-vs-os-level-virtualization"&gt;Full virtualization vs paravirtualization vs OS level virtualization
&lt;/h2&gt;&lt;p&gt;First, I’ll go with the schema. I know the point was to provide a really simple schema to help understand the differences between virtualization types but I don’t think it should be presented like that.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://blog.zwindler.fr/2016/08/Virtualization.avif"
loading="lazy"
&gt;&lt;/p&gt;
&lt;p&gt;Hypervisor and host OS are both displayed in the full/para. I find this be misleading. Of course there is a Host OS and a virtualization engine on top of it. But most of the time, either the OS is really thin (ESXi fits in 8GB SD cards and runs nothing but virtualization) or the virt engine is a part of the kernel (KVM, Xen) just like LXC is a part of the Linux kernel.&lt;/p&gt;
&lt;p&gt;Also, the bins/libs are only displayed on OS level virt. This is interesting to put in the « host level virtualization schema » but it should be added on full and para as well because this is one of the advantages host level virt. has over full/para.&lt;br&gt;
Even if your VMs are all identicals, bins and libs have to be present (copied) in each VMs. On contrary, in OS Level virt, you CAN share identicals bins/libs between containers, thus reducing the storage footprint of the virtualized environment.&lt;/p&gt;
&lt;p&gt;That’s how I would have presented it&lt;/p&gt;
&lt;p&gt;&lt;img src="https://blog.zwindler.fr/2016/08/Fullvirt_containers.avif"
loading="lazy"
&gt;&lt;/p&gt;
&lt;p&gt;You can see that OS level virtualization and Hypervisors are not so different on this simplified view. The differences appear more clearly when you add x86 Security Rings (0-&amp;gt;3). The « overhead » of full virtualization comes from the calls that guest OSes do to hypervisor pilots and the translation of CPU instructions.&lt;/p&gt;
&lt;p&gt;On a side note, I put Docker on the left to show that it’s basically an administration suite that helps you run LXC containers&lt;/p&gt;
&lt;h2 id="the-rest-of-the-analysis"&gt;The rest of the analysis
&lt;/h2&gt;&lt;h3 id="security"&gt;Security
&lt;/h3&gt;&lt;p&gt;When talking about containers, the security point is often raised.&lt;/p&gt;
&lt;p&gt;VMs are really hermetics. Taking control of the hypervisor after hacking a VM should be MUCH harder than taking control of the host OS if you are inside a container with whom the kernel is shared.&lt;/p&gt;
&lt;p&gt;But I agree with &lt;strong&gt;fntlnz&lt;/strong&gt;: having to patch only one kernel for all your virtual environments instead of having to patch ALL kernels of your virtual machines is actually a good point.&lt;/p&gt;
&lt;p&gt;I encourage you to read &lt;a class="link" href="https://web.archive.org/web/20200925215559/https://2015.rmll.info/IMG/pdf/containers_docker_and_security__state_of_the_union.pdf" target="_blank" rel="noopener"
&gt;this (dead link, using Internet Archive)&lt;/a&gt; from Jérôme Petazzoni if you’d like a good presentation on the subject.&lt;/p&gt;
&lt;h3 id="performance"&gt;Performance
&lt;/h3&gt;&lt;p&gt;A point that’s not really developed in &lt;em&gt;fntlnz&lt;/em&gt; article is performance, but I read it/ear it &lt;strong&gt;all the time&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;General belief is that VMs are slow. That was true in the « early days » of x86 virtualization, because of the limitations of the x86 architectures which didn’t allow efficient OS virtualisation. Overhead for CPU instructions was known to be of about 15% (which is enormous). Thus, running processes directly on the OS are believed to be more efficent.&lt;/p&gt;
&lt;p&gt;But nowadays, modern hypervisors on modern hardware nearly generates no overhead at all over CPU and RAM consumption. You could argue that guest OSes consume ressources while containers don’t. But let’s be honest: with the 32 GB RAM tomcat instances I regularly see, don’t say to me that a Linux guest OS CPU&amp;amp;RAM consumption is significative.&lt;/p&gt;
&lt;p&gt;The real difference is the on the storage consumption. First, for N VMs, you save yourself N*xGB of guest OS files. If your Linux templates are good, you don’t consume that much (a few GB at most) but this can add up when we are talking about thousands of instances. [Edit jan. 2020]Not so true today if you host your own hardware and have so deduplicated storage[/Edit]&lt;/p&gt;
&lt;p&gt;From there, you still have some margin for gains, mostly through &lt;strong&gt;Copy on write and union filesystems&lt;/strong&gt; :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;You make a modification to an official tomcat image to add you configuration files ? Only the delta will be stored.&lt;/li&gt;
&lt;li&gt;You launch thousands of containers from this image ? You only consume the container image once.&lt;/li&gt;
&lt;li&gt;The real data (user data, business data) is of course the same for both architectures&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="so-should-i-use-containers-"&gt;So, should I use containers ?
&lt;/h2&gt;&lt;p&gt;The problem here is that’s not the real question. &lt;strong&gt;Do you need containers ?&lt;/strong&gt; Here’s &lt;em&gt;fntlnz&lt;/em&gt; point of view.**&lt;br&gt;
**&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;But if at some extent your motivation consist in &lt;strong&gt;decreasing costs related to full virtualization overheads&lt;/strong&gt; while allowing &lt;strong&gt;developers to ship, develop and test code faster&lt;/strong&gt; we already found two.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;fntlnz&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p&gt;I won’t tell you not to use containers or Docker. Truth be told, we use it in dev and production. Docker is awesome.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Yes, Docker reduces overhead of full virtualization. Storage mostly, but it highly depends on your workload. For example if you have the need for millions of really tiny instances, then Guest OS overhead is significative  in full virtualization.&lt;/li&gt;
&lt;li&gt;Yes, Docker allows developers to ship, develop and test code faster. You still have to change your way to develop yours app but Docker and DevOps is the new thing. Better get on with it ;)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;But you shouldn’t use Docker just because of that. Docker containers need you to change your philosophy toward applications and administration.&lt;/p&gt;
&lt;h3 id="shared-kernel--same-kernel-"&gt;Shared kernel = same kernel~~ ~~
&lt;/h3&gt;&lt;p&gt;You need to understand that you’ll share a kernel. For a long time that ment a 100% Linux only which could be problematic in some cases. I just realized that Windows containers exists in Windows 2016 tech preview. And Solaris is coming.&lt;/p&gt;
&lt;p&gt;But independantly of platforms, you still you share a kernel. If you want Linux containers, you’ll need Linux Docker nodes. If you need Windows containers, you’ll have to have Windows Docker nodes.&lt;/p&gt;
&lt;h3 id="non-persistantcloud-ready-instances"&gt;Non-persistant/cloud-ready instances
&lt;/h3&gt;&lt;p&gt;Docker containers are by design non-persistant and by best practice single-process. This isn’t mandatory of course, but Docker works better that way.&lt;/p&gt;
&lt;p&gt;The whole idea is to help you make « cloud-ready » &amp;amp; atomic applications that don’t store anything in the container itself (persistant storage is presented to the container but outside it). This way, you can scale out really quickly: you just start up a few more instances if you need more firepower.&lt;/p&gt;
&lt;p&gt;This also modifies the way you do systems/applications administration. A container/application is spinning out of control ? Don’t try to repair it.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Kill it&lt;/li&gt;
&lt;li&gt;Launch a new one&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The fact that persistant storage is handled outside the containers also helps you to deal with lifecycle management.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Update your application inside the docker image&lt;/li&gt;
&lt;li&gt;Shutdown the old container&lt;/li&gt;
&lt;li&gt;Start the new container with the new image, plugged to the persistant storage&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;All that requires of course applications that have been designed this way! This is a massive change in philosophy and old monolithic apps on a Docker platform won’t work as well as microservices will.&lt;/p&gt;
&lt;h3 id="system-administration"&gt;System administration
&lt;/h3&gt;&lt;p&gt;I don’t say solutions don’t exist because they do.&lt;/p&gt;
&lt;p&gt;But starting up and shutting down containers on the fly will give headaches to your « old school Nagios » monitoring administrator. What could be done easily in the physical/VM world (installing an agent in the template), each of those having an IP adress to query for health checks is a lot easier than checking on a single host a highly volatile number of isolated processes.&lt;/p&gt;
&lt;p&gt;You’ll probably have to adapt and use tools that are designed to handle such cases.&lt;/p&gt;
&lt;p&gt;Backup administrator may find it confusing at first to make application consistant data backups when applications are running in an variable number of containers.&lt;/p&gt;
&lt;p&gt;And so on&amp;hellip;&lt;/p&gt;
&lt;h2 id="final-thoughts"&gt;Final thoughts
&lt;/h2&gt;&lt;p&gt;Yes, you should definitely &lt;em&gt;look into&lt;/em&gt; containers. They are mature, stable, a great new way to speed up development and contribute to save money on hardware.&lt;/p&gt;
&lt;p&gt;But be aware that VMs and containers don’t answer all usecases; and that you won’t migrate all your applications overnight!&lt;/p&gt;</description></item></channel></rss>