<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en"><generator uri="https://jekyllrb.com/" version="3.10.0">Jekyll</generator><link href="https://paolobussacchini.it/feed.xml" rel="self" type="application/atom+xml" /><link href="https://paolobussacchini.it/" rel="alternate" type="text/html" hreflang="en" /><updated>2026-10-19T09:59:56+00:00</updated><id>https://paolobussacchini.it/feed.xml</id><title type="html">Paolo Bussacchini</title><subtitle>Platform / Infrastructure Software Engineer</subtitle><entry><title type="html">Starting an SRE lab: CoreOS, Ignition, and the laptop-&amp;gt;cluster path</title><link href="https://paolobussacchini.it/sre-lab/homelab/2026/10/18/starting-an-sre-lab.html" rel="alternate" type="text/html" title="Starting an SRE lab: CoreOS, Ignition, and the laptop-&amp;gt;cluster path" /><published>2026-10-18T00:00:00+00:00</published><updated>2026-10-18T00:00:00+00:00</updated><id>https://paolobussacchini.it/sre-lab/homelab/2026/10/18/starting-an-sre-lab</id><content type="html" xml:base="https://paolobussacchini.it/sre-lab/homelab/2026/10/18/starting-an-sre-lab.html"><![CDATA[<p>This is the first public note for <strong>sre-lab</strong> - a personal learning path toward platform / SRE work: IaC, lightweight Kubernetes, GitOps, and a small Go service. Before Terraform or Argo CD, I wanted a grounded base: a VM I can rebuild, a declarative first-boot config, and SSH that works without console passwords.</p>

<p>What follows is educational and sanitised. No secrets, no company runbooks, no employer internals - just patterns anyone can practice on a laptop.</p>

<h2 id="why-a-lab-at-all">Why a lab at all</h2>

<p>On the CV, <em>sre-lab</em> is marked <em>in progress</em>: practice the delivery loop from laptop to cluster. The first slice is deliberately small:</p>

<ol>
  <li>Run an immutable-ish Linux appliance in a local hypervisor.</li>
  <li>Configure it once with <strong>Ignition</strong> (from a readable <strong>Butane</strong> file).</li>
  <li>Reach it over <strong>SSH</strong> with a key.</li>
  <li>Only then: pin a lightweight Kubernetes install, Helm, and a smoke PVC to see where data lives.</li>
</ol>

<p>That order matters. Skipping the OS/network layer and jumping straight to “install k3s somehow” hides the failure modes you need for day-2 thinking.</p>

<h2 id="the-mental-model">The mental model</h2>

<div class="language-text highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Laptop (host OS)
  └── Hypervisor (e.g. VirtualBox)
        └── VM disk
              └── Fedora CoreOS (first boot applies Ignition)
                    └── sshd + your user
                          └── (later) k3s -&gt; Helm -&gt; PVC smoke test
</code></pre></div></div>

<p><strong>Fedora CoreOS</strong> fits this lab because it is built around Ignition and a “don’t casually <code class="language-plaintext highlighter-rouge">dnf install</code> forever” mindset. Day-0 config belongs in the recipe, not in ad-hoc shell history.</p>

<h2 id="butane---ignition-the-recipe">Butane -&gt; Ignition (the recipe)</h2>

<ul>
  <li><strong>Butane</strong> (<code class="language-plaintext highlighter-rouge">.bu</code>): human-readable YAML - hostname, user, public SSH key, directories, systemd units you will add later.</li>
  <li><strong>Ignition</strong> (<code class="language-plaintext highlighter-rouge">.ign</code>): machine JSON applied <strong>once</strong> on first boot.</li>
  <li>The <code class="language-plaintext highlighter-rouge">butane</code> tool compiles A -&gt; B.</li>
</ul>

<p>Typical flow on a laptop: compile the Ignition file, serve it with a tiny HTTP server on the host, boot a <strong>CoreOS Live</strong> ISO in the VM, and install to disk with something like <code class="language-plaintext highlighter-rouge">coreos-installer</code> pointing at that URL.</p>

<p>Two lessons that cost me time (and are worth writing down):</p>

<ol>
  <li><strong>Product, not version number.</strong> A Fedora <em>Workstation</em> live ISO is the wrong tool for this path. You want <strong>Fedora CoreOS Live</strong> (appliance + installer + Ignition).</li>
  <li><strong>Encoding.</strong> On Windows PowerShell, redirecting JSON with <code class="language-plaintext highlighter-rouge">&gt;</code> can yield UTF-16. The HTTP download may look fine; Ignition parse will not. Prefer explicit UTF-8 when writing the <code class="language-plaintext highlighter-rouge">.ign</code> file.</li>
</ol>

<p>The <code class="language-plaintext highlighter-rouge">version</code> field in a Butane file is the <strong>schema</strong> version of that file format - not “which Fedora release I installed.”</p>

<h2 id="networking-why-1270012222">Networking: why <code class="language-plaintext highlighter-rouge">127.0.0.1:2222</code></h2>

<p>With VirtualBox <strong>NAT</strong>, the guest often sits on an internal address (commonly <code class="language-plaintext highlighter-rouge">10.0.2.15</code>) that your LAN never sees. Port-forward host <code class="language-plaintext highlighter-rouge">2222</code> -&gt; guest <code class="language-plaintext highlighter-rouge">22</code>, then:</p>

<div class="language-text highlighter-rouge"><div class="highlight"><pre class="highlight"><code>ssh -i &lt;private-key&gt; -p 2222 core@127.0.0.1
</code></pre></div></div>

<p>Bridge mode can work depending on Wi-Fi/NIC quirks; NAT + forward is a reliable default for a single laptop lab.</p>

<h2 id="ssh-without-a-console-password">SSH without a console password</h2>

<p>Put the <strong>public</strong> key in Butane / on the guest <code class="language-plaintext highlighter-rouge">authorized_keys</code>. Keep the <strong>private</strong> key only on the host. CoreOS lab images often have <strong>no</strong> password login on the console - that is expected. Missing <code class="language-plaintext highlighter-rouge">-i</code> or <code class="language-plaintext highlighter-rouge">-p</code> usually shows up as <code class="language-plaintext highlighter-rouge">Permission denied (publickey)</code>.</p>

<p>Checkpoint when it works: expected hostname, guest interface up, user <code class="language-plaintext highlighter-rouge">core</code> (or whatever you declared), SSH only via key.</p>

<h2 id="how-this-ties-to-sre-lab">How this ties to sre-lab</h2>

<table>
  <thead>
    <tr>
      <th>Lab slice</th>
      <th>Practice</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>CoreOS + Ignition + SSH</td>
      <td>Rebuildable machine identity</td>
    </tr>
    <tr>
      <td>Next: pinned k3s + Helm + PVC</td>
      <td>Where workloads and data live on the node</td>
    </tr>
    <tr>
      <td>Later: Terraform / Go service / Argo CD</td>
      <td>IaC + app + GitOps sync</td>
    </tr>
  </tbody>
</table>

<p>The CV project description stays the north star; this post is the <strong>foundation chapter</strong> - the part that makes later automation honest instead of magical.</p>

<h2 id="what-i-am-deliberately-not-publishing">What I am deliberately not publishing</h2>

<ul>
  <li>Private keys, tokens, or Ignition files with secrets.</li>
  <li>Employer diagrams, internal hostnames, or product-specific installers.</li>
  <li>Copy-paste “production” procedures. This is a <strong>personal</strong> learning loop.</li>
</ul>

<p>If you are on a similar path: start from an empty disk, write a Butane file you understand, get SSH working, then add one systemd one-shot at a time. Reprovision from scratch at least twice - that is the real test.</p>

<hr />

<p><em>First published note for sre-lab. An earlier Italian CoreOS walkthrough remains in <code class="language-plaintext highlighter-rouge">_drafts/</code> for my own notes.</em></p>]]></content><author><name></name></author><category term="sre-lab" /><category term="homelab" /><category term="sre" /><category term="coreos" /><category term="ignition" /><category term="virtualbox" /><category term="kubernetes" /><category term="ssh" /><category term="learning" /><summary type="html"><![CDATA[This is the first public note for sre-lab - a personal learning path toward platform / SRE work: IaC, lightweight Kubernetes, GitOps, and a small Go service. Before Terraform or Argo CD, I wanted a grounded base: a VM I can rebuild, a declarative first-boot config, and SSH that works without console passwords.]]></summary></entry></feed>