<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Kubernetes on Landry Zetam - Tech Blog</title><link>https://blog.landryzetam.net/tags/kubernetes/</link><description>Recent content in Kubernetes on Landry Zetam - Tech Blog</description><generator>Hugo -- gohugo.io</generator><language>en-us</language><lastBuildDate>Mon, 10 Aug 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://blog.landryzetam.net/tags/kubernetes/index.xml" rel="self" type="application/rss+xml"/><item><title>The Full Architecture of My Kubernetes Agents</title><link>https://blog.landryzetam.net/posts/kubernetes-agents-full-architecture/</link><pubDate>Mon, 10 Aug 2026 00:00:00 +0000</pubDate><guid>https://blog.landryzetam.net/posts/kubernetes-agents-full-architecture/</guid><description>&lt;p>Five agents run against my K3s cluster. Three of them form a closed loop — one detects problems, one fixes them, one reviews the fix — and none of the three can do another&amp;rsquo;s job. This is everything about how they&amp;rsquo;re built: the framework, the prompt assembly, every tool, both safety gates, the memory layers, and a real pull request one of them opened.&lt;/p>
&lt;p>Then I merged it and spent a day fixing what production found. Eight more bugs, none of them in the agent logic — §17 onward is that day, and it&amp;rsquo;s the more useful half.&lt;/p></description></item><item><title>NetworkPolicy vs AuthorizationPolicy: One Decides If the Call Connects, the Other Decides If Anyone Answers</title><link>https://blog.landryzetam.net/posts/network-policy-vs-authorization-policy/</link><pubDate>Thu, 11 Jun 2026 00:00:00 +0000</pubDate><guid>https://blog.landryzetam.net/posts/network-policy-vs-authorization-policy/</guid><description>&lt;p>Kubernetes gives you two resources that both look like &amp;ldquo;firewall rules for pods,&amp;rdquo; and most teams deploy one and assume they got the other for free. They didn&amp;rsquo;t. The two policies operate at different layers, speak different languages, and fail in completely different ways — and you almost certainly need both.&lt;/p>
&lt;h2 id="the-setup">The Setup&lt;/h2>
&lt;p>Picture a cluster running a service mesh (Istio, in my case) with a typical three-tier layout: an ingress gateway, a handful of API services, and a PostgreSQL database listening on port 5432. The security requirement sounds simple: only the API services should reach the database, and only the gateway should reach the APIs. The first instinct is to reach for &lt;em>a&lt;/em> policy — and Kubernetes hands you two that both claim to do this. &lt;code>NetworkPolicy&lt;/code> ships with Kubernetes itself (enforced by your CNI — Cilium, Calico). &lt;code>AuthorizationPolicy&lt;/code> ships with Istio (enforced by the Envoy sidecar). Same goal on paper, very different machinery underneath.&lt;/p></description></item><item><title>Building a Production-Grade Home Network with UniFi VLANs</title><link>https://blog.landryzetam.net/posts/unifi-vlan-home-network/</link><pubDate>Tue, 23 Dec 2025 00:00:00 +0000</pubDate><guid>https://blog.landryzetam.net/posts/unifi-vlan-home-network/</guid><description>&lt;p>Your home network doesn&amp;rsquo;t have to be a flat, insecure mess where your smart toaster can talk to your NAS. With UniFi gear and some intentional design, you can build network segmentation that rivals enterprise setups—without the enterprise price tag. This is how I architected a 10-VLAN home network that isolates everything from security cameras to a 7-node Kubernetes cluster.&lt;/p>
&lt;hr>
&lt;h2 id="part-1-the-design-philosophy">Part 1: The Design Philosophy&lt;/h2>
&lt;h3 id="why-segment-at-all">Why Segment at All?&lt;/h3>
&lt;p>Most home networks run everything on a single subnet. Your laptop, your Ring cameras, your kids&amp;rsquo; tablets, and your IoT light bulbs all share the same network space. This creates several problems:&lt;/p></description></item><item><title>GitOps Framework: How the Fako Cluster Repository is Organized</title><link>https://blog.landryzetam.net/posts/gitops-framework/</link><pubDate>Sun, 21 Dec 2025 00:00:00 +0000</pubDate><guid>https://blog.landryzetam.net/posts/gitops-framework/</guid><description>&lt;h2 id="overview">Overview&lt;/h2>
&lt;p>The Fako Cluster uses a GitOps approach where &lt;strong>Git is the single source of truth&lt;/strong> for all cluster state. Every deployment, configuration change, and infrastructure update flows through Git commits. FluxCD watches the repository and automatically reconciles the cluster to match the desired state defined in code.&lt;/p>
&lt;p>This post explains the repository structure, the reasoning behind each directory, and how the pieces work together.&lt;/p>
&lt;h2 id="repository-structure">Repository Structure&lt;/h2>
&lt;pre tabindex="0">&lt;code>fako-cluster/
├── apps/ # Application deployments
│ ├── base/ # Base Kustomize configurations
│ └── staging/ # Environment overlay (what actually deploys)
├── clusters/ # Cluster bootstrap and Flux config
│ └── staging/ # Flux Kustomizations that orchestrate everything
├── infrastructure/ # Platform components
│ ├── controllers/ # Operators (Cert-Manager, CloudNative-PG, etc.)
│ └── configs/ # Configuration for controllers
├── monitoring/ # Observability stack
│ ├── controllers/ # Prometheus, Loki, Grafana, etc.
│ └── configs/ # Dashboards, alerting rules
├── scripts/ # Deployment and maintenance scripts
└── notes/ # Documentation and troubleshooting
&lt;/code>&lt;/pre>&lt;h2 id="the-basestaging-pattern">The Base/Staging Pattern&lt;/h2>
&lt;p>The most important concept to understand is the &lt;strong>base/staging pattern&lt;/strong> used throughout the repository.&lt;/p></description></item><item><title>From Transcripts to Summaries: Completing the Audio Pipeline</title><link>https://blog.landryzetam.net/posts/transcripts-to-summaries-audio-pipeline/</link><pubDate>Sat, 20 Dec 2025 00:00:00 +0000</pubDate><guid>https://blog.landryzetam.net/posts/transcripts-to-summaries-audio-pipeline/</guid><description>&lt;p>Remember that audio transcription pipeline I built? Raw recordings flow in, get compressed, transcribed by Whisper, and stored as JSON. Great for archival, but 204 transcript files sitting on NFS storage aren&amp;rsquo;t exactly useful. Today I&amp;rsquo;ll show you how I completed the loop—automatically summarizing transcripts with an LLM and publishing everything to my Obsidian vault.&lt;/p>
&lt;hr>
&lt;h2 id="part-1-the-problem-with-raw-transcripts">Part 1: The Problem with Raw Transcripts&lt;/h2>
&lt;p>The original pipeline worked beautifully. Every morning, new transcripts appeared as JSON files:&lt;/p></description></item><item><title>Complete Kubernetes Security Pipeline - Kube-bench and Kubescape to Obsidian</title><link>https://blog.landryzetam.net/posts/kubernetes-security-pipeline-kubebench-kubescape/</link><pubDate>Fri, 19 Dec 2025 00:00:00 +0000</pubDate><guid>https://blog.landryzetam.net/posts/kubernetes-security-pipeline-kubebench-kubescape/</guid><description>&lt;p>What if your Kubernetes cluster could write comprehensive security reports directly into your second brain every night? Not just one perspective, but two complementary views: infrastructure security &lt;em>and&lt;/em> workload security. I built exactly that—a pipeline combining kube-bench (CIS benchmarks) and kubescape (NSA/MITRE frameworks) that publishes human-readable reports to Obsidian automatically. Here&amp;rsquo;s how the complete system works.&lt;/p>
&lt;hr>
&lt;h2 id="part-1-why-you-need-both-tools">Part 1: Why You Need Both Tools&lt;/h2>
&lt;h3 id="the-security-visibility-gap">The Security Visibility Gap&lt;/h3>
&lt;p>Running a Kubernetes homelab means wearing many hats. Security scanning tools exist, but most people either:&lt;/p></description></item><item><title>Prometheus WAL Replay: When Your Metrics Database Can't Start Fast Enough</title><link>https://blog.landryzetam.net/posts/prometheus-wal-replay/</link><pubDate>Thu, 18 Dec 2025 00:00:00 +0000</pubDate><guid>https://blog.landryzetam.net/posts/prometheus-wal-replay/</guid><description>&lt;p>There&amp;rsquo;s a special kind of frustration that comes from watching a pod restart 90 times over 37 hours, each time getting &lt;em>just&lt;/em> a little further before Kubernetes kills it again. Today I debugged a Prometheus instance stuck in an infinite crash loop, and the root cause was surprisingly subtle: the database was simply too large to start within the default health check window.&lt;/p>
&lt;p>This is the story of startup probes, Write-Ahead Logs, and why your monitoring system might be the hardest thing to monitor.&lt;/p></description></item><item><title>Building a Kubernetes Security Reporter for Obsidian</title><link>https://blog.landryzetam.net/posts/kubernetes-security-reporter-obsidian/</link><pubDate>Wed, 17 Dec 2025 00:00:00 +0000</pubDate><guid>https://blog.landryzetam.net/posts/kubernetes-security-reporter-obsidian/</guid><description>&lt;p>What if your Kubernetes cluster could automatically write security reports directly into your second brain? Today I built exactly that—a system that runs CIS benchmark scans against my K3s cluster and publishes the results as beautifully formatted Obsidian notes. No more checking dashboards or parsing JSON files; just open your vault and see your cluster&amp;rsquo;s security posture.&lt;/p>
&lt;hr>
&lt;h2 id="part-1-the-problem">Part 1: The Problem&lt;/h2>
&lt;h3 id="security-visibility-in-a-homelab">Security Visibility in a Homelab&lt;/h3>
&lt;p>Running a Kubernetes homelab means wearing many hats: developer, operator, and security engineer. Tools like &lt;a href="https://github.com/aquasecurity/kube-bench">kube-bench&lt;/a> exist to scan your cluster against CIS benchmarks, but they typically output JSON or text that sits in a PersistentVolume gathering dust.&lt;/p></description></item><item><title>Enabling DNS-01 TLS for Internal Kubernetes Services</title><link>https://blog.landryzetam.net/posts/dns01-tls-kubernetes-internal-services/</link><pubDate>Tue, 16 Dec 2025 00:00:00 +0000</pubDate><guid>https://blog.landryzetam.net/posts/dns01-tls-kubernetes-internal-services/</guid><description>&lt;p>Ever visited a website and seen that little padlock icon in your browser? That&amp;rsquo;s TLS at work, encrypting the connection between you and the server. But what happens when you want that same security for services running on your home network that aren&amp;rsquo;t accessible from the internet? Today I solved this exact problem, and I want to walk you through not just &lt;em>how&lt;/em> I did it, but &lt;em>why&lt;/em> each piece matters.&lt;/p></description></item><item><title>Building an Automated Audio Transcription Pipeline on Kubernetes</title><link>https://blog.landryzetam.net/posts/audio-transcription-pipeline/</link><pubDate>Fri, 12 Dec 2025 00:00:00 +0000</pubDate><guid>https://blog.landryzetam.net/posts/audio-transcription-pipeline/</guid><description>&lt;p>Every day, raw audio recordings land on an SFTP server. By morning, they&amp;rsquo;re compressed, transcribed, and stored as searchable JSON - all without human intervention. Here&amp;rsquo;s how I built this pipeline on my homelab Kubernetes cluster.&lt;/p>
&lt;h2 id="the-problem">The Problem&lt;/h2>
&lt;p>I had a growing collection of audio recordings that needed transcription. Manual processing wasn&amp;rsquo;t sustainable: download files, compress them, run through a transcription service, organize the output. This needed automation.&lt;/p>
&lt;p>The requirements were straightforward:&lt;/p></description></item><item><title>Building an Oura Ring Health Dashboard with Streamlit</title><link>https://blog.landryzetam.net/posts/oura-dashboard/</link><pubDate>Fri, 08 Aug 2025 00:00:00 +0000</pubDate><guid>https://blog.landryzetam.net/posts/oura-dashboard/</guid><description>&lt;h2 id="overview">Overview&lt;/h2>
&lt;p>Oura Dashboard is a Streamlit-based web application deployed in the Fako cluster that provides interactive visualization of health data collected from the Oura Ring. It connects to the PostgreSQL database populated by the Oura Collector service and presents comprehensive health insights through charts, graphs, and analytics. The dashboard is secured with OAuth2 authentication and provides personalized health tracking capabilities for sleep, activity, readiness, and heart rate metrics.&lt;/p>
&lt;h2 id="key-features">Key Features&lt;/h2>
&lt;ul>
&lt;li>&lt;strong>Interactive Visualizations&lt;/strong>: Real-time charts and graphs using Streamlit&lt;/li>
&lt;li>&lt;strong>Comprehensive Metrics&lt;/strong>: Sleep, activity, readiness, and HRV analytics&lt;/li>
&lt;li>&lt;strong>OAuth2 Authentication&lt;/strong>: Secure access with OAuth2 proxy&lt;/li>
&lt;li>&lt;strong>PostgreSQL Integration&lt;/strong>: Direct database queries for data&lt;/li>
&lt;li>&lt;strong>Responsive Design&lt;/strong>: Mobile-friendly interface&lt;/li>
&lt;li>&lt;strong>Health Trends&lt;/strong>: Long-term pattern analysis&lt;/li>
&lt;li>&lt;strong>Custom Reports&lt;/strong>: Exportable health summaries&lt;/li>
&lt;li>&lt;strong>Real-time Updates&lt;/strong>: Auto-refresh capabilities&lt;/li>
&lt;/ul>
&lt;h2 id="architecture">Architecture&lt;/h2>
&lt;h3 id="components">Components&lt;/h3>
&lt;ol>
&lt;li>&lt;strong>Streamlit App&lt;/strong>: Python-based web dashboard&lt;/li>
&lt;li>&lt;strong>OAuth2 Proxy&lt;/strong>: Authentication layer&lt;/li>
&lt;li>&lt;strong>Service&lt;/strong>: ClusterIP on port 8501&lt;/li>
&lt;li>&lt;strong>Ingress&lt;/strong>: HTTPS access with authentication&lt;/li>
&lt;li>&lt;strong>External Secrets&lt;/strong>: AWS Secrets Manager integration&lt;/li>
&lt;li>&lt;strong>Database Connection&lt;/strong>: PostgreSQL read access&lt;/li>
&lt;/ol>
&lt;h3 id="resource-requirements">Resource Requirements&lt;/h3>
&lt;ul>
&lt;li>&lt;strong>Memory&lt;/strong>: 256Mi (request), 512Mi (limit)&lt;/li>
&lt;li>&lt;strong>CPU&lt;/strong>: 100m (request), 500m (limit)&lt;/li>
&lt;li>&lt;strong>Storage&lt;/strong>: EmptyDir for temporary data&lt;/li>
&lt;li>&lt;strong>Port&lt;/strong>: 8501 (Streamlit default)&lt;/li>
&lt;/ul>
&lt;h2 id="configuration">Configuration&lt;/h2>
&lt;h3 id="environment-settings">Environment Settings&lt;/h3>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>Parameter&lt;/th>
&lt;th>Value&lt;/th>
&lt;th>Description&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>&lt;code>DATABASE_NAME&lt;/code>&lt;/td>
&lt;td>&lt;code>app&lt;/code>&lt;/td>
&lt;td>PostgreSQL database&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>DAYS_TO_BACKFILL&lt;/code>&lt;/td>
&lt;td>&lt;code>7&lt;/code>&lt;/td>
&lt;td>Default data range&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>LOG_LEVEL&lt;/code>&lt;/td>
&lt;td>&lt;code>INFO&lt;/code>&lt;/td>
&lt;td>Application logging&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>API_TIMEOUT&lt;/code>&lt;/td>
&lt;td>&lt;code>30&lt;/code>&lt;/td>
&lt;td>Query timeout&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;h3 id="oauth2-configuration">OAuth2 Configuration&lt;/h3>
&lt;p>Protected by OAuth2 proxy for secure access:&lt;/p></description></item><item><title>Home Assistant Voice Pipeline with Ollama</title><link>https://blog.landryzetam.net/posts/voice-pipeline/</link><pubDate>Fri, 08 Aug 2025 00:00:00 +0000</pubDate><guid>https://blog.landryzetam.net/posts/voice-pipeline/</guid><description>&lt;h2 id="overview">Overview&lt;/h2>
&lt;p>This implementation demonstrates a complete voice assistant pipeline using Wyoming Satellite with Home Assistant and Ollama as the AI brain, achieving natural conversation and smart home control entirely on-premises. The system transforms spoken words into meaningful actions through a sophisticated pipeline of AI models, all running locally for complete privacy.&lt;/p>
&lt;h2 id="why-ollama-for-voice">Why Ollama for Voice?&lt;/h2>
&lt;p>Voice assistants have unique requirements that Ollama handles beautifully:&lt;/p>
&lt;h3 id="speed-requirements">Speed Requirements&lt;/h3>
&lt;ul>
&lt;li>&lt;strong>Response Time&lt;/strong>: &amp;lt; 2 seconds for natural conversation&lt;/li>
&lt;li>&lt;strong>Model Loading&lt;/strong>: Pre-loaded models for instant responses&lt;/li>
&lt;li>&lt;strong>Streaming&lt;/strong>: Real-time token generation for faster perceived response&lt;/li>
&lt;/ul>
&lt;h3 id="privacy-first">Privacy First&lt;/h3>
&lt;ul>
&lt;li>&lt;strong>Local Processing&lt;/strong>: No cloud dependencies&lt;/li>
&lt;li>&lt;strong>Conversation History&lt;/strong>: Stored locally, never uploaded&lt;/li>
&lt;li>&lt;strong>Custom Wake Words&lt;/strong>: Combined with OpenWakeWord for complete privacy&lt;/li>
&lt;/ul>
&lt;h2 id="components-used">Components Used&lt;/h2>
&lt;ul>
&lt;li>&lt;strong>OpenWakeWord&lt;/strong>: Wake word detection (&amp;ldquo;Hey Jarvis&amp;rdquo;)&lt;/li>
&lt;li>&lt;strong>Whisper&lt;/strong>: Speech-to-text transcription&lt;/li>
&lt;li>&lt;strong>Ollama (Qwen2.5:3b &amp;amp; Llama 8B)&lt;/strong>: Natural language understanding and response generation&lt;/li>
&lt;li>&lt;strong>Piper TTS&lt;/strong>: Text-to-speech synthesis&lt;/li>
&lt;li>&lt;strong>Home Assistant&lt;/strong>: Smart home orchestration and pipeline management&lt;/li>
&lt;li>&lt;strong>Wyoming Satellite&lt;/strong>: Voice satellite software on Raspberry Pi&lt;/li>
&lt;/ul>
&lt;h2 id="hardware-setup">Hardware Setup&lt;/h2>
&lt;ul>
&lt;li>&lt;strong>Raspberry Pi 5&lt;/strong> (2.4GHz, 4GB RAM) - Voice satellite device&lt;/li>
&lt;li>&lt;strong>ME6S USB Microphone&lt;/strong> - Audio input device&lt;/li>
&lt;li>&lt;strong>Bluetooth Speaker&lt;/strong> (88:92:CC:5D:CB:79) - Audio output via BlueALSA&lt;/li>
&lt;li>&lt;strong>Mini PC&lt;/strong> - Home Assistant server&lt;/li>
&lt;li>&lt;strong>Kubernetes Cluster&lt;/strong> - Container orchestration for AI services&lt;/li>
&lt;li>&lt;strong>NVIDIA GPU Node (yeezyai)&lt;/strong> - GPU acceleration for Ollama&lt;/li>
&lt;/ul>
&lt;h2 id="the-voice-pipeline-architecture">The Voice Pipeline Architecture&lt;/h2>
&lt;p>The voice pipeline runs entirely on the K8s homelab, with Ollama at its heart:&lt;/p></description></item><item><title>Powering Open WebUI and Cline with GPUStack: My AI Infrastructure Journey</title><link>https://blog.landryzetam.net/posts/local-ai-open-webui-cline/</link><pubDate>Fri, 08 Aug 2025 00:00:00 +0000</pubDate><guid>https://blog.landryzetam.net/posts/local-ai-open-webui-cline/</guid><description>&lt;p>After building my Mac AI cluster, I needed a way to make it accessible to all my tools. The journey took me through several frameworks before landing on the perfect solution: GPUStack providing an OpenAI-compatible API that seamlessly integrates with everything.&lt;/p>
&lt;h2 id="the-evolution-finding-the-right-framework">The Evolution: Finding the Right Framework&lt;/h2>
&lt;h3 id="the-journey">The Journey&lt;/h3>
&lt;p>My path to the current setup wasn&amp;rsquo;t straightforward:&lt;/p>
&lt;ol>
&lt;li>&lt;strong>MLX Distributed Computing&lt;/strong>: Started here for model training and local inference on Apple Silicon&lt;/li>
&lt;li>&lt;strong>Exo Labs&lt;/strong>: Experimented with this promising framework, but pivoted when the community began a redesign&lt;/li>
&lt;li>&lt;strong>GPUStack&lt;/strong>: The solution that finally clicked - providing OpenAI-compatible endpoints that work with everything&lt;/li>
&lt;/ol>
&lt;h2 id="the-current-architecture">The Current Architecture&lt;/h2>
&lt;p>Here&amp;rsquo;s how my AI infrastructure actually works:&lt;/p></description></item><item><title>From GitHub Notes to Production Blog</title><link>https://blog.landryzetam.net/posts/hugo-blogging/</link><pubDate>Thu, 07 Aug 2025 00:00:00 +0000</pubDate><guid>https://blog.landryzetam.net/posts/hugo-blogging/</guid><description>&lt;h2 id="why-this-guide-exists">Why This Guide Exists&lt;/h2>
&lt;p>I&amp;rsquo;ve been doing a lot of dev work, research and hadn&amp;rsquo;t really thought about sharing the knowledge without having to learn frontend development or maintain complex code. I knew I had a bunch of markdown GitHub notes and thought they could be used as a baseline to catch up on all my lack of documentation. Then I found Hugo.&lt;/p>
&lt;p>This guide covers the entire workflow of creating a Hugo blog, containerizing it, and deploying it to Kubernetes - all without writing a single line of frontend code (html, css, js).&lt;/p></description></item><item><title>Running 184 Pods on a 6-Node K3s Homelab Cluster</title><link>https://blog.landryzetam.net/posts/k8s/</link><pubDate>Thu, 07 Aug 2025 00:00:00 +0000</pubDate><guid>https://blog.landryzetam.net/posts/k8s/</guid><description>&lt;h2 id="project-overview">Project Overview&lt;/h2>
&lt;p>The Fako Cluster is my production Kubernetes environment that serves as the foundation for all other projects. It&amp;rsquo;s a self-hosted, production-grade K8s cluster that demonstrates enterprise-level practices while running on homelab hardware.&lt;/p>
&lt;h3 id="why-fako">Why &amp;ldquo;Fako&amp;rdquo;?&lt;/h3>
&lt;p>The name &amp;ldquo;Fako&amp;rdquo; holds special significance - it&amp;rsquo;s named after Mount Fako (Mount Cameroon), the highest peak in West and Central Africa. Just as Mount Fako stands as a towering landmark visible from miles away, this Kubernetes cluster serves as the foundational infrastructure that all other services can rely on.&lt;/p></description></item><item><title>Securing GitOps: SOPS Secret Management in k8s with FluxCD</title><link>https://blog.landryzetam.net/posts/secrets-management-with-sops-flux-gitops/</link><pubDate>Thu, 07 Aug 2025 00:00:00 +0000</pubDate><guid>https://blog.landryzetam.net/posts/secrets-management-with-sops-flux-gitops/</guid><description>&lt;h2 id="the-problem-secrets-in-gitops">The Problem: Secrets in GitOps&lt;/h2>
&lt;p>When I started my Kubernetes homelab journey, I quickly hit a wall that every GitOps practitioner faces: &lt;strong>How do you store secrets in Git without compromising security?&lt;/strong>&lt;/p>
&lt;p>The GitOps philosophy is beautifully simple - everything should be in Git. Your entire cluster state, all your applications, configurations, and yes, even secrets. But committing passwords, API keys, and certificates to a public (or even private) repository feels fundamentally wrong. It is wrong.&lt;/p></description></item><item><title>Self-Hosting n8n on Kubernetes for AI Automation</title><link>https://blog.landryzetam.net/posts/n8n/</link><pubDate>Thu, 07 Aug 2025 00:00:00 +0000</pubDate><guid>https://blog.landryzetam.net/posts/n8n/</guid><description>&lt;h2 id="overview">Overview&lt;/h2>
&lt;p>N8N is an open-source workflow automation tool deployed in the Fako cluster. It provides a visual interface for creating complex automation workflows, integrating with hundreds of services and APIs. N8N allows you to automate repetitive tasks, connect different services, and build sophisticated data pipelines without extensive coding.&lt;/p>
&lt;h2 id="key-features">Key Features&lt;/h2>
&lt;ul>
&lt;li>&lt;strong>Visual Workflow Builder&lt;/strong>: Drag-and-drop interface for creating automations&lt;/li>
&lt;li>&lt;strong>200+ Integrations&lt;/strong>: Pre-built nodes for popular services&lt;/li>
&lt;li>&lt;strong>Self-Hosted&lt;/strong>: Full control over your data and workflows&lt;/li>
&lt;li>&lt;strong>PostgreSQL Backend&lt;/strong>: Reliable storage using the cluster&amp;rsquo;s PostgreSQL&lt;/li>
&lt;li>&lt;strong>Webhook Support&lt;/strong>: Trigger workflows via HTTP webhooks&lt;/li>
&lt;li>&lt;strong>Custom Functions&lt;/strong>: JavaScript code support for complex logic&lt;/li>
&lt;li>&lt;strong>Fair-Code License&lt;/strong>: Source available with sustainable business model&lt;/li>
&lt;/ul>
&lt;h2 id="architecture">Architecture&lt;/h2>
&lt;h3 id="components">Components&lt;/h3>
&lt;ol>
&lt;li>&lt;strong>Deployment&lt;/strong>: Single-replica deployment (stateful workflows)&lt;/li>
&lt;li>&lt;strong>Service&lt;/strong>: ClusterIP service on port 5678&lt;/li>
&lt;li>&lt;strong>Ingress&lt;/strong>: HTTPS access at &lt;code>n8n.landryzetam.net&lt;/code>&lt;/li>
&lt;li>&lt;strong>Storage&lt;/strong>: PersistentVolumeClaim for workflow data&lt;/li>
&lt;li>&lt;strong>Database&lt;/strong>: PostgreSQL for workflow definitions and execution data&lt;/li>
&lt;li>&lt;strong>External Secrets&lt;/strong>: Database credentials from AWS Secrets Manager&lt;/li>
&lt;/ol>
&lt;h3 id="resource-requirements">Resource Requirements&lt;/h3>
&lt;ul>
&lt;li>&lt;strong>Memory&lt;/strong>: 512Mi (request), 2Gi (limit)&lt;/li>
&lt;li>&lt;strong>CPU&lt;/strong>: 250m (request), 1000m (limit)&lt;/li>
&lt;li>&lt;strong>Storage&lt;/strong>: Persistent volume for N8N data and files&lt;/li>
&lt;li>&lt;strong>Database&lt;/strong>: Uses shared PostgreSQL cluster&lt;/li>
&lt;/ul>
&lt;h2 id="configuration">Configuration&lt;/h2>
&lt;h3 id="environment-settings">Environment Settings&lt;/h3>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>Parameter&lt;/th>
&lt;th>Value&lt;/th>
&lt;th>Description&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>&lt;code>N8N_HOST&lt;/code>&lt;/td>
&lt;td>&lt;code>n8n.landryzetam.net&lt;/code>&lt;/td>
&lt;td>External hostname&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>N8N_PORT&lt;/code>&lt;/td>
&lt;td>&lt;code>5678&lt;/code>&lt;/td>
&lt;td>Application port&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>N8N_PROTOCOL&lt;/code>&lt;/td>
&lt;td>&lt;code>https&lt;/code>&lt;/td>
&lt;td>External protocol&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>WEBHOOK_URL&lt;/code>&lt;/td>
&lt;td>&lt;code>https://n8n.landryzetam.net/&lt;/code>&lt;/td>
&lt;td>Webhook base URL&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>GENERIC_TIMEZONE&lt;/code>&lt;/td>
&lt;td>&lt;code>America/New_York&lt;/code>&lt;/td>
&lt;td>Timezone for scheduling&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>N8N_METRICS&lt;/code>&lt;/td>
&lt;td>&lt;code>true&lt;/code>&lt;/td>
&lt;td>Enable metrics endpoint&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>N8N_TEMPLATES_ENABLED&lt;/code>&lt;/td>
&lt;td>&lt;code>true&lt;/code>&lt;/td>
&lt;td>Enable workflow templates&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;h3 id="database-configuration">Database Configuration&lt;/h3>
&lt;ul>
&lt;li>&lt;strong>Type&lt;/strong>: PostgreSQL&lt;/li>
&lt;li>&lt;strong>Host&lt;/strong>: &lt;code>postgres-cluster-rw.postgres.svc.cluster.local&lt;/code>&lt;/li>
&lt;li>&lt;strong>Database&lt;/strong>: &lt;code>app&lt;/code>&lt;/li>
&lt;li>&lt;strong>User&lt;/strong>: &lt;code>app&lt;/code>&lt;/li>
&lt;li>&lt;strong>Password&lt;/strong>: Managed via External Secrets&lt;/li>
&lt;/ul>
&lt;h2 id="usage">Usage&lt;/h2>
&lt;h3 id="accessing-n8n">Accessing N8N&lt;/h3>
&lt;p>External access:&lt;/p></description></item><item><title>GitOps in Practice: Managing k8s with FluxCD</title><link>https://blog.landryzetam.net/posts/gitops-with-fluxcd/</link><pubDate>Wed, 06 Aug 2025 00:00:00 +0000</pubDate><guid>https://blog.landryzetam.net/posts/gitops-with-fluxcd/</guid><description>&lt;p>After running the Fako Cluster for several months, I can confidently say that adopting GitOps with FluxCD has been one of the best decisions for managing my Kubernetes infrastructure. In this post, I&amp;rsquo;ll share practical insights and patterns that have proven invaluable.&lt;/p>
&lt;h2 id="what-is-gitops">What is GitOps?&lt;/h2>
&lt;p>GitOps is a way of implementing Continuous Deployment for cloud native applications.
FluxCD is designed to simplify that, making it easier than ever to manage your Kubernetes environments. Here’s why i leverage it in my workflow:&lt;/p></description></item></channel></rss>