<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:atom="http://www.w3.org/2005/Atom" version="2.0">
    <channel>
      <title>Alek&#x27;s Blog - networking</title>
      <link>https://blog.none.at</link>
      <description>Production notes on Kubernetes, OpenShift, and OVHcloud: observability, log archiving, service mesh, LLM inference, and digital sovereignty.</description>
      <generator>Zola</generator>
      <language>en</language>
      <atom:link href="https://blog.none.at/tags/networking/rss.xml" rel="self" type="application/rss+xml"/>
      <lastBuildDate>Sat, 18 Jul 2026 00:00:00 +0000</lastBuildDate>
      <item>
          <title>ingress-nginx Annotation Compatibility Matrix</title>
          <pubDate>Sat, 18 Jul 2026 00:00:00 +0000</pubDate>
          <author>aleks</author>
          <link>https://blog.none.at/blog/2026/2026-07-18-ingress-nginx-annotation-matrix/</link>
          <guid>https://blog.none.at/blog/2026/2026-07-18-ingress-nginx-annotation-matrix/</guid>
          <description xml:base="https://blog.none.at/blog/2026/2026-07-18-ingress-nginx-annotation-matrix/">&lt;p&gt;Part 2 built the inventory. This part answers the question that inventory exists to feed: for the
annotations that actually turn out to be hard cases — not every annotation, but the ones where the
answer isn’t obvious — does migration go cleanly, or does it silently break? The honest answer
changes row by row — and, in one case in this matrix, changes depending on the &lt;em&gt;value&lt;&#x2F;em&gt; of the
annotation, not just its name.&lt;&#x2F;p&gt;</description>
      </item>
      <item>
          <title>ingress-nginx Replacement Candidates: Envoy, HAProxy, NGINX</title>
          <pubDate>Sat, 18 Jul 2026 00:00:00 +0000</pubDate>
          <author>aleks</author>
          <link>https://blog.none.at/blog/2026/2026-07-18-ingress-nginx-candidates/</link>
          <guid>https://blog.none.at/blog/2026/2026-07-18-ingress-nginx-candidates/</guid>
          <description xml:base="https://blog.none.at/blog/2026/2026-07-18-ingress-nginx-candidates/">&lt;p&gt;Part 3 answered which annotations survive a migration and which don’t. This part answers the
question that matrix exists to feed into: given those findings, which target do you actually move
to? Five candidates get the same source-verified depth as Part 3’s matrix here — not because the other
seven considered for this series are less real, but because “tested with the same rigor” and
“worth a mention” are different claims, and this guide tries not to blur them.&lt;&#x2F;p&gt;</description>
      </item>
      <item>
          <title>ingress-nginx Hard Cases: Auth, Rate Limits, gRPC, Snippets</title>
          <pubDate>Sat, 18 Jul 2026 00:00:00 +0000</pubDate>
          <author>aleks</author>
          <link>https://blog.none.at/blog/2026/2026-07-18-ingress-nginx-hard-cases/</link>
          <guid>https://blog.none.at/blog/2026/2026-07-18-ingress-nginx-hard-cases/</guid>
          <description xml:base="https://blog.none.at/blog/2026/2026-07-18-ingress-nginx-hard-cases/">&lt;p&gt;Every earlier part of this series was research: read the source, read the docs, verify a claim
against a repo. This one is different. A real OVH Managed Kubernetes Service (MKS) cluster, a real
domain, one deliberately nasty sample application, and the exact same 10-request test script run
against ingress-nginx, then Envoy Gateway, then HAProxy Unified Gateway. Every result below is a
real HTTP response or a real line read out of a running pod, not a docs claim.&lt;&#x2F;p&gt;</description>
      </item>
      <item>
          <title>ingress-nginx Inventory: Annotations, ConfigMaps, Flags</title>
          <pubDate>Sat, 18 Jul 2026 00:00:00 +0000</pubDate>
          <author>aleks</author>
          <link>https://blog.none.at/blog/2026/2026-07-18-ingress-nginx-inventory/</link>
          <guid>https://blog.none.at/blog/2026/2026-07-18-ingress-nginx-inventory/</guid>
          <description xml:base="https://blog.none.at/blog/2026/2026-07-18-ingress-nginx-inventory/">&lt;p&gt;Most migration guides start by comparing replacement Ingress controllers. That’s the wrong first
step. The first step is finding out which &lt;code&gt;ingress-nginx&lt;&#x2F;code&gt; behaviours your own clusters actually
depend on — because the answer changes which controller (or Gateway API implementation) is even a
candidate, and it’s usually smaller than a full annotation reference makes it look.&lt;&#x2F;p&gt;</description>
      </item>
      <item>
          <title>ingress-nginx Migration: A Field Guide</title>
          <pubDate>Sat, 18 Jul 2026 00:00:00 +0000</pubDate>
          <author>aleks</author>
          <link>https://blog.none.at/blog/2026/2026-07-18-ingress-nginx-migration-field-guide/</link>
          <guid>https://blog.none.at/blog/2026/2026-07-18-ingress-nginx-migration-field-guide/</guid>
          <description xml:base="https://blog.none.at/blog/2026/2026-07-18-ingress-nginx-migration-field-guide/">&lt;p&gt;This is the index for a field guide to migrating away from &lt;code&gt;ingress-nginx&lt;&#x2F;code&gt;, the Kubernetes Ingress
controller that was archived and retired in March 2026. Each part stands on its own, but together
they cover the whole path: deciding whether to act, finding out what you actually depend on,
knowing which annotations translate cleanly, choosing a target, and doing the migration itself
without a flag day.&lt;&#x2F;p&gt;</description>
      </item>
      <item>
          <title>ingress-nginx Migration Mechanics: ingress2gateway and Cutover</title>
          <pubDate>Sat, 18 Jul 2026 00:00:00 +0000</pubDate>
          <author>aleks</author>
          <link>https://blog.none.at/blog/2026/2026-07-18-ingress-nginx-migration-mechanics/</link>
          <guid>https://blog.none.at/blog/2026/2026-07-18-ingress-nginx-migration-mechanics/</guid>
          <description xml:base="https://blog.none.at/blog/2026/2026-07-18-ingress-nginx-migration-mechanics/">&lt;p&gt;Parts 3 through 5 answered what migrates cleanly and to which target. This part answers the
question every migration guide owes its reader eventually: how do you actually move traffic without
a flag day? A converter tool, a coexistence window, a staged cutover, and — the section every
migration plan needs but few write down — an actual rollback plan.&lt;&#x2F;p&gt;</description>
      </item>
      <item>
          <title>ingress-nginx Alternatives: Cilium, Traefik, Kong, AKS, GKE</title>
          <pubDate>Sat, 18 Jul 2026 00:00:00 +0000</pubDate>
          <author>aleks</author>
          <link>https://blog.none.at/blog/2026/2026-07-18-ingress-nginx-other-paths/</link>
          <guid>https://blog.none.at/blog/2026/2026-07-18-ingress-nginx-other-paths/</guid>
          <description xml:base="https://blog.none.at/blog/2026/2026-07-18-ingress-nginx-other-paths/">&lt;p&gt;Part 4 covered the five candidates source-verified with the same depth as the Part 3 matrix. This
part covers the rest of what this series set out to compare: three candidates this series tests but
doesn’t deep-dive — Cilium, Traefik, Kong — and a survey of what migrating off ingress-nginx looks
like on four managed Kubernetes platforms that were never part of the empirical lab at all.&lt;&#x2F;p&gt;</description>
      </item>
      <item>
          <title>ingress-nginx Retirement: Four Ways Forward</title>
          <pubDate>Sat, 18 Jul 2026 00:00:00 +0000</pubDate>
          <author>aleks</author>
          <link>https://blog.none.at/blog/2026/2026-07-18-ingress-nginx-retirement-decision/</link>
          <guid>https://blog.none.at/blog/2026/2026-07-18-ingress-nginx-retirement-decision/</guid>
          <description xml:base="https://blog.none.at/blog/2026/2026-07-18-ingress-nginx-retirement-decision/">&lt;p&gt;The &lt;code&gt;ingress-nginx&lt;&#x2F;code&gt; Kubernetes controller is not “retiring soon.” It already has. The GitHub
repository was archived and made read-only on 2026-03-24, and its own description now reads in the
past tense: it &lt;em&gt;was&lt;&#x2F;em&gt; an Ingress controller. For a piece of software that reportedly still runs in
front of roughly half of all cloud-native workloads, that is a completed fact, not a countdown.&lt;&#x2F;p&gt;
&lt;p&gt;This is Part 1 of a field guide to migrating away from it. This part is deliberately
non-technical — it is for whoever has to decide &lt;em&gt;what to do&lt;&#x2F;em&gt;, not yet for whoever will do the
migration work. Parts 2 onward get concrete: inventorying what you actually depend on, an
annotation compatibility matrix, migration mechanics, and a reproducible lab.&lt;&#x2F;p&gt;</description>
      </item>
      <item>
          <title>Istio AuthorizationPolicy &amp; HTTP&#x2F;2 Coalescing</title>
          <pubDate>Mon, 13 Jul 2026 00:00:00 +0000</pubDate>
          <author>aleks</author>
          <link>https://blog.none.at/blog/2026/2026-07-13-istio-authorizationpolicy-http2-coalescing/</link>
          <guid>https://blog.none.at/blog/2026/2026-07-13-istio-authorizationpolicy-http2-coalescing/</guid>
          <description xml:base="https://blog.none.at/blog/2026/2026-07-13-istio-authorizationpolicy-http2-coalescing/">&lt;p&gt;Isolating an admin surface behind its own hostname and an IP-restricted
&lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;istio.io&quot;&gt;Istio&lt;&#x2F;a&gt; &lt;code&gt;AuthorizationPolicy&lt;&#x2F;code&gt; sounds like a Tuesday-afternoon change: add a
second &lt;code&gt;HTTPRoute&lt;&#x2F;code&gt;, add a &lt;code&gt;DENY&lt;&#x2F;code&gt; policy with an allowlist, done. Two non-obvious Envoy behaviors
turned it into a two-day debugging exercise instead — one in how &lt;code&gt;AuthorizationPolicy&lt;&#x2F;code&gt; resolves
“the client’s IP,” and one in how browsers reuse HTTP&#x2F;2 connections across hostnames that share a
certificate. Neither is specific to Keycloak or to this particular setup; both apply to any Istio
or Envoy Gateway API ingress sitting behind a cloud load balancer with a shared wildcard
certificate.&lt;&#x2F;p&gt;
&lt;p&gt;This post walks through both bugs, how they were root-caused, and the fix for each — so the next
person hitting either symptom can skip straight to the cause.&lt;&#x2F;p&gt;</description>
      </item>
      <item>
          <title>Istio vs. Linkerd: Service Mesh on Kubernetes</title>
          <pubDate>Tue, 12 May 2026 00:00:00 +0000</pubDate>
          <author>aleks</author>
          <link>https://blog.none.at/blog/2026/2026-05-12-istio-vs-linkerd/</link>
          <guid>https://blog.none.at/blog/2026/2026-05-12-istio-vs-linkerd/</guid>
          <description xml:base="https://blog.none.at/blog/2026/2026-05-12-istio-vs-linkerd/">&lt;p&gt;Both &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;istio.io&quot;&gt;Istio&lt;&#x2F;a&gt; and &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;linkerd.io&quot;&gt;Linkerd&lt;&#x2F;a&gt; are CNCF Graduated service
meshes that provide automatic mTLS, traffic policy, and observability for Kubernetes
workloads. Both run in sidecar mode for this comparison — a proxy container injected into
every pod. The fundamental difference is the data plane: Istio uses
&lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.envoyproxy.io&quot;&gt;Envoy&lt;&#x2F;a&gt;, Linkerd uses its own Rust-based proxy
(&lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;linkerd&#x2F;linkerd2-proxy&quot;&gt;&lt;code&gt;linkerd2-proxy&lt;&#x2F;code&gt;&lt;&#x2F;a&gt;). That choice drives the differences in overhead, extensibility, and egress
control.&lt;&#x2F;p&gt;
&lt;p&gt;This post compares them on the dimensions that matter for a production deployment. For the
broader question of Istio vs. Envoy Gateway (ingress-only), ambient mode, and managed cloud
specifics (AKS, GKE, OVH MKS), see the companion post
&lt;a href=&quot;&#x2F;blog&#x2F;2026&#x2F;2026-04-30-istio-vs-envoy-gateway&#x2F;&quot;&gt;Istio vs. Envoy Gateway: Gateway API on Kubernetes&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;</description>
      </item>
      <item>
          <title>Istio vs. Envoy Gateway: Gateway API on Kubernetes</title>
          <pubDate>Thu, 30 Apr 2026 00:00:00 +0000</pubDate>
          <author>aleks</author>
          <link>https://blog.none.at/blog/2026/2026-04-30-istio-vs-envoy-gateway/</link>
          <guid>https://blog.none.at/blog/2026/2026-04-30-istio-vs-envoy-gateway/</guid>
          <description xml:base="https://blog.none.at/blog/2026/2026-04-30-istio-vs-envoy-gateway/">&lt;p&gt;Both &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;istio.io&quot;&gt;Istio&lt;&#x2F;a&gt; and &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;gateway.envoyproxy.io&quot;&gt;Envoy Gateway&lt;&#x2F;a&gt; implement the
&lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;gateway-api.sigs.k8s.io&quot;&gt;Kubernetes Gateway API&lt;&#x2F;a&gt; and use Envoy as their data plane.
That is roughly where the similarity ends. Istio is a full service mesh that happens to
implement Gateway API; Envoy Gateway is a dedicated Gateway API controller with no mesh
ambitions. Choosing between them is mostly a question of scope.&lt;&#x2F;p&gt;
&lt;p&gt;This post starts with that comparison — architecture, mTLS, egress control, and resource
overhead — then broadens to cover &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;cilium.io&quot;&gt;Cilium&lt;&#x2F;a&gt; as a lighter alternative for
East-West security, how the choice plays out on managed Kubernetes offerings (AKS, GKE, and
OVH MKS including their cloud-native ingress and egress options), and finally how to get
the real client IP through a cloud load balancer to your application.&lt;&#x2F;p&gt;</description>
      </item>
      <item>
          <title>haproxy-spoe-rs: A Rust SPOA Agent Library for HAProxy</title>
          <pubDate>Sun, 12 Apr 2026 00:00:00 +0000</pubDate>
          <author>aleks</author>
          <link>https://blog.none.at/blog/2026/2026-04-12-haproxy-spoa-rs/</link>
          <guid>https://blog.none.at/blog/2026/2026-04-12-haproxy-spoa-rs/</guid>
          <description xml:base="https://blog.none.at/blog/2026/2026-04-12-haproxy-spoa-rs/">&lt;p&gt;&lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;git001&#x2F;haproxy-spoe-rs&quot;&gt;haproxy-spoe-rs&lt;&#x2F;a&gt; is a Rust library for writing
&lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;haproxy&#x2F;haproxy&#x2F;blob&#x2F;master&#x2F;doc&#x2F;SPOE.txt&quot;&gt;HAProxy SPOE&lt;&#x2F;a&gt; agents. This post
covers what SPOE is, the design decisions behind the library, and how its throughput compares
to the Go reference implementation.&lt;&#x2F;p&gt;</description>
      </item>
      <item>
          <title>Running pdns_recursor as a root-independent validating resolver</title>
          <pubDate>Mon, 06 Apr 2026 00:00:00 +0000</pubDate>
          <author>aleks</author>
          <link>https://blog.none.at/blog/2026/2026-04-05-pdns-recursor-root-resolver/</link>
          <guid>https://blog.none.at/blog/2026/2026-04-05-pdns-recursor-root-resolver/</guid>
          <description xml:base="https://blog.none.at/blog/2026/2026-04-05-pdns-recursor-root-resolver/">&lt;p&gt;&lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;doc.powerdns.com&#x2F;recursor&#x2F;&quot;&gt;PowerDNS Recursor&lt;&#x2F;a&gt; is a mature, production-grade recursive DNS resolver. This post documents how to configure it to bootstrap directly from a local &lt;code&gt;root.zone&lt;&#x2F;code&gt; file — so it never needs to reach the root name servers at runtime — with full DNSSEC validation producing the &lt;code&gt;ad&lt;&#x2F;code&gt; flag in responses.&lt;&#x2F;p&gt;</description>
      </item>
      <item>
          <title>Running a validating DNS recursor from the root zone with Hickory DNS</title>
          <pubDate>Sat, 04 Apr 2026 00:00:00 +0000</pubDate>
          <author>aleks</author>
          <link>https://blog.none.at/blog/2026/2026-04-04-hickory-dns-root-resolver/</link>
          <guid>https://blog.none.at/blog/2026/2026-04-04-hickory-dns-root-resolver/</guid>
          <description xml:base="https://blog.none.at/blog/2026/2026-04-04-hickory-dns-root-resolver/">&lt;p&gt;&lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;hickory-dns&#x2F;hickory-dns&quot;&gt;Hickory DNS&lt;&#x2F;a&gt; is a Rust-based DNS implementation that covers the full stack: resolver, recursor, authoritative server, and DNSSEC. This post documents how to run it as a &lt;strong&gt;full recursive resolver&lt;&#x2F;strong&gt; — starting directly from the root zone, with DNSSEC validation and encrypted upstream transport — based on the changes developed in the &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;git001&#x2F;hickory-dns&#x2F;tree&#x2F;recurser-from-root-zone&quot;&gt;&lt;code&gt;recurser-from-root-zone&lt;&#x2F;code&gt;&lt;&#x2F;a&gt; branch.&lt;&#x2F;p&gt;</description>
      </item>
      <item>
          <title>tls-proxy-tunnel: Transparent TLS Tunnelling Through Corporate HTTP Proxies</title>
          <pubDate>Tue, 02 Jul 2024 00:00:00 +0000</pubDate>
          <author>aleks</author>
          <link>https://blog.none.at/blog/2024/2024-07-02-tls-proxy-tunnel/</link>
          <guid>https://blog.none.at/blog/2024/2024-07-02-tls-proxy-tunnel/</guid>
          <description xml:base="https://blog.none.at/blog/2024/2024-07-02-tls-proxy-tunnel/">&lt;p&gt;Many enterprise networks sit behind a corporate HTTP CONNECT proxy. Applications
that speak TLS natively — think &lt;code&gt;git&lt;&#x2F;code&gt;, &lt;code&gt;curl&lt;&#x2F;code&gt;, SSH-over-HTTPS, or any custom
binary — often have no built-in proxy support. Configuring every single tool is
tedious, fragile, and sometimes impossible when you don’t control the binary.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;tls-proxy-tunnel&lt;&#x2F;code&gt; (&lt;code&gt;tpt&lt;&#x2F;code&gt;) solves this at layer 4: it sits between your
application and the outside world, intercepts the TLS connection, extracts the
Server Name Indication (SNI) from the ClientHello, and tunnels the raw bytes
through your corporate HTTP CONNECT proxy — without ever terminating TLS.&lt;&#x2F;p&gt;</description>
      </item>
      <item>
          <title>curl:&#x2F;&#x2F; for Network Debugging — curlup 2017</title>
          <pubDate>Sat, 18 Mar 2017 00:00:00 +0000</pubDate>
          <author>aleks</author>
          <link>https://blog.none.at/blog/2017/2017-03-18-curl-meetup/</link>
          <guid>https://blog.none.at/blog/2017/2017-03-18-curl-meetup/</guid>
          <description xml:base="https://blog.none.at/blog/2017/2017-03-18-curl-meetup/">&lt;p&gt;Talk I gave at &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;curl.se&#x2F;docs&#x2F;videos&#x2F;&quot;&gt;curlup 2017&lt;&#x2F;a&gt; in Nürnberg. The slides cover three practical curl techniques that are useful for everyday network debugging.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;a href=&quot;&#x2F;pdf&#x2F;2017&#x2F;Curl-meetup-2017.pdf&quot;&gt;slides are available as PDF&lt;&#x2F;a&gt; and the &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;curl.se&#x2F;video&#x2F;curlup-2017&#x2F;2017-03-18_02_Aleksandar_Lazic_curl_for_network_debugging.mp4&quot;&gt;video recording (MP4)&lt;&#x2F;a&gt; is hosted on curl.se.&lt;&#x2F;p&gt;</description>
      </item>
    </channel>
</rss>
