<?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 Casey Robb</title><link>https://neozeon.io/categories/kubernetes/</link><description>Recent content in Kubernetes on Casey Robb</description><generator>Hugo</generator><language>en</language><lastBuildDate>Wed, 21 Oct 2026 08:46:18 -0600</lastBuildDate><atom:link href="https://neozeon.io/categories/kubernetes/index.xml" rel="self" type="application/rss+xml"/><item><title>Thirty Apps, One Repo: Anatomy of a GitOps Homelab Cluster</title><link>https://neozeon.io/posts/chaos-cluster-anatomy/</link><pubDate>Sun, 18 Oct 2026 19:30:00 -0600</pubDate><guid>https://neozeon.io/posts/chaos-cluster-anatomy/</guid><description>&lt;h2 id="thirty-apps-one-repo-anatomy-of-a-gitops-homelab-cluster"&gt;Thirty Apps, One Repo: Anatomy of a GitOps Homelab Cluster&lt;/h2&gt;
&lt;p&gt;Somewhere between running my first app on Kubernetes and running my thirtieth,
the problem changed shape. It stopped being &amp;ldquo;how do I deploy this&amp;rdquo; and became
&amp;ldquo;how do I know what my cluster &lt;em&gt;is&lt;/em&gt;, and how do I change it without
nuking &amp;amp; paving.&amp;rdquo; My answer is a single GitLab repo &lt;a href="https://gitlab.com/caseyrobb/iac"&gt;gitlab.com/caseyrobb/iac&lt;/a&gt;: one ApplicationSet
generator, one allowlist per cluster, one thin wrapper chart per app, and a
handful of infrastructure operators doing the rest. The production cluster,
&lt;code&gt;chaos&lt;/code&gt; (k0s, six nodes on mini PCs at home — no, the name is not
prophetic; mostly), runs thirty-two apps out of that repo and has never had a
&lt;code&gt;kubectl apply&lt;/code&gt; from a human.&lt;/p&gt;</description></item><item><title>Serving OpenShift VIPs from OpenBSD: relayd, pf, and unbound as Your Cluster's Load Balancer</title><link>https://neozeon.io/posts/ocp-relayd-unbound-pf/</link><pubDate>Sat, 17 Oct 2026 18:45:00 -0600</pubDate><guid>https://neozeon.io/posts/ocp-relayd-unbound-pf/</guid><description>&lt;h2 id="serving-openshift-vips-from-openbsd-relayd-pf-and-unbound"&gt;Serving OpenShift VIPs from OpenBSD: relayd, pf, and unbound&lt;/h2&gt;
&lt;p&gt;OpenShift is unusual among Kubernetes distros in how much it demands from your
network before it will install itself: three virtual IPs (API, internal API, and
wildcard ingress), DNS that resolves all three &lt;em&gt;before the first node boots&lt;/em&gt;,
and a healthcheck contract for your load balancer that is spelled out almost
to the millisecond in the install docs. In the cloud this is someone else&amp;rsquo;s
problem, on bare metal it is yours.&lt;/p&gt;</description></item><item><title>Using OpenBSD's OpenBGPD and Cilium for k0s Networking</title><link>https://neozeon.io/posts/k0s-cilium-bgpd/</link><pubDate>Fri, 16 Oct 2026 13:31:00 -0700</pubDate><guid>https://neozeon.io/posts/k0s-cilium-bgpd/</guid><description>&lt;h2 id="using-openbsds-openbgpd-and-cilium-for-k0s-networking"&gt;Using OpenBSD&amp;rsquo;s OpenBGPD and Cilium for k0s Networking&lt;/h2&gt;
&lt;p&gt;If you&amp;rsquo;re running a bare-metal or on-premises Kubernetes cluster, one of the biggest challenges is making your services accessible to the rest of your network. While NodePorts and traditional reverse proxies work, running BGP (Border Gateway Protocol) natively gives you a much more elegant, scalable, and true-to-cloud experience.&lt;/p&gt;
&lt;p&gt;In this post, we&amp;rsquo;ll walk through how to configure an OpenBSD router running &lt;strong&gt;OpenBGPD&lt;/strong&gt; to peer with a &lt;strong&gt;k0s&lt;/strong&gt; Kubernetes cluster using &lt;strong&gt;Cilium&lt;/strong&gt; as the CNI (Container Network Interface). This allows Cilium to announce LoadBalancer IP pools and Pod CIDRs directly to your network&amp;rsquo;s core router.&lt;/p&gt;</description></item></channel></rss>