<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>Virtualization on Frank&#39;s Blog</title>
    <link>https://frankblogs.com/tags/virtualization/</link>
    <description>Recent content in Virtualization on Frank&#39;s Blog</description>
    <generator>Hugo -- 0.150.0</generator>
    <language>en-us</language>
    <lastBuildDate>Mon, 06 Oct 2025 21:32:45 +0800</lastBuildDate>
    <atom:link href="https://frankblogs.com/tags/virtualization/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>The Router VM Saga: OpenWrt vs. iStoreOS &amp; The Great Migration</title>
      <link>https://frankblogs.com/posts/article-5/</link>
      <pubDate>Mon, 06 Oct 2025 21:32:45 +0800</pubDate>
      <guid>https://frankblogs.com/posts/article-5/</guid>
      <description>With PVE running, it was time to create the router VM. This post details my struggles with vanilla OpenWrt, the dependency hell, and the eventual, crucial decision to migrate to the pre-integrated iStoreOS.</description>
      <content:encoded><![CDATA[<p>My Proxmox VE (PVE) hypervisor was installed and the host networking configured on my N100 box. Now it was time to create the core component: the virtual machine that would act as my main home router. My initial plan was to use vanilla <strong>OpenWrt</strong>, the classic, highly customizable Linux distribution for routers.</p>
<h2 id="act-i-the-struggles-with-vanilla-openwrt">Act I: The Struggles with Vanilla OpenWrt</h2>
<p>Creating the VM in PVE (giving it VM ID 100) involved several steps:</p>
<ol>
<li><strong>Download Firmware:</strong> Get the official OpenWrt x86-64 combined-ext4 image (<code>.img.gz</code>).</li>
<li><strong>Upload &amp; Import:</strong> Upload the <code>.img.gz</code> file to PVE (e.g., via SCP or the web UI&rsquo;s storage browser – note: uploading directly as an ISO image type fails). Import the disk image into the VM using <code>qm importdisk 100 openwrt.img.gz local-lvm</code>.</li>
<li><strong>VM Hardware Config:</strong> Assign CPU cores, RAM. Remove the default SCSI disk. Attach the imported OpenWrt disk as a VirtIO block device. Add two VirtIO network cards – one connected to PVE&rsquo;s <code>vmbr0</code> (WAN) and one to <code>vmbr1</code> (LAN). Set the boot order to use the OpenWrt disk.</li>
<li><strong>Disk Resizing:</strong> The default image is tiny. Resize the virtual disk in PVE&rsquo;s hardware tab. Boot the VM with a GParted Live ISO attached, use GParted to expand the OpenWrt partition to fill the larger virtual disk.</li>
<li><strong>Initial Network Config:</strong> Boot OpenWrt. Access the console (via PVE&rsquo;s web UI or <code>qm terminal 100</code> - not <code>qm console</code>). Use the <code>vi</code> editor to modify <code>/etc/config/network</code>, changing the LAN interface&rsquo;s IP address to <code>10.0.0.1</code>.</li>
</ol>
<p>So far, so good. I could access the OpenWrt LuCI web interface at <code>10.0.0.1</code>. I configured PPPoE on <code>eth1</code> (WAN, connected to <code>vmbr0</code>) and set up the LAN interface (<code>eth0</code>, connected to <code>vmbr1</code>) with DHCP and IPv6 server settings. Basic routing worked!</p>
<h3 id="the-dependency-hell">The Dependency Hell</h3>
<p>The problems began when I tried to customize OpenWrt by installing packages. My goal was simple: install <code>luci-app-adguardhome</code>. But <code>opkg update</code> often failed to connect to the repositories. When it did connect, attempting to install AdGuard Home resulted in a cascade of errors about <strong>incompatible architectures</strong> or missing dependencies (<code>luci-lua-runtime</code> was a frequent culprit). Even manually downloading <code>.ipk</code> packages failed with similar architecture errors.</p>
<p>I spent hours trying different package versions, compiling dependencies, and scouring forums. I even managed to &ldquo;force install&rdquo; some packages, but this led to a broken LuCI interface – the &ldquo;Services&rdquo; menu simply wouldn&rsquo;t appear, despite the package seemingly being installed.</p>
<p>[<strong>Placeholder: Add a screenshot of the terminal showing the <code>opkg</code> errors or the LuCI interface missing the Services menu.</strong>]</p>
<p>Clearing LuCI caches (<code>rm /tmp/luci-indexcache</code>) did nothing. Log files (<code>logread</code>) showed no obvious errors. File permissions seemed correct. The final nail in the coffin was a detailed error log clearly stating that key LuCI components and their dependencies were fundamentally incompatible with the base system. Trying to manually build a complex setup on vanilla OpenWrt felt like assembling a car from mismatched parts found in a junkyard.</p>
<h2 id="act-ii-the-turn-towards-istoreos">Act II: The Turn Towards iStoreOS</h2>
<p>Frustrated and realizing the &ldquo;DIY package management&rdquo; route was unsustainable, I revisited earlier advice: use a <strong>pre-integrated firmware</strong> like <strong>iStoreOS</strong>. Based on OpenWrt but comes with a user-friendly interface and, crucially, a curated app store where dependencies <em>should</em> just work.</p>
<h3 id="the-migration-plan">The Migration Plan</h3>
<p>The challenge: perform this migration without disrupting my family&rsquo;s internet access for too long.</p>
<ol>
<li><strong>Preparation:</strong> In PVE, create a <em>new</em> VM (e.g., VM ID 101) for iStoreOS. Download the iStoreOS x86 <code>.img.gz</code> firmware.</li>
<li><strong>Import &amp; Basic Config:</strong> Upload and import the iStoreOS disk into VM 101. Configure its hardware similarly to the OpenWrt VM (CPU, RAM, 2x VirtIO NICs connected to <code>vmbr0</code> and <code>vmbr1</code>).</li>
<li><strong>Offline Config Attempt (Failed):</strong> Boot VM 101 with GParted. Try to mount the iStoreOS partition to change the default IP (<code>192.168.100.1</code>) to <code>10.0.0.1</code> offline. <strong>Failure!</strong> GParted couldn&rsquo;t identify the filesystem. Manual <code>mount</code> commands failed, complaining about unknown filesystem types or missing superblocks. Offline config was impossible.</li>
<li><strong>The Switch:</strong> Plan B - configure online. Physically disconnect the WAN cable from the N100. Shut down the old OpenWrt VM (100). Start the new iStoreOS VM (101). Set my Mac&rsquo;s IP statically to <code>192.168.100.5</code>. Connect my Mac to one of the N100&rsquo;s LAN ports (connected to <code>vmbr1</code>). Try accessing <code>192.168.100.1</code>.</li>
</ol>
<h3 id="the-wanlan-inversion-twist">The WAN/LAN Inversion Twist</h3>
<p>Failure again! <code>192.168.100.1</code> was unreachable. In a moment of desperation (or maybe just random plugging), I moved my Mac&rsquo;s cable to the N100 port I had designated for <strong>WAN</strong> (connected to <code>vmbr0</code>). And&hellip; success! I reached the iStoreOS login page.</p>
<p><strong>Diagnosis:</strong> iStoreOS had, for some reason, <strong>reversed</strong> the network interface identification compared to OpenWrt. It saw <code>eth0</code> (connected to PVE&rsquo;s <code>vmbr1</code>, my LAN bridge) as its <em>WAN</em> interface, and <code>eth1</code> (connected to PVE&rsquo;s <code>vmbr0</code>, my WAN bridge) as its <em>LAN</em> interface, assigning the <code>192.168.100.1</code> address there.</p>
<p><strong>Resolution:</strong> Logged into iStoreOS via the &ldquo;wrong&rdquo; port. Navigated to <code>Network -&gt; Interfaces</code>. Edited the LAN and WAN interfaces, <strong>swapping</strong> their assigned physical devices (<code>eth0</code> &lt;-&gt; <code>eth1</code>). Saved and applied. Moved my Mac&rsquo;s cable back to a correct LAN port. Set my Mac back to DHCP. Accessed <code>192.168.100.1</code> (the default iStore IP). Success! Changed the iStoreOS LAN IP to <code>10.0.0.1</code>. Plugged the WAN cable back into the N100&rsquo;s WAN port.</p>
<p>The network migration was complete in under 15 minutes. The foundation was finally stable. iStoreOS provided the pre-packaged environment I needed. Now, it was time to deploy the services that started this whole journey.</p>
]]></content:encoded>
    </item>
    <item>
      <title>Proxmox VE Initiation: Taming the Virtualization Hypervisor</title>
      <link>https://frankblogs.com/posts/article-4/</link>
      <pubDate>Wed, 01 Oct 2025 21:30:18 +0800</pubDate>
      <guid>https://frankblogs.com/posts/article-4/</guid>
      <description>With my N100 soft router hardware assembled, the next step was installing Proxmox VE (PVE). This post covers the installation process and my first major challenge: configuring PVE networking without losing access.</description>
      <content:encoded><![CDATA[<p>The N100 hardware for my new soft router/home server was assembled and ready. The grand vision involved virtualization, allowing this single machine to run my router, NAS, and potentially other services simultaneously. The chosen foundation for this was <strong>Proxmox Virtual Environment (PVE)</strong>, a powerful, open-source hypervisor based on Debian Linux.</p>
<h2 id="installing-pve-the-first-hurdle">Installing PVE: The First Hurdle</h2>
<p>Installing PVE itself is relatively straightforward, similar to installing any Linux distribution:</p>
<ol>
<li><strong>Create Installation Media:</strong> Download the PVE ISO image. On my Mac, I used <strong>Balena Etcher</strong> to write the ISO to a USB drive. My first attempt failed – turns out the old USB drive I grabbed was faulty. A newer drive worked perfectly.</li>
<li><strong>Boot from USB:</strong> Connect a monitor and keyboard to the N100 box, plug in the USB drive, and boot into the BIOS/UEFI settings (usually by pressing DEL or F2 during startup). Set the USB drive as the primary boot device.</li>
<li><strong>PVE Installer:</strong> Follow the graphical installer prompts. Key settings during installation:
<ul>
<li>Target Hard Disk: Select the Fanxiang NVMe SSD.</li>
<li>Location/Timezone: Set appropriately.</li>
<li>Hostname: Set to something memorable, like <code>pve.local</code>.</li>
<li>Network Configuration: <strong>Crucially</strong>, assign a <strong>static IP address</strong> for PVE&rsquo;s management interface (e.g., <code>10.0.0.2</code>), along with the gateway (<code>10.0.0.1</code> - my eventual router VM&rsquo;s address) and DNS servers. I chose one of the four physical ports (e.g., <code>enp1s0</code>) for this initial management access.</li>
</ul>
</li>
</ol>
<p>The installation completed smoothly, and PVE rebooted. I could access the command line directly on the N100, and more importantly, access the web UI from my Mac at <code>https://10.0.0.2:8006</code>. Stage one complete!</p>
<h2 id="the-networking-nightmare-reconfiguring-for-vms">The Networking Nightmare: Reconfiguring for VMs</h2>
<p>PVE&rsquo;s default network setup uses one physical port (<code>enp1s0</code> in my case) solely for its own management. However, to allow my <em>virtual machines</em> (like the router VM) to connect to both the internet (WAN) and my home network (LAN), I needed to create <strong>Linux Bridges</strong>.</p>
<p>My plan:</p>
<ul>
<li><code>vmbr0</code>: Use a different physical port (e.g., <code>enp2s0</code>) for the <strong>WAN</strong> connection (connecting to my ISP modem).</li>
<li><code>vmbr1</code>: Use the remaining two physical ports (e.g., <code>enp3s0</code>, <code>enp4s0</code>) bridged together for the <strong>LAN</strong> connection (connecting to my home switch).</li>
<li><strong>Crucially:</strong> Move PVE&rsquo;s <em>own</em> management interface from the physical port <code>enp1s0</code> onto the newly created <strong>LAN bridge (<code>vmbr1</code>)</strong>. This way, I could manage PVE from any computer on my home network using the <code>10.0.0.2</code> address, freeing up <code>enp1s0</code> perhaps for other uses.</li>
</ul>
<p>This reconfiguration is done by editing the <code>/etc/network/interfaces</code> file directly via the PVE console (or SSH). I carefully modified the file, creating the bridge definitions and changing the management interface settings.</p>
<p>I applied the changes (<code>systemctl restart networking</code> or a reboot). And then&hellip; disaster.</p>
<p>I could no longer access the PVE web UI at <code>10.0.0.2</code>. Pings failed. It seemed I had completely locked myself out.</p>
<h2 id="troubleshooting-in-the-dark">Troubleshooting in the Dark</h2>
<p>Panic set in. Had I made a typo in the config file? Did the bridge fail to come up? I had to go back to the &ldquo;direct connection&rdquo; method: plug a monitor and keyboard directly into the N100 box.</p>
<p>Logging into the PVE console, I ran <code>ip a</code> to check the network interface status. The output revealed the problem: <code>vmbr1</code> (my intended LAN bridge and new management interface) <strong>had no IP address</strong>. My configuration changes hadn&rsquo;t been applied correctly, or something had gone wrong during the network restart.</p>
<p>Carefully re-examining <code>/etc/network/interfaces</code> line by line, I eventually spotted the error – perhaps a typo, a missing <code>auto vmbr1</code>, or incorrect bridge port settings. I corrected the file using the <code>nano</code> editor (a bit friendlier than <code>vi</code> for quick edits).</p>
<p>After saving the corrected file and restarting the networking service again (<code>systemctl restart networking</code>), I ran <code>ip a</code> one more time. Success! <code>vmbr1</code> now showed the correct <code>10.0.0.2</code> address.</p>
<p>Back on my Mac, I refreshed <code>https://10.0.0.2:8006</code>, and the Proxmox login screen reappeared. Access restored!</p>
<p>This harrowing experience was my first real taste of configuring Linux networking and the importance of meticulousness when editing critical system files. With the PVE host networking finally stable, I was ready for the main event: creating the virtual machine that would become my new home router.</p>
]]></content:encoded>
    </item>
  </channel>
</rss>
