<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Hubble on lo0 — Blog Técnico</title><link>https://blog.lo0.es/tags/hubble/</link><description>Recent content in Hubble on lo0 — Blog Técnico</description><generator>Hugo -- gohugo.io</generator><language>es</language><lastBuildDate>Tue, 19 May 2026 06:00:00 +0200</lastBuildDate><atom:link href="https://blog.lo0.es/tags/hubble/index.xml" rel="self" type="application/rss+xml"/><item><title>Hubble: observabilidad de red en eBPF, estado del arte 2026 y la nueva frontera con los agentes IA</title><link>https://blog.lo0.es/posts/hubble-observabilidad-ebpf/</link><pubDate>Tue, 19 May 2026 06:00:00 +0200</pubDate><guid>https://blog.lo0.es/posts/hubble-observabilidad-ebpf/</guid><description>&lt;h2 id="tldr">TL;DR&lt;/h2>
&lt;p>&lt;a href="https://github.com/cilium/hubble">Hubble&lt;/a> es &lt;strong>la observabilidad de red nativa de Cilium&lt;/strong>, construida sobre los mismos programas eBPF que Cilium usa para enforcement. No duplica datapath ni instrumenta el kernel a su manera: &lt;strong>escucha&lt;/strong> los hooks que Cilium ya tiene y produce &lt;strong>flow logs estructurados&lt;/strong> con contexto Kubernetes incluido —pod, namespace, labels, service, verdict de policy, payload L7 cuando aplica—. Es lo que pasa cuando alguien decide que &lt;code>tcpdump&lt;/code> con &lt;code>grep&lt;/code> no escala a 10 000 pods y construye un sistema distribuido propio (Hubble server por nodo + Hubble Relay como agregador + CLI + UI) con overhead &lt;strong>prácticamente cero&lt;/strong> porque la captura ya estaba ocurriendo. En 2026 está en &lt;strong>versión 1.19.3&lt;/strong> (abril 2026), con Cilium 1.19 marcando el décimo aniversario del proyecto; ha llegado el &lt;strong>tracing por IP options&lt;/strong>, el filtrado por estado de cifrado, el &lt;strong>drop event taggeado con la NetworkPolicy exacta que lo causó&lt;/strong> (atribución directa), el &lt;strong>field mask API&lt;/strong> estabilizado, y la primera oleada de &lt;strong>anomaly detection con ML aplicado a flows&lt;/strong> para predictive security en clusters IoT/5G. Y, lo más interesante para 2026: aparece una frontera nueva donde el mismo eBPF observa &lt;strong>agentes de IA&lt;/strong> —Claude Code, Gemini CLI, agentes MCP— interceptando SSL/TLS y stdio sin instrumentar el código, lo que convierte el stack Cilium + Hubble + Tetragon + &lt;strong>AgentSight&lt;/strong> en una pila completa para entender qué hace un sistema agentic dentro de un cluster.&lt;/p>
&lt;blockquote>
&lt;p>Este artículo es la &lt;strong>parte 3 de la serie sobre eBPF&lt;/strong>. Parte 1: &lt;a href="https://blog.lo0.es/posts/ebpf-cilium-tcp-ip-bypass/">eBPF de cero a Cilium: cómo el kernel aprendió a saltarse su propia pila TCP/IP&lt;/a>. Parte 2: &lt;a href="https://blog.lo0.es/posts/tetragon-runtime-security/">Tetragon: el primo de seguridad de Cilium que ve cada syscall en el kernel&lt;/a>. Aquí completamos el cuadrante de observabilidad: &lt;strong>red&lt;/strong> con Hubble, &lt;strong>proceso&lt;/strong> con Tetragon, &lt;strong>agente IA&lt;/strong> con AgentSight.&lt;/p>
&lt;/blockquote>
&lt;h2 id="la-analogía-tcpdump-que-habla-kubernetes">La analogía: tcpdump que habla Kubernetes&lt;/h2>
&lt;p>Si has administrado redes los últimos veinte años, &lt;code>tcpdump&lt;/code> y Wireshark han sido el pan nuestro de cada día. Capturan paquetes en una interfaz, los parsean, te dejan filtrar con &lt;code>tcp.port == 443 and host 10.0.0.5&lt;/code>. Funcionan, llevan funcionando desde los 90, y son lo primero que abres cuando algo huele raro.&lt;/p>
&lt;p>Ahora pega &lt;code>tcpdump&lt;/code> a un cluster Kubernetes de 10 000 pods. Los problemas saltan en orden:&lt;/p>
&lt;ol>
&lt;li>&lt;strong>Una sesión &lt;code>tcpdump&lt;/code> por nodo&lt;/strong>. Querías &amp;ldquo;ver el tráfico entre el frontend y la API&amp;rdquo;; necesitas SSH a cada nodo, tcpdump por cada NIC, sincronizar timestamps, agregar a mano.&lt;/li>
&lt;li>&lt;strong>No hay contexto K8s&lt;/strong>. Ves un paquete de &lt;code>10.244.5.7&lt;/code> a &lt;code>10.244.8.42&lt;/code>. ¿Qué pod era? ¿Qué namespace? ¿Qué label? Te toca correlar con &lt;code>kubectl get pod -A -o wide&lt;/code> cada vez.&lt;/li>
&lt;li>&lt;strong>Sin entender L7&lt;/strong>. Ves un POST a HTTPS, no puedes saber qué método y path porque está cifrado en el cable. Si hay mTLS entre pods, peor.&lt;/li>
&lt;li>&lt;strong>Coste alto&lt;/strong>: captura completa de paquetes con copia a userspace ralentiza el datapath. En tráfico denso, lo notas.&lt;/li>
&lt;/ol>
&lt;p>Hubble es &lt;strong>tcpdump rediseñado para todo eso&lt;/strong>. Reutiliza los programas eBPF que &lt;strong>ya están&lt;/strong> procesando cada paquete (Cilium los pone ahí para enforcement) y, mientras toman su decisión de allow/deny, &lt;strong>emiten un evento de flow&lt;/strong> con todo el contexto: identidad del pod origen y destino, namespace, labels, protocolo, verdict, y —si Cilium ha hecho parsing L7 vía Envoy— método HTTP, path, status code, DNS query, Kafka topic. Ese evento viaja por un ringbuffer a userspace, lo recibe el &lt;strong>Hubble server&lt;/strong> que vive dentro del agent Cilium del nodo, y lo expone vía gRPC. Un servicio aparte, &lt;strong>Hubble Relay&lt;/strong>, agrega los streams de todos los nodos y te da una única API cluster-wide. Por encima de eso: una CLI (&lt;code>hubble&lt;/code>) y una UI web con grafo de servicios en tiempo real.&lt;/p>
&lt;p>Cero copia adicional. Cero parsing duplicado. Y el resultado lo entiende cualquiera que sepa qué es un Pod.&lt;/p>
&lt;h2 id="arquitectura-cuatro-piezas-que-se-ven-desde-fuera">Arquitectura: cuatro piezas que se ven desde fuera&lt;/h2>
&lt;p>Hubble se compone de cuatro componentes lógicos, todos opcionales según lo que quieras hacer:&lt;/p>
&lt;h3 id="1-hubble-server-embedded-en-cada-agent-cilium">1. Hubble Server (embedded en cada agent Cilium)&lt;/h3>
&lt;p>Vive &lt;strong>dentro del proceso del agent Cilium&lt;/strong> (no es un binario aparte). Cada nodo expone localmente un endpoint gRPC en el socket Unix &lt;code>/var/run/cilium/hubble.sock&lt;/code>. El server escucha los eventos que los programas eBPF emiten al ringbuffer, los enriquece con metadata Kubernetes (que el agent ya tiene en memoria), y los pone disponibles para consumidores.&lt;/p>
&lt;p>Activación: &lt;code>--set hubble.enabled=true&lt;/code> en el chart Helm de Cilium. Por defecto, el server &lt;strong>solo es accesible localmente&lt;/strong>; si quieres consumirlo desde otro nodo, hace falta exponerlo (lo que hace Hubble Relay).&lt;/p>
&lt;h3 id="2-hubble-relay-agregador">2. Hubble Relay (agregador)&lt;/h3>
&lt;p>Es un Deployment aparte (típicamente 1 réplica, escalable) que &lt;strong>se conecta a todos los Hubble servers del cluster&lt;/strong> y &lt;strong>agrega sus streams en una única API&lt;/strong>. Cuando tu CLI o UI pide &amp;ldquo;los últimos 1000 flows del cluster&amp;rdquo;, la Relay los recoge en paralelo de todos los nodos y devuelve la unión.&lt;/p>
&lt;p>Activación: &lt;code>--set hubble.relay.enabled=true&lt;/code>. Sin la Relay, solo ves el tráfico del nodo donde estás conectado, lo que es útil para debug local pero no para visión cluster-wide.&lt;/p>
&lt;h3 id="3-hubble-cli-hubble">3. Hubble CLI (&lt;code>hubble&lt;/code>)&lt;/h3>
&lt;p>Un binario en Go que habla gRPC con la Relay (o con un Hubble server local). Soporta dos modos principales:&lt;/p>
&lt;ul>
&lt;li>&lt;strong>&lt;code>hubble observe&lt;/code>&lt;/strong>: stream de flows en tiempo real, con filtros muy expresivos (por namespace, pod, port, verdict, protocolo, label).&lt;/li>
&lt;li>&lt;strong>&lt;code>hubble status&lt;/code>&lt;/strong>: estado del cluster Hubble (cuántos nodos conectados, lag, flow rate).&lt;/li>
&lt;/ul>
&lt;p>Y el equivalente a &lt;code>tcpdump&lt;/code>&amp;rsquo;s pcap dump: &lt;code>hubble observe --output jsonpb &amp;gt; flows.json&lt;/code> para procesar a posteriori con &lt;code>jq&lt;/code> u otras herramientas.&lt;/p>
&lt;h3 id="4-hubble-ui">4. Hubble UI&lt;/h3>
&lt;p>Frontend web que se conecta a Hubble Relay y muestra:&lt;/p>
&lt;ul>
&lt;li>&lt;strong>Grafo de servicios&lt;/strong> en tiempo real (qué Pod habla con qué Service, qué protocolos usa, qué verdict).&lt;/li>
&lt;li>&lt;strong>Lista de flows&lt;/strong> filtrable.&lt;/li>
&lt;li>&lt;strong>Detalles L7&lt;/strong> cuando los hay (HTTP method/path/status, DNS query/response).&lt;/li>
&lt;/ul>
&lt;p>Activación: &lt;code>--set hubble.ui.enabled=true&lt;/code>. Útil para presentaciones a equipos no-CLI; no sustituye a la CLI para debug serio.&lt;/p>
&lt;div class="diagram" style="max-width:720px;margin:1.5rem auto;">
&lt;svg viewBox="0 0 720 290" xmlns="http://www.w3.org/2000/svg" role="img" aria-label="Arquitectura de Hubble">
&lt;style>.title{font:600 13px sans-serif;fill:#222}.lbl{font:600 12px sans-serif;fill:#222}.sm{font:11px sans-serif;fill:#555}.box{stroke:#444;stroke-width:1.4}.k{fill:#ffe9d6}.s{fill:#d6eaff}.r{fill:#d9f5d6}.c{fill:#e9d6f5}.arr{stroke:#666;stroke-width:1.4;fill:none;marker-end:url(#hh)}&lt;/style>
&lt;defs>&lt;marker id="hh" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="6" markerHeight="6" orient="auto">&lt;path d="M0,0 L10,5 L0,10 z" fill="#666"/>&lt;/marker>&lt;/defs>
&lt;text x="360" y="18" text-anchor="middle" class="title">Arquitectura Hubble: 4 piezas, eBPF como única fuente de datos&lt;/text>
&lt;rect x="30" y="40" width="200" height="50" rx="6" class="box k"/>
&lt;text x="130" y="60" text-anchor="middle" class="lbl">eBPF (kernel)&lt;/text>
&lt;text x="130" y="78" text-anchor="middle" class="sm">programs de Cilium&lt;/text>
&lt;rect x="30" y="115" width="200" height="50" rx="6" class="box s"/>
&lt;text x="130" y="135" text-anchor="middle" class="lbl">Hubble Server (nodo)&lt;/text>
&lt;text x="130" y="153" text-anchor="middle" class="sm">grpc local, dentro del agent&lt;/text>
&lt;rect x="270" y="115" width="180" height="50" rx="6" class="box s"/>
&lt;text x="360" y="135" text-anchor="middle" class="lbl">Hubble Server (nodo N)&lt;/text>
&lt;text x="360" y="153" text-anchor="middle" class="sm">uno por nodo&lt;/text>
&lt;rect x="490" y="115" width="200" height="50" rx="6" class="box s"/>
&lt;text x="590" y="135" text-anchor="middle" class="lbl">Hubble Server (nodo …)&lt;/text>
&lt;text x="590" y="153" text-anchor="middle" class="sm">N agents = N servers&lt;/text>
&lt;rect x="220" y="190" width="280" height="50" rx="6" class="box r"/>
&lt;text x="360" y="210" text-anchor="middle" class="lbl">Hubble Relay (Deployment)&lt;/text>
&lt;text x="360" y="228" text-anchor="middle" class="sm">agrega streams gRPC de todos los nodos&lt;/text>
&lt;rect x="80" y="245" width="160" height="35" rx="6" class="box c"/>
&lt;text x="160" y="266" text-anchor="middle" class="lbl">Hubble CLI&lt;/text>
&lt;rect x="290" y="245" width="160" height="35" rx="6" class="box c"/>
&lt;text x="370" y="266" text-anchor="middle" class="lbl">Hubble UI&lt;/text>
&lt;rect x="500" y="245" width="180" height="35" rx="6" class="box c"/>
&lt;text x="590" y="266" text-anchor="middle" class="lbl">Prometheus / OTLP&lt;/text>
&lt;path class="arr" d="M130,90 L130,115"/>
&lt;path class="arr" d="M130,165 L290,190"/>
&lt;path class="arr" d="M360,165 L360,190"/>
&lt;path class="arr" d="M590,165 L430,190"/>
&lt;path class="arr" d="M340,240 L200,245"/>
&lt;path class="arr" d="M360,240 L370,245"/>
&lt;path class="arr" d="M380,240 L560,245"/>
&lt;/svg>
&lt;/div>
&lt;h2 id="qué-se-ve-el-flow-log-de-hubble-por-dentro">Qué se ve: el flow log de Hubble por dentro&lt;/h2>
&lt;p>Un flow de Hubble en formato JSON tiene aproximadamente esta forma (simplificado):&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-json" data-lang="json">&lt;span class="line">&lt;span class="cl">&lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;time&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;2026-05-19T03:12:45.182Z&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;verdict&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;FORWARDED&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;source&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;ID&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="mi">5482&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;identity&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="mi">24871&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;namespace&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;prod-api&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;labels&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="p">[&lt;/span>&lt;span class="s2">&amp;#34;app=checkout&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;team=payments&amp;#34;&lt;/span>&lt;span class="p">],&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;pod_name&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;checkout-7c9f-x8j2&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;workloads&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="p">[{&lt;/span>&lt;span class="nt">&amp;#34;name&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;checkout&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nt">&amp;#34;kind&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;Deployment&amp;#34;&lt;/span>&lt;span class="p">}]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">},&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;destination&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;ID&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="mi">12041&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;identity&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="mi">18356&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;namespace&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;prod-db&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;labels&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="p">[&lt;/span>&lt;span class="s2">&amp;#34;app=postgres&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;tier=primary&amp;#34;&lt;/span>&lt;span class="p">],&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;pod_name&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;postgres-0&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">},&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;Type&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;L3_L4&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;l4&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;TCP&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;source_port&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="mi">41982&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;destination_port&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="mi">5432&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;flags&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="p">{&lt;/span>&lt;span class="nt">&amp;#34;SYN&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="kc">true&lt;/span>&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">},&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;node_name&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;rke2-worker-03&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;Summary&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;TCP Flags: SYN&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Cuando hay parsing L7 activo (vía Envoy embebido o el parser ligero de Hubble), el mismo flujo añade:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-json" data-lang="json">&lt;span class="line">&lt;span class="cl">&lt;span class="s2">&amp;#34;l7&amp;#34;&lt;/span>&lt;span class="err">:&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;type&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;REQUEST&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;http&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;code&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="mi">200&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;method&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;GET&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;url&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;/api/v1/cart/items&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;protocol&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;HTTP/1.1&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;headers&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="p">[{&lt;/span>&lt;span class="nt">&amp;#34;key&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;user-agent&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nt">&amp;#34;value&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;checkout/1.4.2&amp;#34;&lt;/span>&lt;span class="p">}]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Los protocolos soportados nativamente para parsing L7:&lt;/p>
&lt;ul>
&lt;li>&lt;strong>HTTP/1.1 y HTTP/2&lt;/strong> (incluyendo gRPC sobre HTTP/2).&lt;/li>
&lt;li>&lt;strong>DNS&lt;/strong> (queries y responses, con domains, tipos, response codes).&lt;/li>
&lt;li>&lt;strong>Kafka&lt;/strong> (topics, API keys).&lt;/li>
&lt;li>&lt;strong>TLS handshake&lt;/strong> (SNI, no el payload cifrado por defecto).&lt;/li>
&lt;li>&lt;strong>MySQL, Cassandra&lt;/strong> (con módulos opcionales).&lt;/li>
&lt;/ul>
&lt;p>Para HTTP y gRPC, Cilium puede activar el proxy Envoy embebido para los flujos que quieras inspeccionar (no todos; selectivo via &lt;code>CiliumNetworkPolicy&lt;/code> con reglas L7). Sin Envoy hay parsing ligero pero menos detallado.&lt;/p>
&lt;h2 id="verdict-y-atribución-de-drops">Verdict y atribución de drops&lt;/h2>
&lt;p>Cada flow tiene un &lt;code>verdict&lt;/code>: &lt;code>FORWARDED&lt;/code>, &lt;code>DROPPED&lt;/code>, &lt;code>ERROR&lt;/code>, &lt;code>AUDIT&lt;/code>, &lt;code>REDIRECTED&lt;/code>, &lt;code>TRACED&lt;/code>, &lt;code>TRANSLATED&lt;/code>. Para el caso &lt;code>DROPPED&lt;/code>, Hubble incluye una &lt;strong>razón estructurada&lt;/strong> (&lt;code>drop_reason&lt;/code>) y, desde Cilium 1.19, &lt;strong>la NetworkPolicy exacta&lt;/strong> que lo causó.&lt;/p>
&lt;p>Esto último cambia la operativa. Antes, cuando un pod no podía hablar con otro, el flujo de debug era:&lt;/p>
&lt;ol>
&lt;li>Ver el flow dropeado en Hubble.&lt;/li>
&lt;li>Mirar todas las CiliumNetworkPolicy del namespace.&lt;/li>
&lt;li>Razonar a mano cuál de ellas, con cuáles labels, lo está bloqueando.&lt;/li>
&lt;/ol>
&lt;p>Con la atribución de Cilium 1.19, el campo &lt;code>policy_match_info&lt;/code> te dice directamente &amp;ldquo;lo dropeó la policy &lt;code>frontend-egress&lt;/code>, regla 3&amp;rdquo;. Pasas de &amp;ldquo;Sherlock Holmes durante 20 minutos&amp;rdquo; a &amp;ldquo;kubectl get -o yaml de esa policy concreta&amp;rdquo;.&lt;/p>
&lt;h2 id="métricas-prometheus-y-dashboards-grafana">Métricas Prometheus y dashboards Grafana&lt;/h2>
&lt;p>Hubble también expone &lt;strong>métricas agregadas&lt;/strong> en formato Prometheus, separadas del stream gRPC de flows. Activación: &lt;code>--set hubble.metrics.enabled=true&lt;/code> (Helm) y enumeración del set que quieres exportar.&lt;/p>
&lt;p>Los grupos de métricas habituales:&lt;/p>
&lt;ul>
&lt;li>&lt;code>flow&lt;/code>: total flows por verdict, source/dest, protocolo.&lt;/li>
&lt;li>&lt;code>http&lt;/code>: requests por método, código de respuesta, latencia (histograma).&lt;/li>
&lt;li>&lt;code>dns&lt;/code>: queries, response codes, dominios top-N.&lt;/li>
&lt;li>&lt;code>tcp&lt;/code>: handshakes, retransmisiones, ventana congestion.&lt;/li>
&lt;li>&lt;code>drop&lt;/code>: drops por razón, con NetworkPolicy attribution.&lt;/li>
&lt;li>&lt;code>port-distribution&lt;/code>: histograma de ports activos.&lt;/li>
&lt;li>&lt;code>policy&lt;/code>: hits por policy y verdict.&lt;/li>
&lt;/ul>
&lt;p>Estas métricas tienen labels K8s ricos (&lt;code>source_workload&lt;/code>, &lt;code>destination_workload&lt;/code>, &lt;code>namespace&lt;/code>, etc.) que las hacen pivotables en Grafana. Hay &lt;a href="https://grafana.com/grafana/dashboards/?search=hubble">dashboards prebuilt en Grafana Labs&lt;/a> que cubren los casos comunes; importar uno y tener visión inmediata cuesta cinco minutos.&lt;/p>
&lt;p>Coste: las métricas con muchos labels K8s pueden &lt;strong>explotar la cardinalidad&lt;/strong> en Prometheus. Para clusters grandes (&amp;gt;1 000 pods), conviene revisar qué set exportas y usar &lt;strong>drop rules&lt;/strong> en Prometheus para limitar.&lt;/p>
&lt;h2 id="despliegue-helm-en-una-pantalla">Despliegue: Helm en una pantalla&lt;/h2>
&lt;p>Instalación canónica de Cilium con Hubble completo:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-yaml" data-lang="yaml">&lt;span class="line">&lt;span class="cl">&lt;span class="c"># values.yaml&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="nt">hubble&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">enabled&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="kc">true&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">metrics&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">enabled&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="l">dns:query;ignoreAAAA&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="l">drop&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="l">tcp&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="l">flow&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="l">port-distribution&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="l">icmp&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="l">httpV2:exemplars=true;labelsContext=source_ip,source_namespace,source_workload,destination_ip,destination_namespace,destination_workload,traffic_direction&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">serviceMonitor&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">enabled&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="kc">true&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="c"># auto-discover por kube-prometheus-stack&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">relay&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">enabled&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="kc">true&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">rollOutPods&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="kc">true&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">ui&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">enabled&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="kc">true&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">rollOutPods&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="kc">true&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">ingress&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">enabled&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="kc">true&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">className&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">cilium&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">hosts&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="l">hubble.example.local&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Y la instalación:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">helm upgrade --install cilium cilium/cilium -n kube-system -f values.yaml
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Tras la instalación, valida con &lt;code>cilium status&lt;/code> (CLI de Cilium) que la sección Hubble muestra OK, y prueba el primer flow con:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">cilium hubble observe --namespace prod-api --pod checkout-7c9f-x8j2
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="estado-del-arte-en-2026">Estado del arte en 2026&lt;/h2>
&lt;p>&lt;a href="https://www.infoq.com/news/2026/02/cilium-119/">Cilium 1.19 se publicó en febrero de 2026&lt;/a> marcando el décimo aniversario del proyecto. Hubble alcanzó la versión 1.19.3 el 22 de abril de 2026. Las novedades relevantes:&lt;/p>
&lt;h3 id="atribución-directa-de-drops-a-networkpolicy">Atribución directa de drops a NetworkPolicy&lt;/h3>
&lt;p>Ya cubierta arriba; es probablemente el cambio operacional más valioso del release. Cualquier flow dropeado lleva el nombre, namespace y regla específica de la policy responsable. Aplicable también vía métricas Prometheus, lo que permite alertas tipo &amp;ldquo;policy X está dropping &amp;gt;N peticiones/segundo&amp;rdquo;.&lt;/p>
&lt;h3 id="tracing-con-ip-options">Tracing con IP options&lt;/h3>
&lt;p>Hubble puede ahora &lt;strong>trazar paquetes individuales con IP options&lt;/strong> activado. Es un mecanismo similar al traceroute pero a nivel L3: pones una marca en el paquete y Cilium la reporta cada vez que el paquete atraviesa un nodo o una decisión de eBPF. Útil para debug de paths multi-cluster, fabric mesh, o NetworkPolicy que se aplican en distintas capas.&lt;/p>
&lt;h3 id="filtrado-por-estado-de-cifrado">Filtrado por estado de cifrado&lt;/h3>
&lt;p>Nuevo flag en CLI: &lt;code>hubble observe --encryption-status=encrypted&lt;/code> (o &lt;code>unencrypted&lt;/code>). Útil para validar despliegues con WireGuard o IPsec activado pod-a-pod: confirmas que el tráfico que &lt;strong>debería&lt;/strong> estar cifrado lo está, y detectas regresiones rápidamente.&lt;/p>
&lt;h3 id="hubble-field-mask-api-estabilizado">Hubble field mask API estabilizado&lt;/h3>
&lt;p>El &lt;code>field_mask&lt;/code> permite pedir solo las partes del flow que te interesan, reduciendo enormemente el ancho de banda y el procesamiento cuando solo necesitas, por ejemplo, source/dest y verdict. Antes era experimental, ahora está estable y es &lt;strong>default-on&lt;/strong> en la CLI.&lt;/p>
&lt;h3 id="ai-driven-anomaly-detection-predictive-security">AI-driven anomaly detection (predictive security)&lt;/h3>
&lt;p>Esta es la incorporación más comentada de 2026. Cilium 1.19 añade hooks para que un consumer externo —típicamente un sistema ML— procese los flows en streaming y detecte anomalías estadísticas: pods que de pronto hablan con destinos nuevos, picos de latencia en una API, secuencias raras de DNS. La parte de &lt;strong>detección&lt;/strong> ocurre fuera del agent Cilium (no se quiere ML pesado en el datapath), pero Cilium expone los flows con las features pre-calculadas que el modelo necesita. Los casos de uso publicados se enfocan en &lt;strong>IoT y 5G&lt;/strong> donde el tráfico es alto en volumen y bajo en variedad, condiciones ideales para anomaly detection.&lt;/p>
&lt;h3 id="escala-a-10-000-pods">Escala a 10 000+ pods&lt;/h3>
&lt;p>Cilium 1.19 ha hecho trabajo serio en escalabilidad: Hubble Relay puede ahora agregar streams de cientos de nodos sin saturar; el field_mask por defecto reduce el ancho de banda inter-nodo; y los flows pueden samplearse en alta carga si tu uso es análisis estadístico (no debug forense).&lt;/p>
&lt;h3 id="cilium-120-en-desarrollo">Cilium 1.20 en desarrollo&lt;/h3>
&lt;p>&lt;a href="https://docs.cilium.io/en/latest/operations/upgrade/">Cilium 1.20&lt;/a> está en branch de desarrollo. Lo más relevante para Hubble:&lt;/p>
&lt;ul>
&lt;li>&lt;strong>Unificación de &lt;code>preferIpv6&lt;/code>&lt;/strong>: el flag &lt;code>hubble.preferIpv6&lt;/code> se deprecó en favor del global &lt;code>preferIpv6&lt;/code> aplicable a todos los componentes Cilium.&lt;/li>
&lt;li>&lt;strong>&lt;code>tetragon-python&lt;/code> SDK&lt;/strong>: aunque es de Tetragon, no de Hubble, marca tendencia: políticas eBPF escritas en Python en lugar de YAML. Probablemente Hubble seguirá camino similar.&lt;/li>
&lt;/ul>
&lt;h2 id="la-nueva-frontera-ebpf-y-los-agentes-de-ia">La nueva frontera: eBPF y los agentes de IA&lt;/h2>
&lt;p>Hasta aquí el contenido clásico de Hubble. Pero hay un giro 2026 que merece la pena cubrir porque cierra el círculo con la otra serie de este blog.&lt;/p>
&lt;p>Cuando un cluster Kubernetes empieza a ejecutar &lt;strong>agentes de IA&lt;/strong> —Claude Code, Gemini CLI, agentes basados en LangGraph que llaman APIs y MCP servers—, el problema de observabilidad cambia de forma. Ya no basta con saber &amp;ldquo;qué pod habló con qué pod&amp;rdquo; (eso es Hubble) ni &amp;ldquo;qué proceso ejecutó qué&amp;rdquo; (eso es Tetragon). Necesitas saber:&lt;/p>
&lt;ul>
&lt;li>&lt;strong>A qué APIs externas está llamando el agente&lt;/strong> y con qué prompts.&lt;/li>
&lt;li>&lt;strong>Qué herramientas MCP está invocando&lt;/strong>, con qué argumentos.&lt;/li>
&lt;li>&lt;strong>Cuántos tokens consume&lt;/strong>, qué modelo elige, cuánto cuesta.&lt;/li>
&lt;li>&lt;strong>Si el agente se desvía&lt;/strong> del comportamiento esperado (out-of-policy queries, intentos de jailbreak, leakage de secretos).&lt;/li>
&lt;/ul>
&lt;p>Las soluciones tradicionales —instrumentar el código del agente con OpenTelemetry, parsear logs estructurados— no funcionan bien cuando el agente es un binario de terceros (Claude Code de Anthropic, Gemini CLI de Google) o cuando los MCP servers viven en otros lenguajes con stdio como transport.&lt;/p>
&lt;h3 id="agentsight-zero-instrumentation-para-agentes-llm">AgentSight: zero-instrumentation para agentes LLM&lt;/h3>
&lt;p>&lt;a href="https://github.com/eunomia-bpf/agentsight">&lt;strong>AgentSight&lt;/strong>&lt;/a> (proyecto del grupo &lt;code>eunomia-bpf&lt;/code>, mismo ecosistema de varios runtimes eBPF de alto perfil) ataca este problema con la misma filosofía que Hubble: &lt;strong>no instrumentes; escucha&lt;/strong>. Pone hooks eBPF en dos puntos críticos:&lt;/p>
&lt;ol>
&lt;li>
&lt;p>&lt;strong>uprobes en bibliotecas SSL/TLS&lt;/strong> (&lt;code>libssl&lt;/code>, &lt;code>boringssl&lt;/code>, &lt;code>rustls&lt;/code>). Captura el plaintext &lt;strong>antes&lt;/strong> del cifrado en send y &lt;strong>después&lt;/strong> del descifrado en recv. Para una llamada HTTP a &lt;code>https://api.anthropic.com/v1/messages&lt;/code>, AgentSight ve el JSON completo del prompt y la respuesta &lt;strong>sin descifrar nada en transit&lt;/strong>, simplemente porque ha llegado al nivel del syscall antes de que la TLS layer haga su trabajo.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>&lt;strong>&lt;code>stdiocap&lt;/code> BPF&lt;/strong>: captura &lt;code>read&lt;/code>, &lt;code>write&lt;/code>, &lt;code>dup&lt;/code> sobre los file descriptors de stdin/stdout/stderr de un proceso. Esto es lo que permite observar &lt;strong>MCP servers que hablan stdio&lt;/strong> con su cliente —el patrón habitual de los servers MCP locales—. Capturas el JSON-RPC que va y viene sin que ni el cliente ni el server lo sepan.&lt;/p>
&lt;/li>
&lt;/ol>
&lt;p>Sobrecarga reportada: &lt;strong>&amp;lt;3% CPU&lt;/strong>, comparable a Hubble en su régimen.&lt;/p>
&lt;h3 id="cómo-encaja-con-hubble-y-tetragon">Cómo encaja con Hubble y Tetragon&lt;/h3>
&lt;p>Los tres se complementan limpiamente:&lt;/p>
&lt;ul>
&lt;li>&lt;strong>Hubble&lt;/strong> te dice: &amp;ldquo;el pod del agente abrió conexión TCP a &lt;code>api.anthropic.com:443&lt;/code> con verdict ALLOW&amp;rdquo;.&lt;/li>
&lt;li>&lt;strong>Tetragon&lt;/strong> te dice: &amp;ldquo;el proceso &lt;code>claude-code&lt;/code> con PID 1843 hizo &lt;code>connect()&lt;/code> a esa IP&amp;rdquo; (más el binario, los argumentos, el namespace de pod).&lt;/li>
&lt;li>&lt;strong>AgentSight&lt;/strong> te dice: &amp;ldquo;el contenido HTTPS de esa conexión era un prompt &lt;code>messages=[{role:'user', content:'analyze this repo and modify the firewall config'}]&lt;/code> y la respuesta incluyó una tool call a &lt;code>read_file&lt;/code> con argument &lt;code>/etc/passwd&lt;/code>&amp;rdquo;.&lt;/li>
&lt;/ul>
&lt;p>Es la diferencia entre &lt;strong>flujo, proceso y semántica&lt;/strong>. Para un equipo de seguridad que quiera vigilar agentes de IA en producción, los tres son necesarios. Para alguien que quiera entender el coste, los tres son útiles (Hubble para latencia de red, Tetragon para uso de recursos, AgentSight para tokens y modelo elegido).&lt;/p>
&lt;h3 id="casos-de-uso-emergentes">Casos de uso emergentes&lt;/h3>
&lt;p>Los patrones que se están consolidando en 2026:&lt;/p>
&lt;ul>
&lt;li>&lt;strong>Audit trail de agentes&lt;/strong>: registrar cada llamada a LLM y cada tool call para compliance (sobre todo en sectores regulados).&lt;/li>
&lt;li>&lt;strong>Detección de jailbreak y prompt injection&lt;/strong>: aplicar reglas sobre los prompts capturados por AgentSight (similar a las TracingPolicy de Tetragon, pero sobre contenido semántico).&lt;/li>
&lt;li>&lt;strong>Cost accountability&lt;/strong>: ver qué team/agente consume qué tokens, sin instrumentar.&lt;/li>
&lt;li>&lt;strong>Replay y debug&lt;/strong>: reproducir el reasoning de un agente en producción sin pedirle que vuelva a ejecutar (que es no-determinístico).&lt;/li>
&lt;/ul>
&lt;p>Es un campo joven —AgentSight tiene meses, no años— pero el patrón &amp;ldquo;eBPF como observabilidad zero-instrumentation&amp;rdquo; está clarísimamente extendiéndose más allá de red y proceso. El próximo año va a ver consolidación y, probablemente, integración nativa con Hubble.&lt;/p>
&lt;h2 id="casos-de-uso-habituales-de-hubble">Casos de uso habituales de Hubble&lt;/h2>
&lt;p>Volviendo a Hubble propiamente, los casos en los que cualquier organización lo despliega:&lt;/p>
&lt;h3 id="1-debug-de-networkpolicy">1. Debug de NetworkPolicy&lt;/h3>
&lt;p>El uso clásico: &amp;ldquo;este pod no llega a este Service&amp;rdquo;. Sin Hubble, tocaba SSH, tcpdump, comparar reglas. Con Hubble:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">hubble observe --from-pod prod-api/checkout --to-pod prod-db/postgres --verdict DROPPED
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Si hay drops, ves la policy responsable (Cilium 1.19+). Si no hay drops, el problema no es policy: es DNS, routing o el target service.&lt;/p>
&lt;h3 id="2-audit-de-comunicación-inter-namespace">2. Audit de comunicación inter-namespace&lt;/h3>
&lt;p>Para compliance: validar que namespaces aislados no están comunicándose contra lo declarado.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">hubble observe --from-namespace prod-payments --to-namespace &lt;span class="s1">&amp;#39;NOT prod-db&amp;#39;&lt;/span> --output json
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="3-detección-de-exfiltración">3. Detección de exfiltración&lt;/h3>
&lt;p>Tráfico saliente a destinos públicos sospechosos. Hubble los detecta por IP/SNI, no por payload (que está cifrado):&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">hubble observe --to-fqdn &lt;span class="s1">&amp;#39;NOT *.example.com&amp;#39;&lt;/span> --to-fqdn &lt;span class="s1">&amp;#39;NOT *.internal&amp;#39;&lt;/span> --protocol tcp
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Combinado con métricas Prometheus y alertas en Grafana, esto da un radar de exfiltración a coste cero.&lt;/p>
&lt;h3 id="4-slo-de-servicio-en-tiempo-real">4. SLO de servicio en tiempo real&lt;/h3>
&lt;p>Métricas &lt;code>hubble:http:response_time_seconds&lt;/code> con labels &lt;code>source_workload&lt;/code>, &lt;code>destination_workload&lt;/code>, &lt;code>method&lt;/code>, &lt;code>status_code&lt;/code> permiten dashboards SLO sin necesidad de instrumentar las apps. El SRE ve la latencia p95 de &lt;code>checkout → catalog&lt;/code> directamente.&lt;/p>
&lt;h3 id="5-performance-debugging">5. Performance debugging&lt;/h3>
&lt;p>&lt;code>hubble:tcp:retransmissions_total&lt;/code> y &lt;code>hubble:tcp:flags_total{flag=&amp;quot;RST&amp;quot;}&lt;/code> son señales tempranas de problemas de red. Una subida correlada con regresión de latencia te apunta a algo en infraestructura (NIC, switch, MTU) antes de bajar a investigar la app.&lt;/p>
&lt;h3 id="6-forensics-post-incidente">6. Forensics post-incidente&lt;/h3>
&lt;p>Configurar Hubble para exportar flows a almacenamiento persistente (vía OTLP a Tempo/Loki, o &lt;code>hubble observe --output jsonpb&lt;/code> a S3) te da capacidad forense: si en T+30 días detectas que algo iba mal en T, puedes reconstruir el tráfico.&lt;/p>
&lt;h2 id="hubble-y-el-resto-del-stack-de-observabilidad">Hubble y el resto del stack de observabilidad&lt;/h2>
&lt;p>Hubble no reemplaza Prometheus, Loki, Tempo ni Jaeger; los complementa:&lt;/p>
&lt;ul>
&lt;li>&lt;strong>Prometheus&lt;/strong>: recibe las métricas agregadas de Hubble. Hubble exporta endpoint Prometheus nativo.&lt;/li>
&lt;li>&lt;strong>Loki&lt;/strong>: recibe los flow logs estructurados si los exportas como logs. Hubble no tiene exporter nativo a Loki, pero un Fluent Bit con plugin OTLP o uno custom hace el puente fácilmente.&lt;/li>
&lt;li>&lt;strong>Tempo / Jaeger&lt;/strong>: el Cilium Operator tiene exportador OTLP de flows en formato traces (cada flujo HTTP/gRPC es un span). Integra con Tempo o cualquier otro tracing backend OTLP.&lt;/li>
&lt;li>&lt;strong>Grafana&lt;/strong>: ya hay dashboards públicos de Hubble. Combinados con Prometheus, Loki y Tempo, te dan un panel unificado: métricas, logs, traces, todo correlado por labels K8s.&lt;/li>
&lt;/ul>
&lt;p>La pila full-stack que se ve en producción 2026 (descrita en &lt;a href="https://dev.to/x4nent/building-a-production-ebpf-observability-security-stack-for-kubernetes-in-2026-5051">Building a Production eBPF Observability &amp;amp; Security Stack for Kubernetes in 2026&lt;/a>):&lt;/p>
&lt;ul>
&lt;li>&lt;strong>Datos&lt;/strong>: Cilium + Hubble (red), Tetragon (proceso), AgentSight (agente IA).&lt;/li>
&lt;li>&lt;strong>Pipeline&lt;/strong>: OTLP Collector como router único.&lt;/li>
&lt;li>&lt;strong>Almacenamiento&lt;/strong>: Prometheus (métricas), Loki (logs), Tempo (traces).&lt;/li>
&lt;li>&lt;strong>UI&lt;/strong>: Grafana con dashboards específicos por dominio.&lt;/li>
&lt;li>&lt;strong>Alerting&lt;/strong>: AlertManager con reglas sobre las métricas Hubble + Tetragon.&lt;/li>
&lt;/ul>
&lt;h2 id="comparativa-con-alternativas">Comparativa con alternativas&lt;/h2>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>Sistema&lt;/th>
&lt;th>Capa&lt;/th>
&lt;th>Foco&lt;/th>
&lt;th>Modelo&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>&lt;strong>Hubble&lt;/strong>&lt;/td>
&lt;td>L3-L7 red&lt;/td>
&lt;td>Cluster K8s con Cilium&lt;/td>
&lt;td>eBPF, pull metrics, push flows gRPC&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;strong>GKE Dataplane v2 obs&lt;/strong>&lt;/td>
&lt;td>L3-L7 red&lt;/td>
&lt;td>GKE managed&lt;/td>
&lt;td>eBPF (Cilium-based, gestionado)&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;strong>Tigera Calico Whisker&lt;/strong>&lt;/td>
&lt;td>L3-L7 red&lt;/td>
&lt;td>Cluster con Calico&lt;/td>
&lt;td>eBPF + pcap, UI propia&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;strong>Tetragon&lt;/strong>&lt;/td>
&lt;td>Proceso/syscall&lt;/td>
&lt;td>Cluster K8s&lt;/td>
&lt;td>eBPF, push events gRPC&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;strong>Falco&lt;/strong>&lt;/td>
&lt;td>Proceso/syscall&lt;/td>
&lt;td>Cluster K8s&lt;/td>
&lt;td>eBPF en userspace o módulo kernel&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;strong>AgentSight&lt;/strong>&lt;/td>
&lt;td>Agente LLM&lt;/td>
&lt;td>Sistemas agentic&lt;/td>
&lt;td>eBPF (SSL uprobes + stdio)&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;strong>Beyla&lt;/strong> (Grafana)&lt;/td>
&lt;td>Aplicación&lt;/td>
&lt;td>App L7 + tracing&lt;/td>
&lt;td>eBPF (uprobes en libs)&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;strong>Pixie&lt;/strong>&lt;/td>
&lt;td>App + sistema&lt;/td>
&lt;td>Visibilidad cluster amplia&lt;/td>
&lt;td>eBPF + script PXL&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;strong>Parca&lt;/strong>&lt;/td>
&lt;td>Profiling CPU/mem&lt;/td>
&lt;td>Performance&lt;/td>
&lt;td>eBPF profile sampling&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;p>Si tu CNI es Cilium, &lt;strong>Hubble es el punto de entrada natural&lt;/strong> y no compite con los demás: complementa. Para clusters Calico, Whisker es el equivalente. Para profiling, Parca. Para agentes IA, AgentSight. La era del &amp;ldquo;una herramienta para todo&amp;rdquo; está pasando: la pila moderna combina varias piezas especializadas, todas basadas en eBPF, expuestas vía OTLP.&lt;/p>
&lt;h2 id="trampas-operativas">Trampas operativas&lt;/h2>
&lt;h3 id="cardinalidad-en-prometheus">Cardinalidad en Prometheus&lt;/h3>
&lt;p>Las métricas Hubble con todos los labels K8s pueden explotar Prometheus. &lt;strong>Mide la cardinalidad antes de exportar todo&lt;/strong>. Las métricas más prolíficas son &lt;code>flow&lt;/code> y &lt;code>httpV2&lt;/code>; empieza por &lt;code>drop&lt;/code> y &lt;code>port-distribution&lt;/code> y añade el resto incrementalmente.&lt;/p>
&lt;h3 id="l7-visibility-cuesta-cpu">L7 visibility cuesta CPU&lt;/h3>
&lt;p>Activar parsing L7 vía Envoy embebido añade carga al agent (no al datapath base, pero sí al envoy proxy del nodo). Para tráfico HTTP intenso, mide. Para flujos donde solo necesitas L4, deja Envoy desactivado.&lt;/p>
&lt;h3 id="hubble-relay-sin-ha">Hubble Relay sin HA&lt;/h3>
&lt;p>Una sola réplica de Relay es un single point of failure para CLI y UI (no para el agent local, que sigue funcionando). Para producción, deploy con &lt;code>replicas: 2+&lt;/code> y &lt;code>topologySpreadConstraints&lt;/code> para que no caigan ambas.&lt;/p>
&lt;h3 id="encryption-status-reporting-depende-de-cilium-config">Encryption status reporting depende de Cilium config&lt;/h3>
&lt;p>El nuevo filtro &lt;code>--encryption-status&lt;/code> solo da datos reales si Cilium tiene encryption activado (WireGuard o IPsec). Sin esto, todo es &lt;code>unencrypted&lt;/code> y el filtro no aporta.&lt;/p>
&lt;h3 id="ui-expuesta-sin-auth">UI expuesta sin auth&lt;/h3>
&lt;p>Hubble UI no tiene auth nativa. Si la expones por Ingress, &lt;strong>delante tiene que haber autenticación&lt;/strong>: OIDC vía oauth2-proxy, mTLS, IP allowlist. No es opcional.&lt;/p>
&lt;h3 id="storage-no-escalado">Storage no escalado&lt;/h3>
&lt;p>Si guardas flows durante días para forensics, el volumen es serio. Para un cluster de 100 pods activos, fácilmente 1-10 GB/día de flow logs. Plantea el ciclo de vida (compactación, retención, cold storage) antes de habilitarlo.&lt;/p>
&lt;h2 id="lo-que-no-hemos-cubierto">Lo que no hemos cubierto&lt;/h2>
&lt;ul>
&lt;li>&lt;strong>Mesh / multi-cluster Hubble&lt;/strong>: agregar flows de varios clusters Cilium en una sola Relay. Caso de uso: visión cross-cluster, debug de service mesh distribuido.&lt;/li>
&lt;li>&lt;strong>&lt;code>hubble export&lt;/code>&lt;/strong>: persistencia local en disco del agent para forensics con baja retención.&lt;/li>
&lt;li>&lt;strong>Anomaly detection con modelos propios&lt;/strong>: cómo conectar el stream gRPC a un consumer ML personalizado.&lt;/li>
&lt;li>&lt;strong>AgentSight en profundidad&lt;/strong>: el proyecto merece su propio artículo. Próxima entrega.&lt;/li>
&lt;li>&lt;strong>eBPF para profiling de LLM serving&lt;/strong>: cómo medir TTFT, TPOT y throughput de vLLM sin instrumentar, usando uprobes en libcudart.&lt;/li>
&lt;/ul>
&lt;h2 id="referencias">Referencias&lt;/h2>
&lt;p>Hubble y Cilium:&lt;/p>
&lt;ul>
&lt;li>&lt;a href="https://github.com/cilium/hubble">Hubble GitHub&lt;/a> — repo principal.&lt;/li>
&lt;li>&lt;a href="https://docs.cilium.io/en/stable/observability/hubble/">Hubble — Network Observability (Cilium docs)&lt;/a> — referencia oficial.&lt;/li>
&lt;li>&lt;a href="https://www.infoq.com/news/2026/02/cilium-119/">Cilium 1.19 release notes (InfoQ, feb 2026)&lt;/a> — décimo aniversario y novedades 1.19.&lt;/li>
&lt;li>&lt;a href="https://github.com/cilium/cilium/releases">Cilium releases&lt;/a> — todos los releases.&lt;/li>
&lt;li>&lt;a href="https://grafana.com/grafana/dashboards/19423-hubble-l7-http-metrics-by-workload/">Hubble L7 HTTP Metrics — Grafana dashboard 19423&lt;/a> — listo para importar.&lt;/li>
&lt;li>&lt;a href="https://cloud-cod.com/index.php/2026/03/03/end-to-end-l7-visibility-with-cilium-hubble/">End‑to‑end L7 Visibility with Cilium Hubble (cloud-cod.com, mar 2026)&lt;/a>.&lt;/li>
&lt;li>&lt;a href="https://www.youngju.dev/blog/cilium/cilium_hubble_observability.en">Cilium Hubble Observability Platform Internal Analysis (Young-ju)&lt;/a>.&lt;/li>
&lt;li>&lt;a href="https://johal.in/ciliumnetworkpolicy-python-hubble-l7-visibility-2026/">CiliumNetworkPolicy Python Hubble: L7 Visibility 2026&lt;/a> — uno de los hilos del SDK Python.&lt;/li>
&lt;/ul>
&lt;p>Estado del arte 2026 y stack completo:&lt;/p>
&lt;ul>
&lt;li>&lt;a href="https://dev.to/x4nent/building-a-production-ebpf-observability-security-stack-for-kubernetes-in-2026-5051">Building a Production eBPF Observability &amp;amp; Security Stack for Kubernetes in 2026 (DEV)&lt;/a>.&lt;/li>
&lt;li>&lt;a href="https://www.cloudraft.io/blog/ebpf-based-network-observability-using-cilium-hubble">eBPF-Based Network Observability: Exploring Cilium Hubble and Alternatives (CloudRaft)&lt;/a>.&lt;/li>
&lt;/ul>
&lt;p>eBPF + agentes IA:&lt;/p>
&lt;ul>
&lt;li>&lt;a href="https://github.com/eunomia-bpf/agentsight">AgentSight (GitHub eunomia-bpf)&lt;/a> — el proyecto referenciado.&lt;/li>
&lt;li>&lt;a href="https://klizosolutions.medium.com/harnessing-ebpf-for-high-performance-llm-workloads-a-cloud-native-guide-efb7d73e19ed">Harnessing eBPF for High‑Performance LLM Workloads (Klizo Solutions)&lt;/a>.&lt;/li>
&lt;/ul>
&lt;p>Cross-references:&lt;/p>
&lt;ul>
&lt;li>Parte 1: &lt;a href="https://blog.lo0.es/posts/ebpf-cilium-tcp-ip-bypass/">eBPF de cero a Cilium&lt;/a>.&lt;/li>
&lt;li>Parte 2: &lt;a href="https://blog.lo0.es/posts/tetragon-runtime-security/">Tetragon: el primo de seguridad de Cilium&lt;/a>.&lt;/li>
&lt;li>Serie de inferencia LLM: &lt;a href="https://blog.lo0.es/posts/kv-cache-fundamentos/">KV cache&lt;/a>, &lt;a href="https://blog.lo0.es/posts/vllm-kubernetes/">vLLM en K8s&lt;/a>, &lt;a href="https://blog.lo0.es/posts/pagedattention-deep-dive/">PagedAttention&lt;/a>, &lt;a href="https://blog.lo0.es/posts/operators-llm-kubernetes/">Operators LLM K8s&lt;/a> — donde el tráfico que Hubble observa lleva los prompts que AgentSight inspecciona.&lt;/li>
&lt;/ul></description></item></channel></rss>