<?xml version='1.0' encoding='UTF-8'?>
<rss xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/" version="2.0">
  <channel>
    <title>Back to the Dev</title>
    <link>https://thiago4go.github.io/rss.xml</link>
    <description>Back to the Dev — posts by thiago4go</description>
    <atom:link href="https://thiago4go.github.io/rss.xml" rel="self"/>
    <docs>http://www.rssboard.org/rss-specification</docs>
    <generator>python-feedgen</generator>
    <language>en-us</language>
    <lastBuildDate>Sun, 19 Jul 2026 04:12:36 +0000</lastBuildDate>
    <item>
      <title>Kubernetes Essentials Tools</title>
      <link>https://thiago4go.github.io/posts/kubernetes-essential-tools/</link>
      <description>Kubernetes Essentials Tools</description>
      <content:encoded><![CDATA[<section id="intro">
    <p>As Kubernetes continues to gain popularity, the ecosystem around it has grown significantly, offering a wide range of tools to simplify and enhance the Kubernetes experience. These tools cover various aspects of Kubernetes, including deployment, monitoring, development, and management, catering to the diverse needs of Kubernetes users. In this article, we'll explore some essential tools that can help you work more effectively with Kubernetes.</p>
  </section>

  <section id="gif">
  <img src="/images/kubernetes-essential-tools.gif" alt="Kubernetes Essential Tools" style="display: block; margin-left: auto; margin-right: auto; max-width: 100%; height: auto;">
  </section>
  <section id="cli-tools">
    <h2>Command Line Tools</h2>
    <div class="tool">
        <h3>kubectl</h3>
        <p><strong>kubectl</strong> is the quintessential command-line tool for interacting with Kubernetes clusters, allowing users to deploy applications, inspect and manage cluster resources, and view logs. It is compatible with any operating system that supports Kubernetes, offering a versatile toolkit for Kubernetes management.</p>
        <strong>Usage:</strong>
        <div style="width: 80%; margin: right;">
          <div class="CodeSnippet"><pre><code>
kubectl get pods
kubectl describe pod my-pod
kubectl logs my-pod
          </code></pre></div>
          </div>
          <a href="https://kubernetes.io/docs/reference/kubectl/overview/" target="_blank" rel="noopener">Learn more about kubectl</a>
    </div>
    <div class="tool">
        <h3>kubie</h3>
        <p><strong>kubie</strong> is a more context-aware CLI tool designed to improve the Kubernetes user experience. It simplifies context switching and namespace management, making it easier for users to work with multiple clusters or namespaces without losing track of their current operational context.</p>
        <strong>Usage:</strong>
        <div style="width: 80%;max-width: 100%; margin: right;">

          <div class="CodeSnippet"><pre><code>
kubie ctx
kubie ns
          </code></pre></div>
        </div>
          <a href="https://github.com/sbstp/kubie" target="_blank" rel="noopener">Learn more about kubie</a>
    </div>
    <div class="tool">
        <h3>k9s</h3>
        <p><strong>k9s</strong> provides a terminal-based UI to interact with your Kubernetes clusters, making it easier to monitor and manage your cluster's resources. It enhances the kubectl experience by offering a more interactive and visually appealing interface, improving efficiency and productivity for Kubernetes administrators and developers.</p>
        <strong>Usage:</strong>
          <div style="width: 80%; max-width: 100%; margin: right;">
            <div class="CodeSnippet"><pre><code>
k9s
            </code></pre></div>
          </div>
          <a href="https://k9scli.io/" target="_blank" rel="noopener">Learn more about k9s</a>
    </div>
</section>


  <section id="adm-tools">
    <h2>Management</h2>
    <div class="tool">
        <h3>minikube</h3>
        <p><strong>Minikube</strong> is an excellent tool for users looking to run Kubernetes locally. It simplifies the process by managing a single-node cluster inside a VM on your computer. This tool is perfect for development, testing, and trying out new features.</p>
        <a href="https://minikube.sigs.k8s.io/docs/" target="_blank" rel="noopener">Learn more about minikube</a>
    </div>
    <div class="tool">
        <h3>kubeadm</h3>
        <p><strong>Kubeadm</strong> streamlines the process of getting a Kubernetes cluster up and running. It provides the necessary tools to initiate the cluster, manage its lifecycle, and perform tasks such as upgrades and configuration changes. It's a fundamental tool for anyone looking to deploy Kubernetes clusters.</p>
        <a href="https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/" target="_blank" rel="noopener">Learn more about kubeadm</a>
    </div>
    <div class="tool">
        <h3>kOps</h3>
        <p><strong>kOps</strong> is a powerful tool designed for creating, destroying, upgrading, and maintaining high-availability Kubernetes clusters. It's user-friendly and ideal for managing clusters in a production environment, offering robust features that cater to demanding requirements.</p>
        <a href="https://kops.sigs.k8s.io/" target="_blank" rel="noopener">Learn more about kOps</a>
    </div>
    <div class="tool">
        <h3>Managed Kubernetes Platforms</h3>
        <p>Managed Kubernetes platforms provide a hands-off approach to cluster management, handling the underlying infrastructure, scaling, and maintenance. These platforms offer various features like built-in authentication, logging, monitoring, and self-healing, making Kubernetes accessible to a broader audience.</p>
        <strong>Examples:</strong>
        <ol>
            <li>Amazon EKS</li>
            <li>Google Kubernetes Engine (GKE)</li>
            <li>Microsoft Azure Kubernetes Service (AKS)</li>
            <li>DigitalOcean Kubernetes</li>
            <li>IBM Cloud Kubernetes Service</li>
            <li>Oracle Container Engine for Kubernetes</li>
            <li>Alibaba Cloud Container Service for Kubernetes</li>
            <li>Red Hat OpenShift</li>
            <li>Rancher</li>
            <li>VMware Tanzu Kubernetes Grid</li>
            <li>Linode Kubernetes Engine</li>
            <li>Platform9 Managed Kubernetes</li>
            <li>StackPath Edge Compute Network</li>
            <li>Canonical Kubernetes</li>
            <li>The list goes on...</li>
        </ol>
        </ul>
      </div>
</section>

<section id="dev-tools">
  <h2>Development Tools</h2>
  <div class="tool">
      <h3>Telepresence</h3>
      <p><strong>Telepresence</strong> dramatically changes the Kubernetes development workflow by allowing developers to run a single service locally while connecting that service to a remote Kubernetes cluster. This approach facilitates rapid development and testing by enabling instant feedback on code changes without the need to deploy the code to the cluster for each update.</p>
      <a href="https://www.telepresence.io/" target="_blank" rel="noopener">Learn more about Telepresence</a>
  </div>
  <div class="tool">
      <h3>Tilt</h3>
      <p><strong>Tilt</strong> streamlines the development of microservices by offering live updates to your Kubernetes environment. It allows developers to automate the build and deploy process in real-time, enabling a more iterative and efficient development cycle. Tilt focuses on improving productivity and reducing the feedback loop in microservices development.</p>
      <a href="https://tilt.dev/" target="_blank" rel="noopener">Learn more about tilt</a>
  </div>
  <div class="tool">
      <h3>Lens IDE</h3>
      <p><strong>Lens IDE</strong> is a powerful integrated development environment specifically designed for Kubernetes, offering developers a comprehensive view of their clusters. It simplifies cluster management, resource monitoring, and application development, providing an intuitive interface that enhances the overall development experience on Kubernetes.</p>
      <a href="https://k8slens.dev/" target="_blank" rel="noopener">Learn more about Lens IDE</a>
  </div>
</section>

 
  <section id="deployment-tools">
    <h2>Deployment</h2>
    <div class="tool">
        <h3>Helm</h3>
        <p><strong>Helm</strong> is often referred to as the 'app store' for Kubernetes, offering a powerful and flexible way to manage Kubernetes applications. Helm Charts help you define, install, and upgrade even the most complex Kubernetes application, streamlining the deployment process.</p>
        <a href="https://helm.sh/" target="_blank" rel="noopener">Learn more about Helm</a>
    </div>
    <div class="tool">
        <h3>Kubespray</h3>
        <p><strong>Kubespray</strong> is a versatile open-source tool for deploying and managing Kubernetes clusters. It provides a straightforward and consistent way to set up clusters, leveraging popular automation tools like Ansible for infrastructure provisioning, making it a reliable choice for infrastructure as code practices.</p>
        <a href="https://kubespray.io/" target="_blank" rel="noopener">Learn more about Kubespray</a>
    </div>
</section>


<section id="monitoring-tools">
  <h2>Monitoring</h2>
  <div class="tool">
      <h3>Kubernetes Dashboard</h3>
      <p>The <strong>Kubernetes Dashboard</strong> offers a user-friendly web-based interface for managing and monitoring your Kubernetes cluster. While not installed by default, it can be easily added to your cluster as a pod, providing a visual overview of the cluster's state and performance.</p>
      <a href="https://kubernetes.io/docs/tasks/access-application-cluster/web-ui-dashboard/" target="_blank" rel="noopener">Learn more about Kubernetes Dashboard</a>
  </div>
  <div class="tool">
      <h3>Prometheus</h3>
      <p><strong>Prometheus</strong> is a widely adopted open-source monitoring solution that seamlessly integrates with Kubernetes. It offers a robust set of features to collect, store, and query metrics, providing valuable insights into the performance and health of your applications and infrastructure.</p>
      <a href="https://prometheus.io/" target="_blank" rel="noopener">Learn more about Prometheus</a>
  </div>
  <div class="tool">
      <h3>Jaeger</h3>
      <p><strong>Jaeger</strong>, a distributed tracing system, leverages OpenTelemetry to provide detailed insights into the behavior of your distributed applications. It's an all-in-one solution for monitoring, troubleshooting, and visualizing the interactions between your services.</p>
      <a href="https://www.jaegertracing.io/" target="_blank" rel="noopener">Learn more about Jaeger</a>
  </div>
</section>
<section id="conclusion">
  <h2>Conclusion</h2>
  <p>As Kubernetes continues to evolve, the ecosystem around it will continue to expand, offering a wide range of tools to enhance the Kubernetes experience. The tools mentioned in this article are just a few examples of the many available, catering to the diverse needs of Kubernetes users. Whether you're a developer, administrator, or operator, these tools can help you work more effectively with Kubernetes, simplifying deployment, monitoring, development, and management tasks.</p>
</section>]]></content:encoded>
      <guid isPermaLink="false">https://thiago4go.github.io/posts/kubernetes-essential-tools/</guid>
      <category>Kubernetes</category>
      <category>Tools</category>
      <category>DevOps</category>
      <category>Cloud-native</category>
      <category>Development</category>
      <category>Deployment</category>
      <category>Monitoring</category>
      <pubDate>Mon, 11 Mar 2024 00:00:00 +0000</pubDate>
    </item>
    <item>
      <title>Embracing Ongoing Education</title>
      <link>https://thiago4go.github.io/posts/ongoing-education/</link>
      <description>Embracing Ongoing Education</description>
      <content:encoded><![CDATA[<blockquote>
        "Knowledge without practice is useless. Practice without knowledge is dangerous." – Confucius
    </blockquote>

  <section id="intro">
    <p>This quote from Confucius has helped me find my way on the path of continuously learning. Being committed to both personal and professional growth has paid off in a big way over the past year. I am excited to talk about my journey and the helpful tools that have illuminated my path.</p>
  </section>

  <section id="gif">
  <img src="/images/continous-learning.gif" alt="Ongoing Education" style="display: block; margin-left: auto; margin-right: auto; max-width: 100%; height: auto;">
  </section>
  <section id="aim-high">
    <h2>Having High Aims</h2>
    <div class="intro">
        <p>While unemployed in Japan, I channeled my situation into a bold ambition: to become a professional developer. Later when I already got a job as Web Developer in Australia  I decided to pursue the Certified Kubernetes Application Developer (CKAD) credential, recognizing that it was not just about the certificate, but about improving my skills and increasing my value in the industry. </p>
    </div>
    </section>
    <section id="resources">
    <div class="resources">
        <h2>An Universe of Learning Resources</h2>
        <p>The digital landscape is a goldmine of educational treasures. Here's a snapshot of the platforms that have been pivotal in my learning journey:</p>
        <ul>
            <li><strong>Libraries</strong> : An often-overlooked gem, local libraries provide free access to a wealth of knowledge, including LinkedIn Learning. Check out the <a href="https://www.slv.vic.gov.au/membership" target="_blank" rel="noopener">State Library Victoria</a></li>
            <li><strong>Online Learning Platforms</strong>: Sites like <a href="https://www.coursera.org/" target="_blank" rel="noopener">Coursera</a>, <a href="https://www.edx.org/" target="_blank" rel="noopener">EdX</a>, and <a href="https://www.freecodecamp.org/" target="_blank" rel="noopener">FreeCodeCamp</a>, alongside <a href="https://cs50.harvard.edu/" target="_blank" rel="noopener">Harvard's CS50</a>, offer an array of courses, many of which are free.</li>
            <li><strong>Tech Giants' Contributions</strong>: Platforms like <a href="https://skillsforall.com/" target="_blank" rel="noopener">Cisco Skills for All</a>, <a href="https://learn.microsoft.com/en-us/" target="_blank" rel="noopener">Microsoft Learn</a>, AWS, and RedHat offer specialized learning resources and certifications.</li>
            <li><strong>Paid Memberships</strong>: For Laravel learning, platforms like Laracast have been invaluable. Also Udemy courses.</li>
            <li><strong><a href="https://kodekloud.com/" target="_blank" rel="noopener">KodeKloud:</a></strong> An essential resource for practical Kubernetes and DevOps training, offering comprehensive courses and hands-on challenges.</li>
        </ul>
    </div>
    </section>
    <section id="practice">
    <div class="practice">
        <h2>It's Not Just About Input: Put Your Knowledge to Practice</h2>
      

<p>Acquiring knowledge is only one part of the equation. Here's how I applied my learnings:</p>
<ol>
  <li><strong>Personal Projects:</strong> Building real-world projects solidifies new concepts and skills.</li>
  <li><strong>Work Applications:</strong> I actively sought ways to use my new skills at work, adding value and demonstrating growth.</li>
</ol>
   </div>
</section>


<section id="community">
  <h2>The Power of Community</h2>
  <p>
    Learning doesn't have to be solitary. This is why I set out to learn Kubernetes, using a range of tools and actively looking for a mentor and a community to help me along the way. </p>
    <p> Connect with like-minded people:  </p>
    <ul>
      <li>Meetup Events: Attend events in your area to network and learn.</li>
      <li>Online Groups and Forums: Share insights and learn from others in relevant online communities. Try Slack or Discord Channels</li>
      <li>Mentoring: Engage in a mentoring relationship where you can either mentor someone else, benefiting from the reciprocal learning process, or find a mentor to guide you through your learning journey, offering personalized advice and insights based on their experience. </li>
    </ul>
</section>

<section id="conclusion">
  <h2>Learning Never Ends</h2>
  <p>Embracing ongoing education has been a game-changer for me. It has not only helped me grow professionally but has also enriched my personal life. "Back to the Dev" isn't just about certifications or tech. It's about staying curious!  I'm constantly taking on new challenges and sharing what I discover through posts and LinkedIn updates.</p>
</section>]]></content:encoded>
      <guid isPermaLink="false">https://thiago4go.github.io/posts/ongoing-education/</guid>
      <category>Ongoing Education</category>
      <category>Personal Growth</category>
      <category>Professional Development</category>
      <category>Kubernetes</category>
      <category>DevOps</category>
      <category>Laravel</category>
      <category>Web Development</category>
      <category>Learning Platforms</category>
      <category>Online Education</category>
      <category>Community Learning</category>
      <category>Mentoring</category>
      <category>Continuous Learning</category>
      <pubDate>Sun, 24 Mar 2024 00:00:00 +0000</pubDate>
    </item>
    <item>
      <title>Project Lifecycle in Software Development</title>
      <link>https://thiago4go.github.io/posts/project-management/</link>
      <description>Project Lifecycle in Software Development</description>
      <content:encoded><![CDATA[<blockquote>
        "Success in software development isn't just about writing code; it's about following a disciplined process." – Unknown
    </blockquote>
    
    <section id="intro">
        <p>As someone deeply involved in software development and project management, I’ve learned that the difference between a successful project and a failed one often comes down to how well you manage each phase of the project lifecycle. This lesson was driven home during a recent project involving Nikkei One, a software consulting firm that prides itself on merging traditional business wisdom with modern technology.</p>
    </section>
    
    <section id="scenario">
        <h2>The Consequences of Rushing Through a Project Phase</h2>
        <div class="intro">
            <p>It was Friday evening when I received an urgent call from my manager. We had a new client, Nikkei One, who needed a custom cloud-native solution to enhance their DevOps pipeline. The deadline was tight—they wanted a cost estimate and timeline by Monday.</p>
            <p>I spent the weekend quickly putting together a proposal, estimating a standard budget of $200,000 and a six-week timeline, based on similar past projects. I sent it off, feeling confident I had met the deadline. However, Monday morning revealed the flaws in this approach. Our engineering team discovered that our solution was incompatible with Nikkei One's infrastructure, leading to a much larger scope than anticipated. The real project would take six months of development and another six months of testing, with a budget exceeding a million dollars. The project was doomed before it even started.</p>
        </div>
    </section>
    
    <section id="better-approach">
        <h2>A Better Approach: Ensuring Project Success Through Proper Planning</h2>
        <div class="intro">
            <p>Reflecting on this experience, I realized I should have taken a different approach. Instead of rushing, I could have requested more time to put together a thorough and accurate proposal. This would have allowed me to involve key stakeholders—engineers, designers, and other experts—in crafting a feasible plan.</p>
            <p>With a bit more time, we could have clarified Nikkei One's needs, assessed technical challenges, and aligned our proposal with their platform. This collaborative approach would have ensured a realistic and achievable project plan.</p>
        </div>
    </section>

    <section id="png">
      <img src="/images/project-life-cycle.png" alt="Project Lifecycle" style="display: block; margin-left: auto; margin-right: auto; max-width: 100%; height: auto;">
      </section>
    
    <section id="project-lifecycle">
        <h2>Applying the Project Lifecycle to Software Development</h2>
        <div class="intro">
            <h3>Initiating the Project</h3>
            <p>The initiation phase is where I should have slowed down and really focused. Instead of rushing through it, I should have sat down with my team to discuss the project goals in detail. For a complex cloud-native solution like this, understanding Nikkei One’s technical environment is crucial.</p>
            
            <h3>Planning for Success</h3>
            <p>With the project properly initiated, the next step would be to craft a detailed plan. This includes mapping out every aspect of the project, from resource allocation to risk management and quality assurance. A solid plan ensures that everyone on the team knows their role and what’s expected of them.</p>
            
            <h3>Executing the Plan</h3>
            <p>During the execution phase, the team would work according to the plan, with my role focused on facilitating communication, removing obstacles, and ensuring tasks are completed on schedule. Regular updates to Nikkei One would allow us to gather feedback and make any necessary adjustments along the way.</p>
            
            <h3>Closing the Project</h3>
            <p>Finally, after successfully delivering the solution, we would enter the closing phase. This is where we gather the team to reflect on what went well and what could be improved. It’s also an opportunity to celebrate our success and recognize the hard work that everyone put in.</p>
        </div>
    </section>
    
    <section id="key-takeaway">
        <h2>Key Takeaways</h2>
        <p>This experience taught me a crucial lesson about the importance of not rushing through project phases, especially in the fast-paced world of software development and cloud-native solutions. By taking the time to thoroughly plan and involve your team early on, you set the stage for a successful project and build stronger, more trusting relationships with clients like Nikkei One.</p>
    </section>]]></content:encoded>
      <guid isPermaLink="false">https://thiago4go.github.io/posts/project-management/</guid>
      <category>Project Management</category>
      <category>Software Development</category>
      <category>Cloud-Native Solutions</category>
      <category>DevOps</category>
      <category>Project Lifecycle</category>
      <category>Nikkei One</category>
      <category>Team Collaboration</category>
      <category>Planning</category>
      <category>Execution</category>
      <category>Success</category>
      <pubDate>Sat, 17 Aug 2024 00:00:00 +0000</pubDate>
    </item>
    <item>
      <title>Homelab Adventures: Nested Proxmox on a Budget Laptop</title>
      <link>https://thiago4go.github.io/posts/home-lab-series-part-1/</link>
      <description>A deep dive into turning a second-hand laptop into a portable homelab using Windows 10, Hyper-V, and nested Proxmox—complete with real-world troubleshooting, future VLAN experiments, and a nod to Kubernetes and IaC.</description>
      <content:encoded><![CDATA[<section id="intro">
          <p>Sometimes, building a homelab is less about having perfect hardware and more about learning to innovate within constraints. By starting with an AUD 75 laptop, we’re proving that you don’t need the latest-and-greatest server gear to master cloud-native and DevOps tools. This post covers how we set up Windows 10 Pro as a base, installed Proxmox in a nested environment, tackled some serious networking hurdles, and laid the groundwork for future Kubernetes, VLAN, and IaC explorations.</p>
        </section>

        <section id="content">
          <section id="key-principles">
<h2>Key Principles</h2>
<ul>
    <li><strong>Start small, iterate often.</strong> Rapid experimentation leads to quicker learning.</li>
    <li><strong>Use secondhand/affordable gear.</strong> Proves you don’t need expensive hardware to explore advanced topics.</li>
    <li><strong>Hands-on troubleshooting over perfection.</strong> Real learning comes from fixing things that break.</li>
</ul>
</section>

<section id="day-0-budget-hardware">
<h2>Day 0: Acquiring Budget Hardware</h2>
<p><strong>Action:</strong> Bought a <em>Dell Latitude E7240 Ultrabook</em> for AUD 75 via Facebook Marketplace.</p>
<p><strong>Reason:</strong> Low-cost entry point for a dedicated homelab—2 cores, 16 GB RAM, and an SSD are enough to run nested virtual machines and experiment with various tools.</p>
<p><strong>Value:</strong> Portable, quiet, and inexpensive to run in a home environment, making it ideal for both portability and 24/7 operation.</p>

<div class="CodeSnippet"><div class="CodeSnippet"><pre><code>Hardware Specs Recap:
• Purchase Price: AUD $75
• CPU: Intel Core i7-4600U (2C/4T)
• RAM: 16GB DDR3L
• Storage: 500GB SSD
• Approx. Power Draw: 15W idle, up to 45W under load</code></pre></div></div>
</section>

<section id="base-os-and-virtualisation">
<h2>Deciding on Base OS & Virtualisation</h2>
<p><strong>Chosen OS:</strong> Windows 10 Pro</p>
<p><strong>Reason:</strong> Familiarity (still run Windows tools), plus Hyper-V integration for quick VM provisioning. Using Windows also enables convenient snapshotting and easy bridging with the rest of the home network.</p>
<p><strong>Alternative Consideration:</strong> Bare-metal Proxmox. Ultimately, we decided on Windows 10 first to minimize downtime and keep certain workflows. Proxmox will run as a nested VM inside Hyper-V.</p>
</section>

<section id="day-1-proxmox-nested">
<h2>Day 1: Proxmox on a Potato (Nested!)</h2>
<p><strong>Action:</strong> Installed Proxmox inside Hyper-V. <br/>
<strong>Reason:</strong> Proxmox is a popular hypervisor for homelabs, offering extensive features like clustering, ZFS support, and advanced networking. <br/>
<strong>Outcome:</strong> Ran into tricky network complications related to bridging and NAT in a nested environment.</p>
</section>

<section id="network-challenges">
<h3>Identified Network Complications</h3>
<p><strong>Problem:</strong> Bridging for Proxmox VMs inside Hyper-V can cause connectivity issues—like trouble obtaining IP addresses or exposing services externally. Nested virtualisation often restricts certain kernel-level features and can add complexity to networking.</p>
<p><em>Decision:</em> Continue with Windows 10 + Hyper-V for now, but refine network config meticulously.</p>
</section>

<section id="step-by-step-setup">
<h2>Step-by-Step Setup & Troubleshooting</h2>

<h3>1. Create the Internal Virtual Switch in Hyper-V</h3>
<ol>
    <li>Open <strong>Hyper-V Manager</strong> → <strong>Virtual Switch Manager</strong> → <em>New Virtual Switch</em>.</li>
    <li>Name it: <code>Proxmox-Lab</code>.</li>
    <li>Select <strong>Internal</strong>.</li>
    <li>Check "Enable virtual LAN identification" if you plan on using VLANs later.</li>
    <li>Click <em>OK</em>.</li>
</ol>

<section id="png">
  <img src="/images/home-lab/virtual-switch.png" alt="Project Lifecycle" style="display: block; margin-left: auto; margin-right: auto; max-width: 100%; height: auto;">
  </section>


<div class="CodeSnippet"><div class="CodeSnippet"><pre><code>Example Configuration:
Switch Name: Proxmox-Lab
Type: Internal
VLAN ID: Optional (future use)
</code></pre></div></div>

<h3>2. Download & Create Proxmox VM in Hyper-V</h3>
<ol>
    <li>Download the <a href="https://www.proxmox.com/en/downloads">Proxmox VE ISO</a>.</li>
    <li>Open <strong>Hyper-V Manager</strong>.</li>
    <li>Right-click your host → <strong>New → Virtual Machine</strong>.</li>
    <li><strong>Name:</strong> Proxmox-VM (or similar).</li>
    <li><strong>Generation:</strong> 2 (required for UEFI support).</li>
    <li><strong>Memory:</strong> 8 GB static allocation (dynamic can cause odd issues with nested VMs).</li>
    <li><strong>Network:</strong> Select the <code>Proxmox-Lab</code> internal switch.</li>
    <li><strong>Virtual Disk:</strong> 128GB (or as large as your SSD can handle).</li>
    <li><strong>Installation Source:</strong> Point to the Proxmox ISO.</li>
</ol>

<section id="png">
  <img src="/images/home-lab/new-vm-wizard.png" alt="Project Lifecycle" style="display: block; margin-left: auto; margin-right: auto; max-width: 100%; height: auto;">
  </section>

<h3>3. Adjust VM Settings</h3>

<h4>3.1 Enable Nested Virtualization</h4>
<div class="CodeSnippet"><div class="CodeSnippet"><pre><code># In Administrator PowerShell:
Set-VMProcessor -VMName "Proxmox-VM" -ExposeVirtualizationExtensions $true
</code></pre></div></div>
<p>If you skip this step, you may encounter errors indicating that Proxmox can’t detect virtualization extensions during installation.</p>

<h4>3.2 Allocate More Virtual Processors</h4>
<div class="CodeSnippet"><div class="CodeSnippet"><pre><code>Set-VM -VMName "Proxmox-VM" -ProcessorCount 4
</code></pre></div></div>
<p>Adjust based on your laptop’s CPU core/thread availability.</p>

<h3>4. Install Proxmox</h3>
<p>Boot the VM and follow the on-screen instructions. When prompted for network configuration, use the table below.</p>

<table>
    <thead>
        <tr><th>Field</th><th>Suggested Value</th><th>Explanation</th></tr>
    </thead>
    <tbody>
        <tr>
            <td>Management Interface</td>
            <td><code>eth0</code> (default)</td>
            <td>This is the interface connected to the <code>Proxmox-Lab</code> switch in Hyper-V.</td>
        </tr>
        <tr>
            <td>Hostname (FQDN)</td>
            <td><code>proxmox.lab</code></td>
            <td>Use a dummy domain like <code>.lab</code> for homelab use.</td>
        </tr>
        <tr>
            <td>IP Address (CIDR)</td>
            <td><code>192.168.10.10/24</code></td>
            <td>Static IP for Proxmox. We’ll NAT from <code>192.168.10.0/24</code>.</td>
        </tr>
        <tr>
            <td>Gateway Address</td>
            <td><code>192.168.10.1</code></td>
            <td>Windows host’s NAT IP—essential for external connectivity.</td>
        </tr>
        <tr>
            <td>DNS Server</td>
            <td><code>8.8.8.8</code> (Google) or <code>1.1.1.1</code> (Cloudflare)</td>
            <td>Ensure reliable external DNS for updates, package installs, etc.</td>
        </tr>
    </tbody>
</table>

<section id="png">
  <img src="/images/home-lab/installing-1.png" alt="Project Lifecycle" style="display: block; margin-left: auto; margin-right: auto; max-width: 100%; height: auto;">
  </section>
  <section id="png">
    <img src="/images/home-lab/installing-2.png" alt="Project Lifecycle" style="display: block; margin-left: auto; margin-right: auto; max-width: 100%; height: auto;">
    </section>
    <section id="png">
      <img src="/images/home-lab/installing-3.png" alt="Project Lifecycle" style="display: block; margin-left: auto; margin-right: auto; max-width: 100%; height: auto;">
      </section>
</section>

<section id="network-troubleshooting">
<h2>Networking: Detailed Troubleshooting</h2>
<p>After installation, you might discover that your Proxmox VM can’t access the internet or the local network. Here’s the deep dive on fixing that.</p>
<section id="png">
  <img src="/images/home-lab/pos-installing.png" alt="Project Lifecycle" style="display: block; margin-left: auto; margin-right: auto; max-width: 100%; height: auto;">
  </section>
<h3>Check /etc/network/interfaces</h3>
<div class="CodeSnippet"><div class="CodeSnippet"><pre><code>nano /etc/network/interfaces

# Example Configuration:
auto lo
iface lo inet loopback

auto eth0
iface eth0 inet manual

auto vmbr0
iface vmbr0 inet static
  address 192.168.10.10/24
  gateway 192.168.10.1
  bridge-ports eth0
  bridge-stp off
  bridge-fd 0
  dns-nameservers 8.8.8.8
</code></pre></div></div>

<h3>Verify Proxmox-Lab NAT on Windows Host</h3>
<div class="CodeSnippet"><div class="CodeSnippet"><pre><code># In PowerShell, check if the NAT is set correctly:
Get-NetNat -Name "ProxmoxNAT" | Select InternalIPInterfaceAddressPrefix

# Expected: 192.168.10.0/24
</code></pre></div></div>

<p>If not configured:</p>
<div class="CodeSnippet"><div class="CodeSnippet"><pre><code># Remove existing NAT (if any)
Remove-NetNat -Name "ProxmoxNAT" -Confirm:$false -ErrorAction SilentlyContinue

# Create a new NAT rule:
New-NetNat -Name "ProxmoxNAT" -InternalIPInterfaceAddressPrefix "192.168.10.0/24"
</code></pre></div></div>

<h3>Assign Static IP 192.168.10.1 to vEthernet (Proxmox-Lab)</h3>
<div class="CodeSnippet"><div class="CodeSnippet"><pre><code># Remove existing IP (if any)
Remove-NetIPAddress -InterfaceAlias "vEthernet (Proxmox-Lab)" -Confirm:$false

# Assign static IP
New-NetIPAddress -InterfaceAlias "vEthernet (Proxmox-Lab)" -IPAddress 192.168.10.1 -PrefixLength 24
</code></pre></div></div>

<h3>Enable Internet Sharing on the Host</h3>
<ol>
    <li>Open <strong>Control Panel → Network Connections</strong>.</li>
    <li>Right-click your main <strong>Wi-Fi/Ethernet adapter</strong> → <strong>Properties → Sharing</strong>.</li>
    <li>Check <em>"Allow other network users to connect"</em> and select <code>vEthernet (Proxmox-Lab)</code> from the dropdown.</li>
    <li>Restart the Proxmox-Lab adapter:<br/>
    <div class="CodeSnippet"><div class="CodeSnippet"><pre><code>Restart-NetAdapter -Name "vEthernet (Proxmox-Lab)"
</code></pre></div></div>
    </li>
</ol>

<h3>Firewall & DNS Checks</h3>
<ol>
    <li><strong>Enable ICMP inbound:</strong>
<div class="CodeSnippet"><div class="CodeSnippet"><pre><code>New-NetFirewallRule -DisplayName "Allow ICMPv4" -Direction Inbound -Protocol ICMPv4 -IcmpType 8 -Action Allow
</code></pre></div></div>
    </li>
    <li><strong>Edit DNS settings in Proxmox:</strong>
<div class="CodeSnippet"><div class="CodeSnippet"><pre><code>nano /etc/resolv.conf

# Add or confirm:
nameserver 8.8.8.8
nameserver 1.1.1.1
</code></pre></div></div>
    </li>
    <li><strong>Open Proxmox Web UI port:</strong>
<div class="CodeSnippet"><div class="CodeSnippet"><pre><code>New-NetFirewallRule -DisplayName "Proxmox Web UI" -Direction Inbound -LocalPort 8006 -Protocol TCP -Action Allow
</code></pre></div></div>
    </li>
</ol>

<p>Now, <code>ping 192.168.10.1</code> and <code>ping 8.8.8.8</code> from the Proxmox VM. If both work, you’re in business!</p>
</section>

<section id="png">
  <img src="/images/home-lab/proxmox-login.png" alt="Project Lifecycle" style="display: block; margin-left: auto; margin-right: auto; max-width: 100%; height: auto;">
  </section>
  <section id="png">
    <img src="/images/home-lab/proxmox-gui.png" alt="Project Lifecycle" style="display: block; margin-left: auto; margin-right: auto; max-width: 100%; height: auto;">
    </section>
    

<section id="final-network-summary">
<h2>Final Network Configuration Summary</h2>
<table>
    <thead>
        <tr>
            <th>Component</th>
            <th>Configuration</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td><strong>Hyper-V Switch</strong> (<em>Proxmox-Lab</em>)</td>
            <td>Static IP on host side: <code>192.168.10.1/24</code></td>
        </tr>
        <tr>
            <td><strong>Proxmox Host</strong></td>
            <td>Static IP: <code>192.168.10.10/24</code>, Gateway: <code>192.168.10.1</code></td>
        </tr>
        <tr>
            <td><strong>NAT Subnet</strong></td>
            <td><code>192.168.10.0/24</code></td>
        </tr>
    </tbody>
</table>
</section>

<section id="vlan-tests">
<h2>Why Enable VLAN ID on the Hyper-V Switch?</h2>
<p>Even if you don’t need VLANs <em>right now</em>, enabling VLAN ID will help you practice advanced networking scenarios in the future:</p>
<ul>
    <li><strong>DirectConnect Emulation:</strong> Simulate AWS/Azure DirectConnect (private VLANs over dedicated lines).</li>
    <li><strong>QinQ (802.1ad):</strong> Experiment with VLAN stacking for carrier-grade network scenarios.</li>
    <li><strong>Multi-Tenant Labs:</strong> Isolate different Kubernetes clusters or DevOps tools in separate VLANs.</li>
</ul>

<div class="CodeSnippet"><div class="CodeSnippet"><pre><code># Applying VLAN ID to a Hyper-V VM
Set-VMNetworkAdapterVlan -VMName "Proxmox-VM" -Access -VlanId 10

# In Proxmox, ensure:
bridge-vlan-aware yes
bridge-vids 2-4094
</code></pre></div></div>
</section>

<section id="conclusion-and-next-steps">
<h2>Next Steps: Kubernetes, IaC, & VLAN Experiments</h2>
<p>With our nested Proxmox environment running on a humble Dell Latitude, we now have a flexible setup for more advanced projects:</p>
<ul>
    <li><strong>Kubernetes Deployment:</strong> Spin up a small cluster in Proxmox VMs, explore a CNI (e.g., Calico or Flannel), and delve into Pod networking in a nested lab.</li>
    <li><strong>Infrastructure as Code (IaC):</strong> Use tools like Terraform and Ansible to automate provisioning and configuration. This is an excellent next step to refine your DevOps skillset.</li>
    <li><strong>Deep VLAN Config:</strong> Separate labs or apps on different VLANs to practice more advanced networking and micro-segmentation.</li>
</ul>
<p>There’s still plenty to learn, and the entire networking arena can get overwhelming. Take it one step at a time, and remember the principle: <strong>fail fast, learn relentlessly</strong>.</p>
<p><em>Do you have any Cloud Native projects in mind that you’d like to see tested on this potato-laptop lab?</em> Feel free to share your ideas—whether it’s ephemeral Kubernetes clusters, custom CI/CD pipelines, or specific open-source platforms. Let’s explore them together!</p>
</section>

        </section>

        <section id="conclusion">
          <h2>Conclusion</h2>
          <p>This nested Proxmox homelab might not be perfect, but it’s a testament to how resourceful we can be with secondhand gear and open-source software. By embracing occasional headaches—like NAT bridging and VLAN confusion—we grow stronger in our sysadmin and DevOps skills. The journey’s only begun. Next up, let’s tackle Kubernetes, get serious with IaC, and eventually master VLANs. Keep building, keep exploring, and keep learning!</p>
        </section>]]></content:encoded>
      <guid isPermaLink="false">https://thiago4go.github.io/posts/home-lab-series-part-1/</guid>
      <category>Homelab</category>
      <category>Proxmox</category>
      <category>Windows 10 Pro</category>
      <category>Cloud Native</category>
      <category>DevOps</category>
      <pubDate>Mon, 27 Jan 2025 00:00:00 +0000</pubDate>
    </item>
    <item>
      <title>Homelab Adventures: Solving the Networking Puzzle with Dual-Stack IPv4 and IPv6</title>
      <link>https://thiago4go.github.io/posts/home-lab-series-part-2/</link>
      <description>A comprehensive guide to setting up a dual-stack (IPv4 + IPv6) private subnet inside Proxmox using nftables for NAT, while Proxmox is nested under Hyper-V.</description>
      <content:encoded><![CDATA[<section id="intro">
          <p>Welcome back to Homelab Adventures! This is day 2, we’re tackling one of the most satisfying (and occasionally hair-pulling) challenges in homelab networking: creating a dual-stack IPv4/IPv6 private subnet inside a Proxmox VM that’s itself nested under Hyper-V. </p>
          <p>Why? Imagine running a K8s cluster where pods communicate over IPv6 while legacy services still rely on IPv4. Or hosting microservices that are ready for the future. Let’s solve this puzzle!</p>
        </section>

        <section id="content">
          <section id="high-level-overview">
    <h2>The Scenario: A Triple-Level Networking Cake</h2>
    <ul>
        <li><strong>Host Windows 10 + Hyper-V (level 1):</strong> Provides an Internal Switch with ICS on 192.168.10.1 (IPv4). The Proxmox VM (level 2) gets 192.168.10.10 from this network.</li>
        <li><strong>Proxmox VM (Level 2):</strong> Has vmbr0 with IPv4 192.168.10.10/24, gateway 192.168.10.1. Creates vmbr1 for private IPv4 and ULA IPv6, uses nftables for NAT, and runs dnsmasq for DHCP and RA services.</li>
        <li><strong>Guest VMs / LXCs (Level 3):</strong> Attach to vmbr1, receive DHCP for IPv4 and SLAAC/DHCPv6 for IPv6, and communicate internally and externally via NAT.</li>
    </ul>

    <h3>The goal? Let your inner VMs/LXCs:</h3>
    <ul>
        <li>Get IPv4 (192.168.200.x) and IPv6 ULA (fdc0:1234:abcd::/64) addresses automatically.</li>
        <li>NAT out to the internet via Proxmox’s vmbr0.</li>
        <li>Avoid Hyper-V MAC spoofing issues by keeping everything behind Proxmox’s single NIC.</li>
    </ul>

</section>

<section id="step-1">
    <h2>Step 1: Ensure Your Current Proxmox Network (vmbr0) is Working</h2>
    <div class="CodeSnippet"><div class="CodeSnippet"><pre><code>ip a show vmbr0
ping -c 3 8.8.8.8
ping -c 3 google.com</code></pre></div></div>
</section>

<section id="step-2">
    <h2>Step 2: Create vmbr1 for Private IPv4 + IPv6</h2>
    <h3>2.1 Add Configuration</h3>
    <p>Append to <code>/etc/network/interfaces</code>:</p>
    <div class="CodeSnippet"><div class="CodeSnippet"><pre><code>auto vmbr1
iface vmbr1 inet static
    address 192.168.200.1/24
    bridge-ports none
    bridge-stp off
    bridge-fd 0

iface vmbr1 inet6 static
    address fdc0:1234:abcd::1/64</code></pre></div></div>
    <h3>2.2 Bring Up the Interface</h3>
    <strong>Pro Tip:</strong> Generate a random ULA with  <kbd>openssl rand -hex 5</kbd> to avoid conflicts.
Restart networking:
    <div class="CodeSnippet"><div class="CodeSnippet"><pre><code>systemctl restart networking
ip addr show vmbr1  # Verify both IPs exist  </code></pre></div></div>
</section>

<section id="step-3">
    <h2>Step 3: Enable IP Forwarding</h2>
    <p>3.1 Edit <code>/etc/sysctl.conf</code> to ensure:</p>

    <div class="CodeSnippet"><div class="CodeSnippet"><pre><code>net.ipv4.ip_forward=1
net.ipv6.conf.all.forwarding=1</code></pre></div></div>
    <p>3.2 Apply the changes:</p>
    <div class="CodeSnippet"><div class="CodeSnippet"><pre><code>sysctl -p</code></pre></div></div>
    <p>This allows traffic forwarding/routing between interfaces for both IPv4 and IPv6.</p>
</section>

<section id="step-4">
    <h2>Step 4: Configure nftables for Dual-Stack NAT</h2>
    <p>Why nftables? It’s modern, flexible, and replaces iptables. We’ll use it to masquerade traffic from <code>vmbr1</code> to <code>vmbr0</code>.</p>
    <h3>4.1 Install nftables</h3>
    <div class="CodeSnippet"><div class="CodeSnippet"><pre><code>apt-get install nftables -y
</code></pre></div></div>
    <h3>4.2 Configure <code>/etc/nftables.conf</code></h3>
    <div class="CodeSnippet"><div class="CodeSnippet"><pre><code>#!/usr/sbin/nft -f
flush ruleset

# ----- IPv4 NAT table -----
table ip nat {
    chain prerouting {
        type nat hook prerouting priority 0; policy accept;
        # (Optional) Add DNAT rules here for port forwarding
        # e.g. tcp dport 2222 iif "vmbr0" dnat to 192.168.200.50:22
    }

    chain postrouting {
        type nat hook postrouting priority 100; policy accept;
        # Masquerade IPv4 from 192.168.200.0/24 going out vmbr0
        ip saddr 192.168.200.0/24 oif "vmbr0" masquerade
    }
} 

# ----- IPv6 NAT table (NAT66, optional) -----

</code></pre></div></div>
<p>NAT66 is non-standard and the upstream doesn't provide public IPv6, this won't truly give global v6 access. Skip it since we only need internal ULA.</p>
<h3>4.3 Apply the Configuration</h3>
    <div class="CodeSnippet"><div class="CodeSnippet"><pre><code>nft -f /etc/nftables.conf
nft list ruleset</code></pre></div></div>

<div class="Troubleshooting">
    <h3>4.4 Fix the “Interface Does Not Exist” Error</h3>
    <p>Proxmox starts nftables too early, before vmbr0 exists. Solve this with a custom service</p>
    <section id="png">
      <img src="/images/home-lab/interface-error.png" alt="Interface Error" style="display: block; margin-left: auto; margin-right: auto; max-width: 100%; height: auto;">
      </section>

      <h4>4.4.1 Create a Wait Script</h4>
<p>For instance, <code>/usr/local/bin/wait-for-vmbr0.sh</code>:</p>
<div class="CodeSnippet"><div class="CodeSnippet"><pre><code>#!/bin/bash
while ! ip link show vmbr0; do sleep 1; done  
systemctl restart nftables
</code></pre></div></div>

<h4>4.4.2 Make it executable</h4>
<div class="CodeSnippet"><div class="CodeSnippet"><pre><code>chmod +x /usr/local/bin/wait-for-vmbr0.sh</code></pre></div></div>

<h4>4.4.3 Create a Systemd Service</h4>
<p>For instance, <code>/etc/systemd/system/nftables-late.service</code>:</p>
<div class="CodeSnippet"><div class="CodeSnippet"><pre><code>[Unit]
Description=Load nftables rules after vmbr0 is up
After=network.target pve-firewall.service
Wants=network.target pve-firewall.service

[Service]
Type=oneshot
ExecStart=/usr/local/bin/wait-for-vmbr0.sh
RemainAfterExit=yes

[Install]
WantedBy=multi-user.target
</code></pre></div></div>

<h4>4.4.4 Enable and Start the Service</h4>
<div class="CodeSnippet"><div class="CodeSnippet"><pre><code>systemctl daemon-reload
systemctl enable nftables-late.service
systemctl start nftables-late.service</code></pre></div></div>
<p>On boot, this service will run your script, wait for vmbr0, then apply the nft rules</p>
</div>



</section>

<section id="step-5">
    <h2>Step 5: Install dnsmasq for DHCP</h2>
    <div class="CodeSnippet"><div class="CodeSnippet"><pre><code>apt-get install dnsmasq -y</code></pre></div></div>
    <h3>5.1 Edit configuration for <code>/etc/dnsmasq.d/vmbr1.conf</code>:</h3>
    <div class="CodeSnippet"><div class="CodeSnippet"><pre><code># Listen on vmbr1 only
interface=vmbr1

# ---- IPv4 DHCP ----
# IP range in 192.168.200.x
dhcp-range=192.168.200.100,192.168.200.200,12h
# Gateway (router) option
dhcp-option=3,192.168.200.1
# DNS server for IPv4 clients
dhcp-option=6,8.8.8.8,1.1.1.1

# ---- IPv6 DHCP/RA ----
# ULA prefix: fdc0:1234:abcd::/64
# For SLAAC + RA:
# Provide addresses from e.g. fdc0:1234:abcd::100 to ...::200
dhcp-range=::100,::200,constructor:vmbr1,64,12h
# Optionally advertise your gateway's IPv6 address as DNS
dhcp-option=option6:dns-server,[fdc0:1234:abcd::1]</code></pre></div></div>

<h3>5.2 Enable & Start dnsmasq:</h3>
<div class="CodeSnippet"><div class="CodeSnippet"><pre><code>systemctl enable dnsmasq
systemctl start dnsmasq</code></pre></div></div>
<p>Now, your VMs/LXCs will get IPv4 and IPv6 addresses automatically!</p>

</section>

<section id="step-6">
    <h2>Step 6: Validate setup with a VM/LCX</h2>
    <h3>6.1 Create a LXC attached to vmbr1</h3>
    <div class="CodeSnippet"><div class="CodeSnippet"><pre><code>pct create 101 local:vztmpl/debian-12-standard_12.7-1_amd64.tar.zst \
      --hostname mycontainer \
      --net0 name=eth0,bridge=vmbr1,ip=dhcp \
      --storage local-lvm \
      --cores 1 --memory 512</code></pre></div></div>
      <h3>6.2 Validate Connectivity</h3>
    <div class="CodeSnippet"><div class="CodeSnippet"><pre><code>pct start 101 #to start the container
pct enter 101 #to enter the container
ip addr show
ping 192.168.200.1
ping 8.8.8.8</code></pre></div></div>
</section>


<section id="step-9">
    <h2>Step 7: (Optional) Port Forwarding</h2>
    <p>For inbound connections to a particular container/VM from the 192.168.10.x network (or outside), add a DNAT rule in the prerouting chain for IPv4 or IPv6. For instance, in <code>/etc/nftables.conf</code>:</p>
    <div class="CodeSnippet"><div class="CodeSnippet"><pre><code>table ip nat {
      chain prerouting {
          type nat hook prerouting priority 0; policy accept;
          # Forward host port 2222 on vmbr0 to container 192.168.200.101:22
          tcp dport 2222 iif "vmbr0" dnat to 192.168.200.101:22
      }
      chain postrouting {
          type nat hook postrouting priority 100; policy accept;
          ip saddr 192.168.200.0/24 oif "vmbr0" masquerade
      }
  }</code></pre></div></div>
  <p>Then you can SSH from your Hyper-V host at 192.168.10.10:2222 → container 192.168.200.101:22.</p>
</section>

<section id="summary">
    <h2>Why Bother? The Bigger Picture</h2>
    <ul>
        <li><strong>Kubernetes:</strong> Run dual-stack clusters to test modern CNI plugins.</li>
        <li><strong>Isolation:</strong> Your Hyper-V host only sees Proxmox’s MAC, avoiding security headaches..</li>
        <li><strong>Future-Proofing:</strong> Experiment with IPv6 services today, even without ISP support</li>
    </ul>

</section>
        <section id="Quick Tips">
           <h2>Troubleshooting Quick Tips</h2>
<ul>
  <li><strong>No IPv6 RA</strong>: Check dnsmasq logs with <code>journalctl -u dnsmasq</code>.</li>
  <li><strong>NAT Failure</strong>: Verify <code>nft list ruleset</code> and ensure <code>vmbr0</code> is the correct outbound interface.</li>
  <li><strong>DHCP Timeouts</strong>: Ensure <code>vmbr1</code> is up and firewall rules aren’t blocking DHCP (port 67/68).</li>
</ul>
        </section>

        <section id="conclusion">
          <h2>Wrapping Up</h2>
          <p>After days of trial, error, and way too much coffee, I’ve emerged on the other side of this dual-stack puzzle—bruised but victorious. Building this setup taught me more about IPv6, NAT quirks, and dnsmasq’s dark magic than any tutorial ever could. And guess what? It works. My budget laptop now hums with nested Proxmox, IPv4/IPv6 harmony, and a private subnet that’s begging for prototyping cloud-native solutions.</p>
          <p>The real win? Understanding the guts of networking well enough to automate it. Soon, I’ll drop an Ansible playbook to replicate this config with a single command—because let’s face it, automation only shines when you’ve manually wrestled the beast first.</p>
          <p>What is next? Stay tuned for Part 3, where we’ll dive into the world of K8s, microservices, IoT simulations, and the joys of experimentation. Until then, keep breaking things (responsibly). The homelab grind never sleeps. 🚀
</p>
            <p>Homelab Adventures continues…</p>
        </section>]]></content:encoded>
      <guid isPermaLink="false">https://thiago4go.github.io/posts/home-lab-series-part-2/</guid>
      <category>Proxmox</category>
      <category>Networking</category>
      <category>IPv4</category>
      <category>IPv6</category>
      <category>NAT</category>
      <category>DHCP</category>
      <category>nftables</category>
      <category>K8S</category>
      <category>Microservices</category>
      <pubDate>Wed, 29 Jan 2025 00:00:00 +0000</pubDate>
    </item>
    <item>
      <title>Why I Built the Kubernetes Security Playbook (And How It Will Help You)</title>
      <link>https://thiago4go.github.io/posts/why-i-built-the-kubernetes-security-playbook-and-how-it-will-help-you/</link>
      <description>Post announcing the Kubernetes Security Playbook:</description>
      <content:encoded><![CDATA[<p>Post announcing the Kubernetes Security Playbook:</p><p><a href="https://www.linkedin.com/embed/feed/update/urn:li:share:7291032976509779968" target="_blank">https://www.linkedin.com/embed/feed/update/urn:li:share:7291032976509779968</a></p><blockquote><p><strong>Stop guessing at Kubernetes security. Get actionable advice and real-world fixes with the Kubernetes Security Playbook. Real problems, trusted frameworks, exam prep too! Subscribe now.</strong></p></blockquote><p>Hey cloud-native friends! 👋</p><p>Kubernetes is booming, powering modern infrastructure for millions. But with massive adoption comes massive security risk. Incidents are rising, costing companies and delaying deployments. We can't afford to guess at security anymore. To navigate this complex landscape and validate your skills, the <a href="https://training.linuxfoundation.org/certification/kubernetes-and-cloud-native-security-associate-kcsa/" target="_blank">KCSA certification</a> is becoming essential.</p><p><strong>That's why I built the </strong><a href="https://cloud-native.nikkei.one/" target="_blank"><strong>Kubernetes Security Playbook</strong></a><strong>.</strong> to help you master real-world Kubernetes security. Plus, it helps you prep for your exam.</p><p><strong>What to Expect:</strong> Real-World best practices and actionable advice &amp; fixes:</p><p><strong>This Week: Pod Security Standards (PSS)</strong></p><p>This article dives into <strong>Pod Security Standards: Baseline vs. Restricted Policies</strong>. Learn how PSS provides your essential first line of defense!</p><p>[Link to article: <a href="https://cloud-native.nikkei.one/kubernetes-security-fundamentals/kubernetes-security-fundamentals/pod-security-standards-pss-baseline-vs.-restricted-policies" target="_blank">https://cloud-native.nikkei.one/kubernetes-security-fundamentals/kubernetes-security-fundamentals/pod-security-standards-pss-baseline-vs.-restricted-policies</a>]</p><p><strong>Quick Security Updates:</strong></p><ul><li><p><strong>Microsoft Defender for Cloud:</strong> New RBAC integration boosts Kubernetes security visibility and attack path detection! [Link: <a href="https://techcommunity.microsoft.com/blog/microsoftdefendercloudblog/unveiling-kubernetes-lateral-movement-and-attack-paths-with-microsoft-defender-f/4374958" target="_blank">https://techcommunity.microsoft.com/blog/microsoftdefendercloudblog/unveiling-kubernetes-lateral-movement-and-attack-paths-with-microsoft-defender-f/4374958</a>]</p></li><li><p><strong>Kubernetes Security Report (Preview):</strong> Good news! Severe pod vulnerabilities are down 50% and high-privilege pods are decreasing. [Link: <a href="https://www.wiz.io/blog/kubernetes-report-preview-2025" target="_blank">https://www.wiz.io/blog/kubernetes-report-preview-2025</a>]</p></li></ul><p><strong>Want more bite-sized cloud-native goodness?</strong></p><p>Join me and other cloud enthusiasts at <strong>Down Under Cloud Nights: Bi-Weekly Bytes</strong>, hosted by <strong>Cloud Native Melbourne</strong>! It's a virtual, 40-minute speed run into cloud-native topics happening <strong>every other Monday.</strong></p><figure><!-- image removed (LinkedIn export link expired) — re-add from the original article if wanted --><figcaption></figcaption></figure><p><strong>Next Event: eBPF Revolution - Feb 10th!</strong></p><p>Learn how eBPF is transforming cloud-native computing.</p><p>[Link to Cloud Native Melbourne Page: <a href="https://community.cncf.io/cloud-native-melbourne/" target="_blank">https://community.cncf.io/cloud-native-melbourne/</a>]</p><p><strong>Secure your Kubernetes journey with the Kubernetes Security Playbook and stay connected with the community!</strong></p><p>Your Cloud-Native Friend,</p><p>Thiago, Kubestronaut.</p>]]></content:encoded>
      <guid isPermaLink="false">https://thiago4go.github.io/posts/why-i-built-the-kubernetes-security-playbook-and-how-it-will-help-you/</guid>
      <category>Kubernetes</category>
      <category>Security</category>
      <category>Cloud Native</category>
      <category>DevSecOps</category>
      <pubDate>Sat, 08 Feb 2025 00:00:00 +0000</pubDate>
    </item>
    <item>
      <title>Fortify Your Kubernetes: Master Supply Chain Security</title>
      <link>https://thiago4go.github.io/posts/fortify-your-kubernetes-master-supply-chain-security/</link>
      <description>Hey Cloud Native Security Champion! 👋</description>
      <content:encoded><![CDATA[<p>Hey Cloud Native Security Champion! 👋</p><p>Are you ready to level up your Kubernetes security game in 2025? With open source software expanding and supply chain threats becoming ever more critical, securing your software pipeline is no longer optional – it's mandatory. Regulations are coming, attacks are evolving, and proactive defense is the only way forward.</p><p>This week's Kubernetes Security Playbook deep dive is your guide to building a robust defense: <strong>"Supply Chain Security: SBOMs, SLSA, and Sigstore."</strong> Learn how to implement layered security using Software Bill of Materials (SBOMs), Supply-chain Levels for Software Artifacts (SLSA), and Sigstore to ensure the integrity and trustworthiness of your Kubernetes deployments. Stop vulnerabilities at the source and build confidence in your cloud-native stack!</p><p>Read the full post: <a href="https://cloud-native.nikkei.one/platform-security/platform-security/supply-chain-security-sboms-slsa-and-sigstore" target="_blank">https://cloud-native.nikkei.one/platform-security/platform-security/supply-chain-security-sboms-slsa-and-sigstore</a></p><p><strong>Quick Security Bytes:</strong></p><ul><li><p>🔐<strong>Microsoft Enhances AKS Security with Ratify:</strong> Learn how Azure Kubernetes Service is bolstering container image security by validating signatures using Ratify and Azure Policy. A practical step towards a more secure deployment pipeline! "<a href="https://learn.microsoft.com/en-us/azure/security/container-secure-supply-chain/articles/validating-image-signatures-using-ratify-aks" target="_blank">Securing AKS workloads: Validating container image signatures with Ratify and Azure Policy</a>"</p></li><li><p>✅<strong>Google Cloud's Transparency Boost for GKE:</strong> Google Kubernetes Engine is raising the bar on transparency by implementing SLSA Verification Summary Attestations for GKE components. Gain deeper insights into your software origins and ensure component integrity. "<a href="https://cloud.google.com/blog/products/identity-security/how-were-making-gke-more-secure-with-supply-chain-attestation-and-slsa" target="_blank">How we’re making GKE more transparent with supply-chain attestation and SLSA</a>" </p></li></ul><h3>Don't Miss Out! 🇦🇺 Cloud Native Down Under: Sustainability Speed Run!🍃♻️🏞️💚🌱</h3><p>Join Cloud Native Melbourne for a lightning-fast virtual session on <strong>Sustainability with Kepler</strong>! Discover how Kepler leverages eBPF to monitor energy consumption in Kubernetes and drive eco-friendly cloud-native practices. Happening <strong>TODAY</strong>!</p><figure><!-- image removed (LinkedIn export link expired) — re-add from the original article if wanted --><figcaption>Melbourne’s 40-Minute Cloud-Native Speed Run</figcaption></figure><p>Cloud Native Melbourne Event: <a href="https://community.cncf.io/events/details/cncf-cloud-native-melbourne-presents-down-under-cloud-nights-bi-weekly-bytes-2025-02-24/" target="_blank">https://community.cncf.io/events/details/cncf-cloud-native-melbourne-presents-down-under-cloud-nights-bi-weekly-bytes-2025-02-24/</a></p><p>Secure your supply chain, keep shipping trusted software! Dive into the Kubernetes Security Playbook and stay ahead of the curve.</p><p>Your Cloud-Native Friend,</p><p>Thiago, Kubestronaut.</p>]]></content:encoded>
      <guid isPermaLink="false">https://thiago4go.github.io/posts/fortify-your-kubernetes-master-supply-chain-security/</guid>
      <category>Kubernetes</category>
      <category>Security</category>
      <category>Cloud Native</category>
      <category>DevSecOps</category>
      <pubDate>Mon, 24 Feb 2025 00:00:00 +0000</pubDate>
    </item>
    <item>
      <title>Kubernetes Trust Boundaries?!</title>
      <link>https://thiago4go.github.io/posts/kubernetes-trust-boundaries/</link>
      <description>Hey Cloud Native Security Champion! 👋</description>
      <content:encoded><![CDATA[<p>Hey Cloud Native Security Champion! 👋</p><p>Are your Kubernetes trust boundaries clearly defined? They should be! Recent breaches prove misconfigurations are kubernetes' weakest link. Our latest post in the Kubernetes Security Playbook dives deep into <strong>mapping data flows and attack surfaces</strong> within your clusters.</p><p>🛡️ Learn to identify critical trust boundaries (you might be surprised where they are!) </p><p>🔑 Get actionable steps to enforce least privilege, zero trust networking, and more. </p><p>💥 Real-world incidents highlight the RIsks - are you protected?</p><p>Read the full post: <a href="https://cloud-native.nikkei.one/kubernetes-threat-model/kubernetes-threat-model/kubernetes-trust-boundaries-mapping-data-flows-and-attack-surfaces" target="_blank">Kubernetes Trust Boundaries: Mapping Data Flows and Attack Surfaces</a></p><h3>Quick Security Bytes:</h3><p><strong>"</strong><a href="https://learn.microsoft.com/en-us/azure/defender-for-cloud/support-matrix-defender-for-containers?tabs=azureva%2Cazurert%2Cazurespm%2Cawsnet" target="_blank"><strong>Learn Azure Defender for Cloud Containers support matrix in Defender for Cloud</strong></a><strong>"</strong>: This doc clearly defines the <strong>boundaries of protection</strong> offered by Microsoft Defender for Cloud for container workloads. It specifies what features are supported for different environments (Azure, AWS, GCP, external registries), operating systems, and Kubernetes distributions.</p><p><strong>"</strong><a href="https://aws.amazon.com/about-aws/whats-new/2025/03/amazon-eks-envelope-encrypts-kubernetes-api-data-default/" target="_blank"><strong>Amazon EKS now envelope encrypts all Kubernetes API data by default</strong></a><strong>"</strong>: This announcement highlights a <strong>strengthening of the security boundary</strong> within Amazon EKS. By default encrypting Kubernetes API data, Amazon is reinforcing the <strong>data protection boundary</strong> for EKS clusters, making it harder for unauthorized access even if the control plane is compromised.</p><p><strong>"</strong><a href="https://techcommunity.microsoft.com/blog/microsoftdefendercloudblog/integrating-security-into-devops-workflows-with-microsoft-defender-cspm/4388094" target="_blank"><strong>Integrating Security into DevOps Workflows with Microsoft Defender CSPM</strong></a><strong>"</strong>: This blog post directly addresses the concept of <strong>shifting security boundaries left</strong> in the development lifecycle. This is about defining and enforcing security boundaries not just at runtime, but also during development and deployment.</p><h3>Don't miss tonight's Down Under Cloud Nights! 🚀🌏</h3><p>Join Cloud Native Melbourne for <strong>Lap #3: DevEx with Inspektor Gadget &amp; mirrord!</strong></p><p>📅 <strong>When:</strong> TODAY, Mar 10, 7:00–7:40 PM (GMT+11)</p><p>📍 <strong>Where:</strong> Virtual (Limited Zoom seats available!)</p><p>Seats are filling fast—secure your spot now!</p><p>🔗 <a href="https://community.cncf.io/events/details/cncf-cloud-native-melbourne-presents-down-under-cloud-nights-bi-weekly-bytes-2025-03-10/" target="_blank">Register Here</a></p><p>Discover how <strong>Inspektor Gadget</strong> leverages eBPF to provide real-time Kubernetes debugging, monitoring network traffic, file I/O, and system calls. Plus, see how <strong>mirrord</strong> mirrors production traffic to local environments, solving the dreaded "works on my machine" syndrome.</p><figure><!-- image removed (LinkedIn export link expired) — re-add from the original article if wanted --><figcaption>Cloud Native Melbourne</figcaption></figure><p>Don't wait for the next breach to learn about trust boundaries. Arm yourself with knowledge from the Kubernetes Security Playbook and community insights from Down Under Cloud Nights. <strong>Secure your Kubernetes environment today, for peace of mind tomorrow.</strong></p><p>Your Cloud-Native Friend,</p><p>Thiago, Kubestronaut.</p>]]></content:encoded>
      <guid isPermaLink="false">https://thiago4go.github.io/posts/kubernetes-trust-boundaries/</guid>
      <category>Kubernetes</category>
      <category>Security</category>
      <category>Cloud Native</category>
      <category>DevSecOps</category>
      <pubDate>Sun, 09 Mar 2025 00:00:00 +0000</pubDate>
    </item>
    <item>
      <title>Secure &amp; Sovereign AI: The Spark (Log 0)</title>
      <link>https://thiago4go.github.io/posts/secure-sovereign-ai-the-spark-log-0/</link>
      <description>For the past two years, I have been a tourist in the land of intelligence. Like everyone else, I have been typing prompts into chat boxes, marveling at the</description>
      <content:encoded><![CDATA[<p>For the past two years, I have been a tourist in the land of intelligence. Like everyone else, I have been typing prompts into chat boxes, marveling at the magic tricks, renting wisdom by the token.</p><p>But I am a <strong>Kubestronaut</strong>. My background is built on the bedrock of orchestration. And as I looked closer at the "magic" of AI, the mist cleared. I realized that under the hood, the ghost in the machine is just a workload. AI is just containers. AI is just Kubernetes with heavier math.</p><p>I decided to stop renting. I decided to build.</p><p>To do that, I needed iron. I needed sovereignty. My modest homelab was fine for running Plex and a few microservices, but the game has changed. You cannot build the future on yesterday’s silicon.</p><h3>The Object of Desire</h3><p>Then, the email arrived.</p><blockquote><p><strong>Subject:</strong> Your DGX Spark is Ready for Purchase <strong>Reservation #26525</strong></p></blockquote><p>The specs read like science fiction transcribed into a receipt:</p><ul><li><p><strong>Two DGX Spark units</strong></p></li><li><p><strong>NVIDIA GB10 Grace Blackwell Superchip</strong></p></li><li><p><strong>NVIDIA GB10 Grace Blackwell Superchip</strong></p></li><li><p><strong>128GB of coherent, unified system memory</strong></p></li><li><p><strong>1 PFLOPS of FP4 AI performance</strong></p></li><li><p><strong>ConnectX-7 Smart NIC</strong></p></li><li><p><strong>4TB Self-Encrypting NVMe</strong></p></li></ul><p>Total: <strong>$8,049.00</strong>.</p><figure><!-- image removed (LinkedIn export link expired) — re-add from the original article if wanted --><figcaption></figcaption></figure><p>It is a salty price tag. But for 1 Petaflop of compute that fits in a carry-on? It wasn’t a purchase; it was a transfer of power.</p><h3>The Weekend Run</h3><p>There was a catch. They shipped to the US. I am in Australia.</p><p>A rational person would use a freight forwarder. A rational person would wait. I am not a rational person; I am building a sovereign AI lab.</p><p>I booked a flight.</p><p>It was the most paranoid trip of my life. I left Australia on Friday. I landed in the US, retrieved the package—my precious cargo, the silicon brain of my future infrastructure—and turned right back around.</p><p><strong>Melbourne → Los Angeles → New York → Los Angeles → Sydney → Melbourne.</strong></p><p>A weekend round-trip for hardware.</p><p>Returning to Sydney, I felt like a character in a bad episode of <em>Border Control</em>. I walked the green line—no, the red line. I declared it. I paid the taxes. I stood there, exhausted, clutching a box containing two Grace Blackwell superchips, waiting for a customs officer to ask me why a man needs a Petaflop in his luggage.</p><p>I walked out into the Australian sun, lighter in the wallet but heavy with potential.</p><h3>The Nest</h3><p>You cannot just plug a DGX Spark into the wall and hope for the best. You do not treat a superchip like a toaster.</p><p>I looked at my home office. It wasn't ready.</p><p>I went into procurement mode. If I was going to run enterprise-grade AI, I needed enterprise-grade stability.</p><ul><li><p><strong>Power:</strong> A new UPS 1600VA. If the grid flickers, the AI must not blink.</p></li><li><p><strong>Networking:</strong> New switches, new NICs. I had to build a Bastion to protect the crown jewels.</p></li></ul><p>And then, the humble reality of high-tech engineering: I was two cables short.</p><p>There I was, holding the cutting edge of NVIDIA’s Blackwell architecture, forced to make a frantic, mundane run to <strong>Officeworks</strong> on a Sunday afternoon for generic patch cables. The contrast was perfect.</p><p>Everything is connected. The UPS is humming. The Bastion is racked. The Sparks are energized.</p><p>The holiday is over. The tourist phase is done.</p><p><strong>Next:</strong> We turn on the lights. In <strong>Part 1</strong>, we design the network architecture that keeps this beast fed, secure, and silent.</p>]]></content:encoded>
      <guid isPermaLink="false">https://thiago4go.github.io/posts/secure-sovereign-ai-the-spark-log-0/</guid>
      <category>Secure AI</category>
      <category>MLOps</category>
      <category>Kubernetes</category>
      <category>Homelab</category>
      <category>AI Sovereignty</category>
      <category>DGX Spark</category>
      <pubDate>Sun, 21 Dec 2025 00:00:00 +0000</pubDate>
    </item>
    <item>
      <title>The Paranoia of Packets (Log 1: The Network)</title>
      <link>https://thiago4go.github.io/posts/the-paranoia-of-packets-log-1-the-network/</link>
      <description>Outside, across the spectral waste of the grand unwashed WAN, the bots crawl like irradiated cockroaches. They sniff at ports, rattle digital doorknobs, an</description>
      <content:encoded><![CDATA[<p>Outside, across the spectral waste of the grand unwashed WAN, the bots crawl like irradiated cockroaches. They sniff at ports, rattle digital doorknobs, and send a cacophony of SYN packets screaming into the void. You do not want them in here.</p><p>You want the silence.</p><p>You want the <strong>Sovereign AI Lab</strong>, but sovereignty is a paradox—to rule, you must first build the walls, yet to govern, you must maintain the lines of supply. We are not building a network; we are constructing a filter against the entropy of the open web. And because true security demands obscurity, we do not publish our maps. We publish only the architecture of the maze.</p><h3>The Double-Blind Shell Game</h3><p>Consider the topology not as a tree, but as a series of airlocks. The traffic arrives from the ISP, wet and chaotic, hitting the <strong>Primary Router</strong>. It is a pedestrian device, a decoy. The traffic thinks it has found home. It hasn’t.</p><p>It flows downstream to the <strong>Secondary Router</strong>, the second layer of the onion, the bureaucratic obfuscation where the real work begins. This is the <strong>Double NAT</strong>—a geometric frustration for the uninvited. But sitting there, humming in the rack, is the <strong>Bastion</strong>. It is the gatekeeper. It is the three-faced Janus.</p><h3>The Bastion: Maxwell’s Demon in Rocky Linux</h3><p>The Bastion is not merely a server; it is a checkpoint Charlie for packets. It possesses three distinct nervous systems, three interfaces wired into the kernel’s cortex:</p><ul><li><p><strong>The External Face:</strong> Staring into the WAN, taking the brunt of the noise from the upstream network.</p></li><li><p><strong>The Internal Face:</strong> The gateway to the Sanctum, the <strong>Compute Zone</strong>.</p></li><li><p><strong>The Ghost Face:</strong> The WireGuard interface. The wormhole.</p></li></ul><p>This Bastion runs , a piece of software acting as the adjudicator of truth. It implements a ruthless logic: nothing enters the Compute Zone without a visa.</p><h3>The Compute Zone: Where the GPUs Dream</h3><p>Deep inside a private, unrouted subnet lie the heavy irons—the <strong>DGX Spark nodes</strong> and the Kubernetes Control Plane. This is the Secure Compute Zone.</p><p>Here, the air is still. The silence is absolute. These machines cannot see the internet. If a node tries to ping Google, the packet hits the Bastion and dies, rejected by a rich rule in the firewall configuration. It is a digital Faraday cage.</p><p>But the machines must eat. They need updates, Python wheels, Docker layers. Enter <strong>Squid</strong>, the transparent proxy.</p><p>The Bastion runs Squid on a local port. It intercepts HTTP/HTTPS traffic from the Compute Zone. It inspects the destination. Is it ? Is it ? If the destination is on the whitelist, the packet is blessed and sent forth. If it is some unknown telemetry endpoint trying to phone home, it is dissolved into nothingness.</p><h3>The WireGuard Wormhole</h3><p>How do <em>you</em>, the architect, enter this hermetically sealed tomb? You do not open a door. You fold space.</p><p>We use <strong>WireGuard</strong> on a specific UDP port, a protocol of elegant, cryptographic silence. Unlike the chatty VPNs of old that announce their presence with elaborate handshakes, WireGuard stays silent until it sees a key it recognizes.</p><p>The path is circuitous, a Rube Goldberg mechanism of routing:</p><p>Your client, drifting somewhere on the 4G cellular ether, sends a packet to the public endpoint. The Primary Router catches it, sees the UDP tag, and flings it to the Bastion’s dedicated backchannel interface, separate from the primary wired WAN.</p><p>The key turns. The tunnel opens. Suddenly, you are bilocated. Your physical body is in a coffee shop; your digital soul is inside the Compute Zone, SSH-ing into the DGX Spark as if you were sitting on the rack.</p><figure><!-- image removed (LinkedIn export link expired) — re-add from the original article if wanted --><figcaption></figcaption></figure><p>We have built a fortress. The GPUs are safe. The data is sovereign. The silence is ours.</p><p><strong>Next:</strong> Now that the walls are up, we must fill the void. In <strong>Part 2</strong>, we descend into the <strong>Setup</strong>, where we will attempt to birth a Kubernetes cluster inside this vacuum—and discover the agony of the whitelist.</p>]]></content:encoded>
      <guid isPermaLink="false">https://thiago4go.github.io/posts/the-paranoia-of-packets-log-1-the-network/</guid>
      <category>Secure AI</category>
      <category>MLOps</category>
      <category>Kubernetes</category>
      <category>Homelab</category>
      <category>AI Sovereignty</category>
      <category>DGX Spark</category>
      <pubDate>Sun, 21 Dec 2025 00:00:00 +0000</pubDate>
    </item>
    <item>
      <title>The Agony of the Whitelist (Log 2: The Setup)</title>
      <link>https://thiago4go.github.io/posts/the-agony-of-the-whitelist-log-2-the-setup/</link>
      <description>The silence of the Compute Zone is not peaceful; it is heavy, the kind of absolute acoustic deadness you find in antechambers before the airlock cycles. We</description>
      <content:encoded><![CDATA[<p>The silence of the <strong>Compute Zone</strong> is not peaceful; it is heavy, the kind of absolute acoustic deadness you find in antechambers before the airlock cycles. We have constructed a digital Faraday cage, a hermetic seal against the howling entropy of the public internet, and inside this sterile box, we intend to cultivate the delicate orchid of a Kubernetes cluster.</p><p>The theory is sovereignty. The reality is that we have locked ourselves in a room with no windows and are now surprised that we cannot see the sky.</p><h3>The Invocation of the Void</h3><p>You sit at the terminal of the control plane, a <strong>Proxmox VM</strong> humming with the naive potential of a blank slate. The cursor blinks, a rhythmic taunt. You type the invocation, the command that has worked a thousand times in the promiscuous, open-air markets of AWS and Azure: <em>kubeadm init</em>.</p><p>You wait for the cascade of ASCII green, the dopamine rush of successful initialization.</p><p>Instead, the console hangs. A timeout. The machine is screaming into the void, trying to phone home to <a href="http://registry.k8s.io" target="_blank">registry.k8s.io</a>, but the line is dead. There is no route. There is only the <strong>Bastion</strong>, sitting at the edge of the world, an unsmiling bureaucrat enforcing a policy of total embargo.</p><p>This is the price of paranoia. You cannot simply install software in a sovereign lab; you must petition for it. You open a second terminal, tunneling through <strong>WireGuard</strong> to the Bastion, and begin the forensic audit of the Squid proxy logs.</p><pre></pre><p>The screen fills with the carnage of rejection. <strong>TCP_DENIED. TCP_DENIED</strong>. The modern software stack reveals itself not as a monolith, but as a desperate, sprawling organism, firing tendrils out to every corner of the globe, begging for dependencies. You see the requests piling up against the firewall: <a href="http://cdn.dl.k8s.io" target="_blank">cdn.dl.k8s.io</a>, <a href="http://quay.io" target="_blank">quay.io</a>, <a href="http://production.cloudflare.docker.com" target="_blank">production.cloudflare.docker.com</a>.</p><h3>The Customs Officer</h3><p>You are no longer an engineer; you are a customs officer in a Kafka novel. You open the configuration file <em>/etc/squid/squid.conf</em>, the ledger of allowed thoughts. You type the domains in, one by one, granting visas to these digital travelers. You restart the proxy. You run <strong>kubeadm </strong>again. </p><p>It advances. It pulls the core images. And then it chokes again.</p><p>The logs reveal a new, more insidious truth. You expected to whitelist a few project domains, perhaps a <strong>GitHub </strong>repository. But there, buried in the CONNECT requests, is the hallucination:</p><pre></pre><p>You stare at it. Your sovereign, on-premise, strictly controlled AI lab—built on local NVMe and owned hardware—is secretly trying to hold hands with a random storage bucket in Oregon. It turns out that Cloud Native is often just a euphemism for Hidden S3 Dependencies. The infrastructure of the independent web is a facade; scratch the surface of a <strong>CNCF </strong>project, and you bleed Amazon object storage.</p><p>If you had left the firewall open, you would be blissfully ignorant, pulling blobs from the ether, unaware of the invisible tethers binding your sovereign AI to a datacenter three thousand miles away. But here, in the silence of the vacuum, the dependencies are loud.</p><h3>The Compromise</h3><p>You add the wildcard to the whitelist. You feel the compromise in your bones, but <em>kubeadm </em>finally completes its ritual. The control plane initializes.</p><p>The pain of the whitelist, the agony of tracking down every single redirect and CNAME, is the only proof that the cage is working. You have mapped the veins of the system, and now, finally, the brain is alive.</p><figure><!-- image removed (LinkedIn export link expired) — re-add from the original article if wanted --><figcaption></figcaption></figure><p><strong>Next</strong>: The infrastructure is breathing. The power is stable. The network is secure. Now, we stop building walls and start teaching the machine to think. <strong>In Part 3</strong>, we finally start making use of the NVIDIA stack and begin our journey into Deep Learning with the Game of Go.</p>]]></content:encoded>
      <guid isPermaLink="false">https://thiago4go.github.io/posts/the-agony-of-the-whitelist-log-2-the-setup/</guid>
      <category>Secure AI</category>
      <category>MLOps</category>
      <category>Kubernetes</category>
      <category>Homelab</category>
      <category>AI Sovereignty</category>
      <category>DGX Spark</category>
      <pubDate>Sun, 21 Dec 2025 00:00:00 +0000</pubDate>
    </item>
    <item>
      <title>Designing for Consistency (Log 3: The State)</title>
      <link>https://thiago4go.github.io/posts/designing-for-consistency-log-3-the-state/</link>
      <description>Good design requires good conceptual models. When I look at a system, I should be able to understand its state simply by looking at it. But in the world of</description>
      <content:encoded><![CDATA[<p>Good design requires good conceptual models. When I look at a system, I should be able to understand its state simply by looking at it. But in the world of infrastructure, servers are often black boxes. We configure them manually, changing a setting here, a file there, until the mental model in our heads no longer matches the reality on the disk. This is a failure of design. It creates what I call a "<strong>gulf of evaluation</strong>"—I cannot know the state of the system just by observing it.</p><p>I have built the <a href="https://www.linkedin.com/pulse/paranoia-packets-log-1-network-thiago-s-shimada-ramos-uhj6c/" target="_blank">network (Log 1)</a> and <a href="https://www.linkedin.com/pulse/agony-whitelist-log-2-setup-thiago-s-shimada-ramos-15vsc/" target="_blank">initialized the cluster (Log 2)</a>, but without a proper design for managing state, the system is brittle. It invites human error.</p><p>To solve this, I must change the affordances of the system. I must make the invisible visible</p><figure><!-- image removed (LinkedIn export link expired) — re-add from the original article if wanted --><figcaption></figcaption></figure><h3>The System Image: GitOps as a Conceptual Model</h3><p>I refuse to configure servers by hand (I use <em>Kiro</em>, btw). To do so is to create a system that cannot be understood or reproduced. Instead, I adopt <strong>GitOps</strong>.</p><p>GitOps is not just a tool; it is a design philosophy. It ensures that the "system image"—the code in the repository—always matches the physical state of the cluster.</p><p>I deployed <strong>Gitea</strong> on the management network to serve as the single source of truth. This is where the intent is stored. Then, I introduced <strong>ArgoCD</strong> into the cluster. Think of ArgoCD as a feedback mechanism. It constantly compares my intent (the Git repo) with the reality (the Kubernetes cluster). If they drift apart, it signals an error. It forces the system back into alignment. This provides the visibility and feedback that are essential for good control.</p><h3>Designing for Persistence (NFS)</h3><p>Computers are ephemeral; data must be permanent. The design challenge here is mapping the abstract concept of "storage" to the physical constraints of the hardware.</p><p>I designated the Proxmox host and a future NAS to act as the NFS backend. But good design imposes constraints, so I carved the storage into distinct categories based on their function:</p><ul><li><p>/srv/k8s/datasets: This is for raw inputs. The policy is "Retain" because the cost of re-acquiring data is high.</p></li><li><p>/srv/k8s/models: This is for the output—the trained intelligence. It is also "Retained".</p></li><li><p>/srv/k8s/artifacts: This is for temporary workspace. The policy is "Delete," signaling its transient nature.</p></li></ul><p>By mapping these directories to Kubernetes StorageClasses, I created a natural mapping. When a pod requests "datasets," the system intuitively knows where to look.</p><h3>The Affordance of Recovery</h3><p>A well-designed system must handle errors gracefully. It must assume that things will go wrong. In the physical world, we have safety rails. In the digital world, we have backups.</p><p>However, the traditional backup process is flawed. It usually involves copying data to a local disk before moving it off-site. This introduces a point of failure—what if the local disk is full? What if it is corrupted?</p><p>I designed a "stream-based" backup workflow that eliminates this intermediate step. I wrote a script that pipes the data directly from the virtualization layer (vzdump) to the cloud storage (az blob upload).</p><p>The data flows from the memory of the Bastion, encrypts in transit, and rests securely in an <strong>Azure Blob Storage</strong> container in Australia. The design is elegant because it removes unnecessary steps. It reduces the cognitive load. I do not have to worry about local disk space. I only have to trust the stream.</p><p><strong>Next:</strong> The system now has memory and a reliable way to manage its own state. In <strong>Log 4</strong>, I must address the interaction between the user and the machine. I must wake the brain.</p>]]></content:encoded>
      <guid isPermaLink="false">https://thiago4go.github.io/posts/designing-for-consistency-log-3-the-state/</guid>
      <category>Secure AI</category>
      <category>MLOps</category>
      <category>Kubernetes</category>
      <category>Homelab</category>
      <category>AI Sovereignty</category>
      <category>DGX Spark</category>
      <pubDate>Mon, 22 Dec 2025 00:00:00 +0000</pubDate>
    </item>
    <item>
      <title>Log 4 – The Idiot Savant</title>
      <link>https://thiago4go.github.io/posts/log-4-the-idiot-savant/</link>
      <description>Sub-Series: How to Train Your Bot (Part 1 of 4)</description>
      <content:encoded><![CDATA[<p><strong>Sub-Series: How to Train Your Bot (Part 1 of 4)</strong></p><p>In Log 3, I talked about the <strong>Gulf of Evaluation</strong>—the difficulty of knowing the state of the system. But now I face its twin, the <strong>Gulf of Execution</strong>. This is the gap between what I <em>want</em> the system to do and the means the system provides to do it.</p><p>Right now, that gulf is massive.</p><h3>Bridging the Gulf with AI</h3><p>Let’s be real: I didn’t bridge this gap by writing boilerplate code by hand. That is the old way. I leveraged the very thing I am trying to build.</p><p>I used <strong>Kiro, Gemini, ChatGPT, and Perplexity</strong>. I treated them as my team of engineers. I used them to brainstorm, to generate the Kubernetes manifests, debug the Python syntax, and explain the obscure error messages. I stopped thinking about the <em>syntax</em> of the bridge and focused entirely on the <em>architecture</em>.</p><p>By leaning on these tools, I condensed weeks of frustration into few days</p><p>We have spent the last few logs building the temple. We racked the DGX Sparks, wrestled the Kubernetes networking into submission, and locked down the security. The infrastructure is beautiful. It’s a Ferrari with the engine idling. But a Ferrari sitting in a garage isn’t a race car; it’s just expensive furniture.</p><p>Now, I turn the key.</p><p>This marks the start of a new phase. I’m moving from <strong>Hardware &amp; Orchestration</strong> to <strong>Applied Machine Learning</strong>. I’m following the roadmap from <em>Deep Learning and the Game of Go by </em>Kevin Ferguson and Max Pumperla<em> (</em><a href="https://amzn.to/49t64uQ" target="_blank"><strong>https://amzn.to/49t64uQ</strong></a><em>)</em>, but I’m doing it my way: inside a sovereign, containerized, GPU-accelerated cluster.</p><figure><!-- image removed (LinkedIn export link expired) — re-add from the original article if wanted --><figcaption></figcaption></figure><h3>Defining the Universe</h3><p>To cross the gulf, I first had to define the laws of physics for this new universe. Therefore before you can train an AI to dominate a world, you first have to create that world.</p><p>In design terms, the rules of Go are <strong>constraints</strong>. They tell the agent what is possible. I had to code the concept of "Liberties" (the empty points that allow a stone to breathe) and "Capture" (what happens when those liberties vanish). I had to strictly define "Ko"—the rule that prevents the game from entering an infinite loop.</p><p>If I get this wrong, the "System Image" fails. The bot will try to do things that physics doesn't allow, and the gulf will widen again.</p><p>This isn't AI. This is just the plumbing. It’s the digital equivalent of gravity.</p><h3>Meet the "Agent" (The Idiot Savant)</h3><p>Once the physics were working, I wrote my first bot.</p><p>In the industry, we use fancy terms like "Agent" or "Actor." It implies intelligence. It implies intent.</p><p>My agent is... well, it’s an idiot.</p><p>I implemented what is effectively a <strong>Random Bot</strong>. It looks at the board, asks the physics engine, "What moves are legal?" and then rolls a virtual die.</p><p>It has no strategy. It has no fear. It has no desire to win. It just <em>does</em>.</p><p>I set it loose on the 9x9 board, running on the most advanced consumer grade silicon NVIDIA has ever produced. It placed stones with the confidence of a grandmaster and the logic of a goldfish.</p><figure><!-- image removed (LinkedIn export link expired) — re-add from the original article if wanted --><figcaption></figcaption></figure><h3>The Problem with Random</h3><p>Watching two Random Bots play against each other is a surreal experience. Because they don't understand the concept of "territory" or "winning," they don't know when to stop.</p><p>Humans stop playing when the boundaries are clear. We look at the board, nod to our opponent, and say, "Okay, that's your territory."</p><p>This bot? It’s stubborn. It keeps placing stones until literally every legal spot on the board is filled. It will fill in its own eyes. It will kill its own groups. It plays until the game collapses under the weight of its own absurdity.</p><h3>Why This Matters (The "Sovereign" Flex)</h3><p>You might ask: <em>"Why did you buy two DGX Spark nodes and build a Kubernetes cluster just to run a random number generator?"</em></p><p>That’s a fair question. I could run this Random Bot on a Raspberry Pi. I could have just installed Python directly on the metal and been done with it.</p><p>But here is the difference: <strong>Architecture</strong>.</p><p>I didn't just write a script. I deployed a <strong>System</strong>.</p><p>I’m not running this locally on my laptop; I’m running it as a defined job in a namespace. My code is decoupled from the hardware. Today, the "Brain" block of my system is a simple random function. Tomorrow, I can swap that block out for a <strong>Deep Neural Network</strong>, and the rest of the pipeline—the board state, the game rules, the scoring engine—doesn't need to change.</p><p>This is what sets this design apart from just using the Spark out of the box. I have laid the foundation for a <strong>Multi-Agent System</strong>. I can spin up fifty of these bots in parallel containers, have them play a thousand games in seconds, and aggregate the results. The DGX isn't sweating yet, but the plumbing is ready for the flood.</p><h3>The Baseline</h3><p>This Random Bot is terrible, but it is crucial. It gives me a <strong>Baseline</strong>.</p><p>Right now, my win rate is 50/50 (because it’s random vs. random). This is the floor. Everything I do from this point on—every neural network I design, every reinforcement learning loop I run—has to beat this idiot.</p><p>The engine is started. The physics work. The bot is alive, even if it is completely mindless.</p><p><strong>Next Log:</strong> We stop rolling dice. We give the bot some lessons. We start feeding it human games and teaching it to mimic the masters. We enter the world of <strong>Machine Learning</strong>, Tree Search algorithms, which are essential tools in game AI and all kinds of optimization problems. Deep Learning, Neural Networks, Reinforcement Learning! Are you excited?!</p>]]></content:encoded>
      <guid isPermaLink="false">https://thiago4go.github.io/posts/log-4-the-idiot-savant/</guid>
      <category>Secure AI</category>
      <category>MLOps</category>
      <category>Kubernetes</category>
      <category>Homelab</category>
      <category>AI Sovereignty</category>
      <category>DGX Spark</category>
      <pubDate>Wed, 24 Dec 2025 00:00:00 +0000</pubDate>
    </item>
  </channel>
</rss>
