<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Xdp on lo0 — Blog Técnico</title><link>https://blog.lo0.es/tags/xdp/</link><description>Recent content in Xdp on lo0 — Blog Técnico</description><generator>Hugo -- gohugo.io</generator><language>es</language><lastBuildDate>Tue, 19 May 2026 04:30:00 +0200</lastBuildDate><atom:link href="https://blog.lo0.es/tags/xdp/index.xml" rel="self" type="application/rss+xml"/><item><title>eBPF de cero a Cilium: cómo el kernel aprendió a saltarse su propia pila TCP/IP</title><link>https://blog.lo0.es/posts/ebpf-cilium-tcp-ip-bypass/</link><pubDate>Tue, 19 May 2026 04:30:00 +0200</pubDate><guid>https://blog.lo0.es/posts/ebpf-cilium-tcp-ip-bypass/</guid><description>&lt;h2 id="tldr">TL;DR&lt;/h2>
&lt;p>eBPF es &lt;strong>una máquina virtual sandboxed dentro del kernel Linux&lt;/strong> que ejecuta código verificado en hooks bien definidos: kprobes, tracepoints, socket events, drivers de red. Antes de eBPF, modificar el comportamiento del kernel era recompilarlo o cargar un módulo arbitrario; con eBPF, cargas un programa pequeño que pasa un verificador formal y se ejecuta a velocidad nativa con seguridad de memoria. En networking, esto se traduce en que &lt;strong>el paquete no tiene que recorrer la pila TCP/IP tradicional&lt;/strong>: un programa eBPF en el driver de la NIC (XDP) puede dropear, reenviar o reescribir el paquete antes de que el kernel haya hecho su primer alloc; un programa en cgroup hooks (sock_ops) puede redirigir conexiones a otro socket sin que el paquete llegue siquiera a salir de la máquina. Cilium es el CNI que ha llevado esto a su conclusión lógica: &lt;strong>reemplaza kube-proxy por eBPF puro&lt;/strong> (O(1) en lugar de O(N) de iptables), enruta pod-a-pod sin VXLAN cuando puede, evalúa Network Policies con BPF maps, y desde 1.16 ha rehecho su control plane de BGP con un set nuevo de CRDs —&lt;code>CiliumBGPClusterConfig&lt;/code>, &lt;code>CiliumBGPPeerConfig&lt;/code>, &lt;code>CiliumBGPAdvertisement&lt;/code>, &lt;code>CiliumBGPNodeConfigOverride&lt;/code>— que sustituyen al monolítico &lt;code>CiliumBGPPeeringPolicy&lt;/code> que ya está deprecado. Este artículo baja por las tres capas (eBPF básico → eBPF networking → Cilium) y termina con los CRDs operativos.&lt;/p>
&lt;h2 id="la-analogía-plugins-firmados-para-el-kernel">La analogía: plugins firmados para el kernel&lt;/h2>
&lt;p>Imagina el navegador. Hace 20 años, extender un navegador significaba compilar un binario nativo y cargarlo: cualquier extensión podía estrellarlo, corromper memoria, leer cookies del banco. Hoy, las extensiones son &lt;strong>JavaScript en una sandbox&lt;/strong> con un manifest que declara permisos, un runtime que aplica el aislamiento y una tienda que firma el código. La extensión no toca el binario del navegador; vive en un mundo controlado y solo puede hablar con el navegador a través de APIs definidas. Resultado: extensibilidad masiva con superficie de ataque acotada.&lt;/p>
&lt;p>eBPF es exactamente eso para el kernel Linux. Cargar un módulo &lt;code>.ko&lt;/code> clásico es cargar código nativo con acceso total a memoria del kernel: un bug y se va el sistema. eBPF es &lt;strong>una VM bytecode&lt;/strong> con verificador estático, allocator controlado, JIT al hardware nativo después de pasar el verificador, y un set de &amp;ldquo;helpers&amp;rdquo; del kernel a los que puede llamar. El programa eBPF puede leer la memoria del kernel donde el verificador le permite leer, y solo eso. No puede entrar en loops infinitos (el verificador exige que termine). No puede saltar a direcciones arbitrarias. No puede dereferenciar punteros sin haberlos validado primero. Y, lo más importante: &lt;strong>es código de usuario, cargado en runtime, que ejecuta dentro del kernel a velocidad nativa&lt;/strong>.&lt;/p>
&lt;p>Las consecuencias se notan a kilómetros. Antes, observar tráfico en producción significaba parchear el kernel o cargar un módulo de riesgo. Hoy, &lt;code>bpftrace -e 'tracepoint:net:net_dev_xmit { @[args-&amp;gt;dev-&amp;gt;name] = count(); }'&lt;/code> te da un histograma de paquetes por interfaz en tres líneas y cero downtime. Antes, sustituir iptables por algo más rápido implicaba reescribir el subsistema de netfilter. Hoy, Cilium carga 60 KB de bytecode eBPF en XDP y desbanca a iptables con un map de hashes.&lt;/p>
&lt;h2 id="ebpf-básico-qué-es-y-qué-no-es">eBPF básico: qué es y qué no es&lt;/h2>
&lt;h3 id="el-origen-y-el-alcance">El origen y el alcance&lt;/h3>
&lt;p>El nombre viene de &lt;strong>Berkeley Packet Filter&lt;/strong>, una idea de 1992 (McCanne y Jacobson) para filtrar paquetes con un mini-bytecode que &lt;code>tcpdump&lt;/code> usaba internamente. En 2014, Alexei Starovoitov lo rebautizó como &lt;strong>eBPF&lt;/strong> y lo extendió enormemente: 11 registros de 64 bits en lugar de 2 de 32, stack de 512 bytes, mapas como estructuras compartidas con userspace, JIT al hardware nativo, y un verificador formal mucho más sofisticado. De ser un filtro de paquetes, pasó a ser &lt;strong>un mecanismo de extensibilidad genérico del kernel&lt;/strong>.&lt;/p>
&lt;p>Hoy eBPF se usa para cuatro cosas:&lt;/p>
&lt;ol>
&lt;li>&lt;strong>Networking&lt;/strong>: XDP, TC, cgroup hooks, socket ops, lightweight tunnels.&lt;/li>
&lt;li>&lt;strong>Observabilidad&lt;/strong>: kprobes, uprobes, tracepoints, USDT. La base de proyectos como &lt;code>bpftrace&lt;/code>, &lt;code>bcc&lt;/code>, Pixie, Parca.&lt;/li>
&lt;li>&lt;strong>Seguridad&lt;/strong>: BPF LSM (Linux Security Module en eBPF), bloqueos de syscall con seccomp-bpf. Falco, Tetragon, Tracee.&lt;/li>
&lt;li>&lt;strong>Scheduling&lt;/strong>: sched_ext (kernel 6.12+), schedulers de procesos completamente en eBPF. Aún en fase muy temprana.&lt;/li>
&lt;/ol>
&lt;h3 id="la-vm">La VM&lt;/h3>
&lt;p>Un programa eBPF se compila desde C (o Rust, Go con cilium/ebpf) a bytecode eBPF, no a x86/arm64 directamente. El loader del kernel (vía syscall &lt;code>bpf()&lt;/code>) pasa ese bytecode por &lt;strong>el verificador&lt;/strong>:&lt;/p>
&lt;ul>
&lt;li>Reconstruye el grafo de control de flujo.&lt;/li>
&lt;li>Hace análisis estático de cada path posible: cada instrucción tiene que ser alcanzable, cada acceso a memoria tiene que estar dentro de bounds conocidos, cada puntero tiene que haber sido validado.&lt;/li>
&lt;li>Rechaza loops sin un upper bound conocido. Los kernels recientes admiten loops acotados (&lt;code>bpf_loop&lt;/code> helper), pero el contador siempre es finito.&lt;/li>
&lt;li>Rechaza llamadas a helpers o kfuncs que el program type del hook no permita.&lt;/li>
&lt;/ul>
&lt;p>Si el verificador acepta el programa, el JIT lo traduce a código nativo del host (x86, arm64, etc.) y queda atado a su hook. A partir de ahí se ejecuta cada vez que el evento del hook ocurre, &lt;strong>sin context switch a userspace&lt;/strong>, &lt;strong>sin coste de syscall&lt;/strong>. Latencias del orden de cientos de nanosegundos por invocación.&lt;/p>
&lt;h3 id="maps-el-puente-con-userspace">Maps: el puente con userspace&lt;/h3>
&lt;p>Un programa eBPF aislado no sirve de mucho. Lo que lo hace útil son los &lt;strong>maps&lt;/strong>: estructuras de datos compartidas entre el programa kernel y el espacio de usuario. Hay varios tipos:&lt;/p>
&lt;ul>
&lt;li>&lt;code>BPF_MAP_TYPE_HASH&lt;/code>, &lt;code>BPF_MAP_TYPE_LRU_HASH&lt;/code>: hash tables con o sin desalojo LRU.&lt;/li>
&lt;li>&lt;code>BPF_MAP_TYPE_ARRAY&lt;/code>, &lt;code>BPF_MAP_TYPE_PERCPU_ARRAY&lt;/code>: arrays, opcionalmente per-CPU para evitar contención.&lt;/li>
&lt;li>&lt;code>BPF_MAP_TYPE_RINGBUF&lt;/code>, &lt;code>BPF_MAP_TYPE_PERF_EVENT_ARRAY&lt;/code>: canales para enviar eventos a userspace en streaming.&lt;/li>
&lt;li>&lt;code>BPF_MAP_TYPE_PROG_ARRAY&lt;/code>: arrays de programas eBPF para tail calls (encadenamiento de programas sin volver al kernel base).&lt;/li>
&lt;/ul>
&lt;p>Userspace lee y escribe estos maps vía syscalls &lt;code>bpf()&lt;/code>; el programa kernel los lee y escribe directamente. Es la base de cualquier sistema eBPF: el programa kernel recoge datos en un map, el daemon en userspace los lee. Cilium hace exactamente esto: el agente userland (Go) gestiona la política y la traduce a entradas en maps; los programas eBPF que viven en XDP/TC leen los maps y aplican las decisiones.&lt;/p>
&lt;h3 id="co-re-compila-una-vez-corre-en-cualquier-kernel">CO-RE: compila una vez, corre en cualquier kernel&lt;/h3>
&lt;p>Una pesadilla clásica de los módulos de kernel: están atados a la versión exacta del kernel donde se compilaron. Distribuir un módulo precompilado para un parque de máquinas con distintas distros era imposible.&lt;/p>
&lt;p>eBPF resuelve esto con &lt;strong>CO-RE (Compile Once, Run Everywhere)&lt;/strong>: el bytecode incluye &lt;strong>relocaciones&lt;/strong> que el loader resuelve en cada kernel concreto consultando &lt;strong>BTF (BPF Type Format)&lt;/strong>, una representación del layout de las structs del kernel que el propio kernel publica. Resultado: un único binario eBPF funciona en kernels 5.10, 5.15, 6.1 y 6.8 sin recompilar, porque el loader ajusta los offsets de acceso a structs en runtime.&lt;/p>
&lt;p>Esto es lo que ha permitido que distribuciones eBPF productivas existan. Sin CO-RE, cada kernel sería un proyecto de portado.&lt;/p>
&lt;h2 id="ebpf-en-networking-los-hooks-que-importan">eBPF en networking: los hooks que importan&lt;/h2>
&lt;p>Dentro del subsistema de red de Linux, eBPF tiene varios hooks. Los relevantes para CNIs:&lt;/p>
&lt;h3 id="xdp--express-data-path">XDP — eXpress Data Path&lt;/h3>
&lt;p>XDP es &lt;strong>el hook más temprano&lt;/strong>: se ejecuta en el driver de la NIC, &lt;strong>antes de que el paquete entre en el kernel propiamente&lt;/strong>. No hay &lt;code>sk_buff&lt;/code> (la struct que el resto del kernel usa para representar paquetes); solo hay un puntero a un buffer de RAM con los bytes recibidos.&lt;/p>
&lt;p>Las acciones que un programa XDP puede devolver:&lt;/p>
&lt;ul>
&lt;li>&lt;code>XDP_DROP&lt;/code>: tirar el paquete inmediatamente. El driver lo deja caer y libera el buffer. Coste: nanosegundos. Caso de uso: DDoS mitigation. Cloudflare procesó &lt;strong>más de 8 millones de paquetes/segundo por CPU&lt;/strong> con XDP para drop de SYN floods.&lt;/li>
&lt;li>&lt;code>XDP_PASS&lt;/code>: dejar que el paquete siga al kernel normal. Pasa a &lt;code>sk_buff&lt;/code> y entra en el stack tradicional.&lt;/li>
&lt;li>&lt;code>XDP_TX&lt;/code>: reenviar por la misma interfaz tras posibles modificaciones. Útil para load balancers L4 que reescriben destino y devuelven.&lt;/li>
&lt;li>&lt;code>XDP_REDIRECT&lt;/code>: enviar el paquete a otra interfaz o a un map (para forward a userspace via AF_XDP, o a otra NIC, o a un veth de un pod).&lt;/li>
&lt;li>&lt;code>XDP_ABORTED&lt;/code>: error (incrementa un contador, dropea).&lt;/li>
&lt;/ul>
&lt;p>Casos de uso reales:&lt;/p>
&lt;ul>
&lt;li>&lt;strong>Cloudflare L3 DDoS protection&lt;/strong>: reglas XDP que drop millones de paquetes/s.&lt;/li>
&lt;li>&lt;strong>Facebook Katran&lt;/strong>: L4 load balancer que reescribe destino IP y devuelve por la misma interfaz. Maneja 10× más conexiones por servidor que IPVS clásico.&lt;/li>
&lt;li>&lt;strong>Cilium XDP acceleration&lt;/strong>: load balancing de Services en la capa más baja posible.&lt;/li>
&lt;/ul>
&lt;h3 id="tc-traffic-control--clsact-con-bpf">TC (Traffic Control) — clsact con BPF&lt;/h3>
&lt;p>XDP es muy rápido pero limitado: el paquete aún no tiene &lt;code>sk_buff&lt;/code> y muchas decisiones (conntrack, NAT, encapsulación con metadatos) son más fáciles cuando sí lo tiene. El hook &lt;strong>TC clsact con BPF&lt;/strong> se ejecuta &lt;strong>después&lt;/strong> de construir el &lt;code>sk_buff&lt;/code> pero &lt;strong>antes de&lt;/strong> las decisiones de routing y netfilter. Acciones:&lt;/p>
&lt;ul>
&lt;li>&lt;code>TC_ACT_OK&lt;/code>: el paquete sigue por el stack.&lt;/li>
&lt;li>&lt;code>TC_ACT_SHOT&lt;/code>: drop.&lt;/li>
&lt;li>&lt;code>TC_ACT_REDIRECT&lt;/code>: redirigir a otra interfaz.&lt;/li>
&lt;li>&lt;code>TC_ACT_PIPE&lt;/code>, &lt;code>TC_ACT_STOLEN&lt;/code>: control de pipeline para combinarse con otros qdiscs.&lt;/li>
&lt;/ul>
&lt;p>Casos de uso:&lt;/p>
&lt;ul>
&lt;li>&lt;strong>Network policy stateful&lt;/strong>: Cilium evalúa políticas L3-L7 en TC con &lt;code>sk_buff&lt;/code> completo y conntrack disponible.&lt;/li>
&lt;li>&lt;strong>Marcado y QoS&lt;/strong>: marcado de tráfico para que el scheduler aplique prioridades.&lt;/li>
&lt;li>&lt;strong>Encapsulación overlay&lt;/strong>: añadir headers VXLAN/Geneve cuando el modo es tunnel.&lt;/li>
&lt;/ul>
&lt;p>XDP y TC se combinan: &lt;strong>XDP para lo barato y temprano&lt;/strong> (DDoS, LB simple), &lt;strong>TC para lo que necesita &lt;code>skb&lt;/code> y stateful&lt;/strong>.&lt;/p>
&lt;h3 id="cgroup-hooks-sock_ops-y-cgroup_sock_addr">Cgroup hooks: sock_ops y CGROUP_SOCK_ADDR&lt;/h3>
&lt;p>El paso conceptual más radical: hooks que no están en la capa de red sino &lt;strong>en la capa de socket&lt;/strong>. Tipos relevantes:&lt;/p>
&lt;ul>
&lt;li>&lt;code>BPF_PROG_TYPE_CGROUP_SOCK_ADDR&lt;/code>: se invoca cuando un proceso de un cgroup hace &lt;code>connect()&lt;/code>, &lt;code>bind()&lt;/code>, &lt;code>sendto()&lt;/code>. El programa eBPF puede &lt;strong>reescribir la dirección de destino&lt;/strong> antes de que la conexión salga. Es lo que permite a Cilium hacer load balancing de Services &lt;strong>sin que el paquete entre en la pila de red&lt;/strong>: si el cliente intenta conectar a &lt;code>10.96.0.1:443&lt;/code> (ClusterIP), un programa eBPF en este hook reescribe el destino a la IP real del pod backend antes de que el syscall continúe.&lt;/li>
&lt;li>&lt;code>BPF_PROG_TYPE_SOCK_OPS&lt;/code>: se invoca en eventos TCP (creación, establecido, retransmisión). Permite ajustar parámetros del socket en runtime y, lo más importante, &lt;strong>emparejar sockets locales&lt;/strong> vía &lt;code>bpf_sk_assign&lt;/code> para shortcut sin que el paquete viaje por la red.&lt;/li>
&lt;/ul>
&lt;p>Esta es la &amp;ldquo;tercera capa&amp;rdquo; del bypass: no es solo más rápido, es &lt;strong>conceptualmente distinto&lt;/strong>. El paquete no se construye, no se serializa, no recorre IP layer ni TCP layer. Es la diferencia entre acelerar una carretera y descubrir que para algunos viajes no hace falta tomar el coche.&lt;/p>
&lt;h2 id="el-camino-largo-cómo-es-la-pila-tcpip-tradicional">El camino largo: cómo es la pila TCP/IP tradicional&lt;/h2>
&lt;p>Para apreciar lo que eBPF ahorra, vale la pena trazar el recorrido completo de un paquete por la pila Linux. Tomemos el caso &amp;ldquo;paquete entra por una NIC, va a un proceso local&amp;rdquo;:&lt;/p>
&lt;pre tabindex="0">&lt;code>NIC (DMA al ring buffer del driver)
↓
driver: napi_schedule, poll, asigna sk_buff
↓
[XDP hook] ← si hay programa XDP, se decide aquí
↓
netif_receive_skb
↓
__netif_receive_skb_core
↓
[TC ingress clsact + BPF] ← si hay programa TC ingress
↓
packet_type handlers (IP, ARP...)
↓
ip_rcv → ip_rcv_core
↓
[netfilter NF_INET_PRE_ROUTING] ← iptables PREROUTING
↓
routing decision (FIB lookup)
↓
[netfilter NF_INET_LOCAL_IN] o [NF_INET_FORWARD]
↓
tcp_v4_rcv → tcp_v4_do_rcv
↓
tcp_rcv_established
↓
sk_data_ready
↓
proceso lee con recv()/read()
&lt;/code>&lt;/pre>&lt;p>Cada flecha es una llamada de función con coste medible. Cada netfilter hook recorre todas las reglas iptables/nftables registradas. Con kube-proxy en modo iptables y 5 000 Services × 10 endpoints cada uno, hay del orden de &lt;strong>150 000 reglas&lt;/strong> que se evalúan secuencialmente en &lt;code>NF_INET_PRE_ROUTING&lt;/code>. Los benchmarks publicados muestran latencias de &lt;strong>decenas de microsegundos por paquete&lt;/strong> en clusters Kubernetes grandes solo en el paso de netfilter, &lt;strong>antes&lt;/strong> de que la aplicación reciba nada.&lt;/p>
&lt;p>Y eso es el camino normal. En el camino de salida pasa lo mismo pero en sentido inverso: &lt;code>tcp_sendmsg → ip_output → NF_INET_LOCAL_OUT → routing → NF_INET_POSTROUTING → dev_queue_xmit → driver → NIC&lt;/code>.&lt;/p>
&lt;h2 id="cómo-cilium-se-salta-esta-pila">Cómo Cilium se salta esta pila&lt;/h2>
&lt;p>Cilium no elimina la pila TCP/IP; sigue ahí para los casos que la necesitan. Lo que hace es &lt;strong>shortcuts&lt;/strong> en los puntos donde duele.&lt;/p>
&lt;h3 id="shortcut-1--xdp-para-el-datapath-de-service">Shortcut 1 — XDP para el datapath de Service&lt;/h3>
&lt;p>Para un cluster con 5 000 Services, kube-proxy iptables tiene un coste O(N) en evaluar reglas (incluso con &lt;code>iptables-restore --noflush&lt;/code> y trucos, sigue siendo lineal en el número de chains que el paquete atraviesa).&lt;/p>
&lt;p>Cilium lo sustituye así:&lt;/p>
&lt;ul>
&lt;li>Cada Service y sus endpoints viven en &lt;strong>un eBPF hash map&lt;/strong>.&lt;/li>
&lt;li>Cuando entra un paquete con destino a una ClusterIP, el programa XDP de Cilium hace &lt;strong>un lookup O(1)&lt;/strong> en ese map y obtiene el endpoint backend.&lt;/li>
&lt;li>Reescribe el destino y &lt;code>XDP_TX&lt;/code> (devuelve por la misma interfaz hacia el backend) o &lt;code>XDP_REDIRECT&lt;/code> (lo envía a la veth del pod local correspondiente).&lt;/li>
&lt;/ul>
&lt;p>Esto significa que el coste no crece con el número de Services. 100 Services o 100 000, &lt;strong>lookup constante en el map&lt;/strong>. Benchmarks publicados muestran reducciones de latencia de &lt;strong>30-50%&lt;/strong> en clusters con muchos Services frente a kube-proxy iptables, y de orden de magnitud frente a IPVS en algunos casos.&lt;/p>
&lt;h3 id="shortcut-2--socket-lb-el-paquete-no-se-llega-a-construir">Shortcut 2 — socket-LB: el paquete no se llega a construir&lt;/h3>
&lt;p>Cilium 1.6+ introdujo el &lt;strong>socket-level load balancing&lt;/strong>, basado en cgroup hooks. Funciona así:&lt;/p>
&lt;ul>
&lt;li>Cuando un pod hace &lt;code>connect(10.96.0.1:443)&lt;/code> (ClusterIP de un Service), el syscall entra en el kernel.&lt;/li>
&lt;li>Antes de que el kernel construya nada de red, &lt;strong>un programa eBPF en &lt;code>CGROUP_SOCK_ADDR/connect4&lt;/code>&lt;/strong> intercepta y &lt;strong>reescribe la dirección de destino&lt;/strong> a la IP real del pod backend.&lt;/li>
&lt;li>El kernel continúa con el &lt;code>connect&lt;/code> como si el cliente hubiera escrito directamente &lt;code>10.0.0.42:8080&lt;/code>.&lt;/li>
&lt;/ul>
&lt;p>¿Por qué importa? Porque cuando el pod backend está &lt;strong>en el mismo nodo&lt;/strong>, este shortcut convierte una llamada que habría implicado:&lt;/p>
&lt;pre tabindex="0">&lt;code>syscall connect → kernel stack → veth → bridge → veth → kernel stack → syscall accept
&lt;/code>&lt;/pre>&lt;p>en:&lt;/p>
&lt;pre tabindex="0">&lt;code>syscall connect (con destino reescrito) → loopback directo
&lt;/code>&lt;/pre>&lt;p>La pila TCP/IP se evita literalmente. No hay paquete encapsulado, no hay viaje por veth pairs, no hay netfilter. Latencias L7 de pod-a-pod en el mismo nodo bajan a niveles de &lt;strong>comunicación local&lt;/strong> (~5-15 µs en lugar de ~30-50 µs para servicios con kube-proxy iptables y veth tradicional).&lt;/p>
&lt;h3 id="shortcut-3--direct-routing-pod-a-pod">Shortcut 3 — direct routing pod-a-pod&lt;/h3>
&lt;p>El modo overlay tradicional (Flannel, Calico VXLAN) encapsula cada paquete pod-a-pod en VXLAN/Geneve. Cada paquete carga un header extra de 50 bytes, requiere encap/decap, y consume MTU.&lt;/p>
&lt;p>Cilium soporta &lt;strong>direct routing&lt;/strong>: los pod CIDRs se anuncian a la fabric subyacente (con BGP, ahí entra el control plane que veremos) y los routers físicos enrutan los paquetes pod-a-pod &lt;strong>sin encapsular&lt;/strong>. El paquete sale de un pod con su IP original como source y la IP del pod destino como dest, la NIC del nodo lo entrega a la red, la red lo enruta, llega al nodo destino y se entrega al pod. Cero encap, MTU completo, latencia mínima.&lt;/p>
&lt;p>Cilium hace esto &lt;strong>vía programas eBPF en TC&lt;/strong> que reescriben las cabeceras necesarias y deciden si el paquete va por encap o direct según la política configurada por nodo.&lt;/p>
&lt;h3 id="shortcut-4--network-policy-en-tc-con-maps">Shortcut 4 — Network Policy en TC con maps&lt;/h3>
&lt;p>Las Network Policies en CNIs clásicos suelen traducirse a reglas iptables, otro factor que explota linealmente. Cilium las evalúa en programas eBPF que leen &lt;strong>maps de identity&lt;/strong>: cada workload tiene un identifier numérico calculado desde sus labels, y la policy es un map &lt;code>(src_identity, dst_identity, port, proto) → allow|deny&lt;/code>. Un lookup en hash map por paquete.&lt;/p>
&lt;p>Esto también permite las &lt;strong>L7 policies&lt;/strong> de Cilium (filtrado HTTP, gRPC, Kafka): el programa eBPF reconoce el handshake L7, redirige selectivamente al proxy Envoy embebido (que vive como sidecar del datapath, no como sidecar de pod) y solo en ese subset paga el coste del proxy L7. Todo el tráfico L3/L4 sigue por el fast path eBPF.&lt;/p>
&lt;h2 id="cilium-la-arquitectura">Cilium: la arquitectura&lt;/h2>
&lt;p>Cilium combina dos planos:&lt;/p>
&lt;ul>
&lt;li>&lt;strong>Agent (Go)&lt;/strong>: vive como DaemonSet en cada nodo. Es lo &amp;ldquo;lento&amp;rdquo;: traduce el deseo expresado en CRDs (CiliumNetworkPolicy, CiliumBGPClusterConfig, etc.) en entradas en eBPF maps. Habla con el API server de Kubernetes para descubrir endpoints, services, pods. Embebe un GoBGP para el control plane de BGP. Embebe un Envoy para L7 policies.&lt;/li>
&lt;li>&lt;strong>Datapath (eBPF)&lt;/strong>: los programas cargados en XDP, TC, cgroup hooks. Son lo &amp;ldquo;rápido&amp;rdquo;: ven cada paquete, leen los maps que el agent mantiene, deciden en nanosegundos.&lt;/li>
&lt;/ul>
&lt;p>Esta separación es lo que hace operacionalmente cómodo a Cilium: el deseo se expresa en YAML, el agent lo materializa en maps, los maps son leídos por el datapath. Si el agent se cae temporalmente, el datapath sigue funcionando con la última configuración cargada. Como en cualquier sistema de control/data plane bien hecho.&lt;/p>
&lt;h2 id="el-bgp-control-plane-v2-los-crds-que-tienes-que-conocer">El BGP Control Plane v2: los CRDs que tienes que conocer&lt;/h2>
&lt;p>Cilium ha tenido soporte de BGP varios años. La primera versión usaba un único CRD monolítico, &lt;code>CiliumBGPPeeringPolicy&lt;/code>, que mezclaba en un solo objeto la configuración del nodo, los peers, los timers y los anuncios. Desde &lt;strong>Cilium 1.16&lt;/strong> existe el &lt;strong>BGP Control Plane v2&lt;/strong>, que descompone esa configuración en CRDs separados con responsabilidades claras. El &lt;code>CiliumBGPPeeringPolicy&lt;/code> (API &lt;code>cilium.io/v2alpha1&lt;/code>) está &lt;strong>deprecated&lt;/strong> y los avisos de migración aparecen en los logs del operator si todavía lo usas.&lt;/p>
&lt;p>Los CRDs nuevos (API &lt;code>cilium.io/v2&lt;/code>):&lt;/p>
&lt;h3 id="1-ciliumbgpclusterconfig">1. &lt;code>CiliumBGPClusterConfig&lt;/code>&lt;/h3>
&lt;p>Define &lt;strong>instancias BGP&lt;/strong> y los peers a los que se conectan, desde la perspectiva del cluster. Se selecciona qué nodos aplican esta configuración con un &lt;code>nodeSelector&lt;/code>.&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="nt">apiVersion&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">cilium.io/v2&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">kind&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">CiliumBGPClusterConfig&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">metadata&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">name&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">cilium-bgp-cluster&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">spec&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">nodeSelector&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">matchLabels&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">bgp-policy&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">rack-1 &lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="c"># solo nodos con esta label&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">bgpInstances&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">name&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">instance-65000&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">localASN&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">65000&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">peers&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">name&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">top-of-rack-1a&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">peerASN&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">64512&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">peerAddress&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">10.0.1.1&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">peerConfigRef&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">name&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">tor-shared-config &lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="c"># → referencia a CiliumBGPPeerConfig&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">name&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">top-of-rack-1b&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">peerASN&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">64512&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">peerAddress&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">10.0.1.2&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">peerConfigRef&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">name&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">tor-shared-config&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Una instancia BGP es la abstracción &amp;ldquo;este nodo participa en BGP con este ASN local y estos peers&amp;rdquo;. Pueden coexistir varias en un mismo nodo (multi-instancia para multi-VRF).&lt;/p>
&lt;h3 id="2-ciliumbgppeerconfig">2. &lt;code>CiliumBGPPeerConfig&lt;/code>&lt;/h3>
&lt;p>Define los &lt;strong>parámetros compartidos&lt;/strong> del peering: timers, address families, transport, password MD5, graceful restart, etc. Se referencia desde &lt;code>CiliumBGPClusterConfig&lt;/code> via &lt;code>peerConfigRef&lt;/code>. Esto evita repetir la misma configuración para cada peer cuando hay decenas de ellos.&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="nt">apiVersion&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">cilium.io/v2&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">kind&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">CiliumBGPPeerConfig&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">metadata&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">name&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">tor-shared-config&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">spec&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">timers&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">holdTimeSeconds&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">30&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">keepAliveTimeSeconds&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">10&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">connectRetryTimeSeconds&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">5&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">gracefulRestart&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">restartTimeSeconds&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">120&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">families&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">afi&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">ipv4&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">safi&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">unicast&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">advertisements&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">matchLabels&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">advertise&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">bgp &lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="c"># → liga a CiliumBGPAdvertisement&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">afi&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">ipv6&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">safi&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">unicast&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">advertisements&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">matchLabels&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">advertise&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">bgp&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">authentication&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">password&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">name&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">bgp-md5-secret &lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="c"># Secret con la password MD5&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">key&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">password&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Una sola &lt;code>CiliumBGPPeerConfig&lt;/code> puede ser referenciada por &lt;strong>muchos peers&lt;/strong> distintos. Cambias timers o families en un sitio.&lt;/p>
&lt;h3 id="3-ciliumbgpadvertisement">3. &lt;code>CiliumBGPAdvertisement&lt;/code>&lt;/h3>
&lt;p>Declara &lt;strong>qué prefijos se anuncian&lt;/strong>: los pod CIDRs del nodo, los ClusterIPs y ExternalIPs de Services, las IPs asignadas por &lt;code>CiliumLoadBalancerIPPool&lt;/code> para Services type=LoadBalancer. Se vinculan a &lt;code>CiliumBGPPeerConfig&lt;/code> via labels.&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="nt">apiVersion&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">cilium.io/v2&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">kind&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">CiliumBGPAdvertisement&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">metadata&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">name&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">services-and-pods&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">labels&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">advertise&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">bgp &lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="c"># ← la label que el PeerConfig matchea&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">spec&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">advertisements&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">advertisementType&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">PodCIDR &lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="c"># anuncia el pod CIDR del nodo&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">attributes&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">communities&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">standard&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="s2">&amp;#34;65000:100&amp;#34;&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">advertisementType&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">Service &lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="c"># anuncia ClusterIPs / LoadBalancer IPs&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">service&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">addresses&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">LoadBalancerIP&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">ClusterIP&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">ExternalIP&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">selector&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">matchLabels&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">bgp-advertise&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">&amp;#34;true&amp;#34;&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="c"># solo Services con esta label&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">attributes&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">communities&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">standard&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="s2">&amp;#34;65000:200&amp;#34;&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">localPreference&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">200&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>La granularidad es muy fina: puedes anunciar diferentes tipos de prefijos con diferentes communities BGP, diferentes local-preference, diferentes path attributes, y filtrar Services con label selectors. Esto era literalmente imposible con &lt;code>CiliumBGPPeeringPolicy&lt;/code> v1.&lt;/p>
&lt;h3 id="4-ciliumbgpnodeconfig-auto-generado">4. &lt;code>CiliumBGPNodeConfig&lt;/code> (auto-generado)&lt;/h3>
&lt;p>Este CRD no se configura a mano. El &lt;strong>operator de Cilium&lt;/strong> lo genera por cada nodo a partir de la &lt;code>CiliumBGPClusterConfig&lt;/code> que aplica a ese nodo. Es el estado materializado per-node que el agente de cada nodo lee para arrancar sus peerings. Si quieres ver qué configuración BGP está corriendo realmente en un nodo, &lt;code>kubectl get ciliumbgpnodeconfig &amp;lt;nodename&amp;gt; -o yaml&lt;/code> te lo enseña.&lt;/p>
&lt;h3 id="5-ciliumbgpnodeconfigoverride">5. &lt;code>CiliumBGPNodeConfigOverride&lt;/code>&lt;/h3>
&lt;p>Opcional. Permite &lt;strong>sobrescribir la configuración generada&lt;/strong> para un nodo concreto cuando necesitas algo no-estándar. Casos de uso:&lt;/p>
&lt;ul>
&lt;li>Anclar el router-id BGP a una IP específica (útil cuando el nodo tiene varias interfaces).&lt;/li>
&lt;li>Especificar la dirección local del peer cuando hay varias interfaces de salida.&lt;/li>
&lt;li>Cambiar timers solo para un nodo problemático.&lt;/li>
&lt;/ul>
&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="nt">apiVersion&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">cilium.io/v2&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">kind&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">CiliumBGPNodeConfigOverride&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">metadata&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">name&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">node-rack1-master01 &lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="c"># nombre debe coincidir con el del nodo&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">spec&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">bgpInstances&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">name&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">instance-65000&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">routerID&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">10.0.1.10&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="c"># override del router-id&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">peers&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">name&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">top-of-rack-1a&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">localAddress&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">10.0.1.10&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="c"># interface local concreta&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="diagrama-de-relaciones">Diagrama de relaciones&lt;/h3>
&lt;div class="diagram" style="max-width:720px;margin:1.5rem auto;">
&lt;svg viewBox="0 0 720 320" xmlns="http://www.w3.org/2000/svg" role="img" aria-label="Diagrama de relaciones entre CRDs de Cilium BGP v2">
&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}.c1{fill:#ffe9d6}.c2{fill:#d6eaff}.c3{fill:#d9f5d6}.c4{fill:#e9d6f5}.c5{fill:#eee;stroke-dasharray:4 2}.arr{stroke:#666;stroke-width:1.4;fill:none;marker-end:url(#h)}.dashed{stroke:#888;stroke-width:1.2;fill:none;stroke-dasharray:4 3;marker-end:url(#h)}&lt;/style>
&lt;defs>&lt;marker id="h" 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="22" text-anchor="middle" class="title">CRDs de Cilium BGP Control Plane v2 y sus relaciones&lt;/text>
&lt;rect x="40" y="50" width="220" height="60" rx="6" class="box c1"/>
&lt;text x="150" y="74" text-anchor="middle" class="lbl">CiliumBGPClusterConfig&lt;/text>
&lt;text x="150" y="94" text-anchor="middle" class="sm">nodeSelector + bgpInstances&lt;/text>
&lt;rect x="290" y="50" width="180" height="60" rx="6" class="box c2"/>
&lt;text x="380" y="74" text-anchor="middle" class="lbl">CiliumBGPPeerConfig&lt;/text>
&lt;text x="380" y="94" text-anchor="middle" class="sm">timers, families, auth&lt;/text>
&lt;rect x="500" y="50" width="180" height="60" rx="6" class="box c3"/>
&lt;text x="590" y="74" text-anchor="middle" class="lbl">CiliumBGPAdvertisement&lt;/text>
&lt;text x="590" y="94" text-anchor="middle" class="sm">pod CIDR, Service IPs&lt;/text>
&lt;rect x="40" y="180" width="220" height="60" rx="6" class="box c5"/>
&lt;text x="150" y="204" text-anchor="middle" class="lbl">CiliumBGPNodeConfig&lt;/text>
&lt;text x="150" y="224" text-anchor="middle" class="sm">auto-generado por operator&lt;/text>
&lt;rect x="290" y="180" width="220" height="60" rx="6" class="box c4"/>
&lt;text x="400" y="204" text-anchor="middle" class="lbl">CiliumBGPNodeConfigOverride&lt;/text>
&lt;text x="400" y="224" text-anchor="middle" class="sm">opcional, por nombre de nodo&lt;/text>
&lt;path class="arr" d="M260,80 L290,80"/>&lt;text x="275" y="74" text-anchor="middle" class="sm">peerConfigRef&lt;/text>
&lt;path class="dashed" d="M380,110 L380,150 L470,180"/>&lt;text x="425" y="155" text-anchor="middle" class="sm">vincula via labels&lt;/text>
&lt;path class="arr" d="M590,110 L590,150 L500,180"/>&lt;text x="545" y="155" text-anchor="middle" class="sm">advertisements&lt;/text>
&lt;path class="arr" d="M150,110 L150,180"/>&lt;text x="165" y="150" text-anchor="middle" class="sm">operator&lt;/text>
&lt;path class="dashed" d="M290,210 L260,210"/>&lt;text x="275" y="205" text-anchor="middle" class="sm">override&lt;/text>
&lt;text x="360" y="290" text-anchor="middle" class="sm">flechas sólidas: referencias YAML directas. Discontinuas: vínculos por label selector o coordinación lateral.&lt;/text>
&lt;/svg>
&lt;/div>
&lt;h3 id="ciliumloadbalancerippool-complementa-no-es-bgp">CiliumLoadBalancerIPPool: complementa, no es BGP&lt;/h3>
&lt;p>Aunque no es un CRD BGP estrictamente, conviene mencionarlo: &lt;strong>&lt;code>CiliumLoadBalancerIPPool&lt;/code>&lt;/strong> es el CRD que provee IPs a Services type=LoadBalancer. Define un rango (&lt;code>10.20.0.0/24&lt;/code>, por ejemplo) que Cilium asigna automáticamente a Services LoadBalancer. Combinado con &lt;code>CiliumBGPAdvertisement&lt;/code> que anuncia &lt;code>LoadBalancerIP&lt;/code>, da el ciclo completo: Service nuevo → IP asignada del pool → anuncio BGP a los routers → IP routable desde la red corporativa, sin balanceador externo.&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="nt">apiVersion&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">cilium.io/v2alpha1&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">kind&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">CiliumLoadBalancerIPPool&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">metadata&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">name&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">lb-pool-rack1&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">spec&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">blocks&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">start&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">&amp;#34;10.20.0.10&amp;#34;&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">stop&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">&amp;#34;10.20.0.250&amp;#34;&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">serviceSelector&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">matchLabels&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">lb-pool&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">rack1&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="manifest-completo-pod-cidrs--loadbalancer-services-anunciados-a-un-par-tor-redundante">Manifest completo: pod CIDRs + LoadBalancer Services anunciados a un par ToR redundante&lt;/h2>
&lt;p>Ejemplo realista de un cluster con dos top-of-rack switches como peers BGP, ambos en el mismo AS (64512), Cilium en AS 65000:&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"># 1. CiliumBGPPeerConfig — config compartida para los dos ToR&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="nn">---&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">apiVersion&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">cilium.io/v2&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">kind&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">CiliumBGPPeerConfig&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">metadata&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">name&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">tor-peers&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">spec&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">timers&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">holdTimeSeconds&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">30&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">keepAliveTimeSeconds&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">10&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">gracefulRestart&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">restartTimeSeconds&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">120&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">families&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">afi&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">ipv4&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">safi&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">unicast&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">advertisements&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">matchLabels&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">advertise&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">bgp&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>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="c"># 2. CiliumBGPAdvertisement — qué se anuncia&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="nn">---&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">apiVersion&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">cilium.io/v2&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">kind&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">CiliumBGPAdvertisement&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">metadata&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">name&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">pods-and-lb&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">labels&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">advertise&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">bgp&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">spec&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">advertisements&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">advertisementType&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">PodCIDR&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">advertisementType&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">Service&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">service&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">addresses&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="l">LoadBalancerIP]&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">selector&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">matchExpressions&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="w"> &lt;/span>&lt;span class="nt">key: io.kubernetes.service.namespace, operator: NotIn, values&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="l">kube-system] }&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>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="c"># 3. CiliumBGPClusterConfig — qué nodos hablan con qué peers&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="nn">---&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">apiVersion&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">cilium.io/v2&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">kind&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">CiliumBGPClusterConfig&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">metadata&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">name&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">cluster-bgp&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">spec&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">nodeSelector&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">matchLabels&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">bgp&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">enabled&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">bgpInstances&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">name&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">instance-65000&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">localASN&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">65000&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">peers&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">name&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">tor-a&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">peerASN&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">64512&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">peerAddress&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">10.0.1.1&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">peerConfigRef&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>{&lt;span class="w"> &lt;/span>&lt;span class="nt">name&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">tor-peers }&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">name&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">tor-b&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">peerASN&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">64512&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">peerAddress&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">10.0.1.2&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">peerConfigRef&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>{&lt;span class="w"> &lt;/span>&lt;span class="nt">name&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">tor-peers }&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>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="c"># 4. CiliumLoadBalancerIPPool — rango de LB IPs&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="nn">---&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">apiVersion&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">cilium.io/v2alpha1&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">kind&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">CiliumLoadBalancerIPPool&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">metadata&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">name&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">lb-corporate&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">spec&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">blocks&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">cidr&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">&amp;#34;10.20.0.0/24&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Cuatro objetos. Antes, en v1, era un único &lt;code>CiliumBGPPeeringPolicy&lt;/code> que mezclaba todo y resultaba difícil de mantener en clusters de más de 5 nodos con configuración heterogénea. La nueva separación es más larga pero claramente factorizable: un &lt;code>PeerConfig&lt;/code> por tipo de peer, una &lt;code>Advertisement&lt;/code> por política de anuncio, un &lt;code>ClusterConfig&lt;/code> que conecta nodos con peers.&lt;/p>
&lt;h2 id="trampas-operativas-comunes">Trampas operativas comunes&lt;/h2>
&lt;h3 id="modo-routingmode-tunnel-con-bgp">Modo &lt;code>routingMode: tunnel&lt;/code> con BGP&lt;/h3>
&lt;p>BGP solo tiene sentido con &lt;strong>direct routing&lt;/strong> (&lt;code>routingMode: native&lt;/code>). Si tienes el modo tunnel (VXLAN/Geneve) y configuras BGP, anunciarás pod CIDRs pero los paquetes seguirán saliendo encapsulados, generando un comportamiento confuso (a veces vía túnel, a veces directo según rutas). Configura &lt;code>routingMode: native&lt;/code> y desactiva túnel.&lt;/p>
&lt;h3 id="ebpf-host-routing-vs-kube-proxy-replacement">eBPF host routing vs &lt;code>kube-proxy replacement&lt;/code>&lt;/h3>
&lt;p>Son dos cosas distintas. &lt;code>kubeProxyReplacement: true&lt;/code> habilita el reemplazo de kube-proxy (los Services). &lt;code>bpf.hostRouting: true&lt;/code> habilita el bypass de iptables del host (las decisiones de routing del nodo se hacen con eBPF en lugar de FIB tradicional). El segundo necesita kernel 5.10+ con todas las features bpf habilitadas; si no tienes ese kernel, queda en modo legacy y el rendimiento es solo &amp;ldquo;casi tan bueno&amp;rdquo;.&lt;/p>
&lt;h3 id="bgp-timers-agresivos-sobre-nics-flapping">BGP timers agresivos sobre NICs flapping&lt;/h3>
&lt;p>Con &lt;code>holdTimeSeconds: 9 / keepAliveSeconds: 3&lt;/code>, una NIC que parpadee 5 segundos rompe la sesión BGP y todas las rutas anunciadas desaparecen del fabric. Los pods de ese nodo se vuelven inalcanzables hasta que la sesión se restablece. Para clusters en hardware con NICs sospechosas, usa los valores conservadores (&lt;code>holdTime: 30, keepAlive: 10&lt;/code>) y considera &lt;strong>graceful restart&lt;/strong> explícitamente (ya viene en el ejemplo de arriba).&lt;/p>
&lt;h3 id="anunciar-clusterip-a-la-red-corporativa">Anunciar ClusterIP a la red corporativa&lt;/h3>
&lt;p>Anunciar &lt;code>ClusterIP&lt;/code> a routers externos es &lt;strong>rara vez lo que quieres&lt;/strong>: son IPs de Service interno, no diseñadas para alcanzarse desde fuera del cluster. Para exposición externa, usa &lt;code>LoadBalancerIP&lt;/code> desde un &lt;code>CiliumLoadBalancerIPPool&lt;/code>. Anunciar &lt;code>ClusterIP&lt;/code> solo tiene sentido en topologías muy específicas (multi-cluster mesh con shared service discovery).&lt;/p>
&lt;h3 id="mezclar-v2alpha1-ciliumbgppeeringpolicy-y-v2-ciliumbgpclusterconfig">Mezclar v2alpha1 (&lt;code>CiliumBGPPeeringPolicy&lt;/code>) y v2 (&lt;code>CiliumBGPClusterConfig&lt;/code>)&lt;/h3>
&lt;p>No funciona bien. El operator emite warnings en los logs sobre el uso de la API deprecated, y los conflictos entre lo que define la peering policy vs la cluster config pueden producir estados raros. Migra de una a la otra en una sola pasada; no convivas.&lt;/p>
&lt;h3 id="md5-password-y-mtu">MD5 password y MTU&lt;/h3>
&lt;p>Si configuras MD5 password en &lt;code>CiliumBGPPeerConfig.authentication&lt;/code>, el header TCP es más grande. En links con MTU justa (1500 - 50 VXLAN del fabric upstream, por ejemplo), el handshake BGP puede fragmentar y morir silenciosamente. O usa MTU 9000 entre nodos y ToR, o asegura que los MSS están negociados correctamente.&lt;/p>
&lt;h2 id="lo-que-no-hemos-cubierto">Lo que no hemos cubierto&lt;/h2>
&lt;ul>
&lt;li>&lt;strong>Cilium Cluster Mesh&lt;/strong>: federación de varios clusters Cilium para que sus Services se vean entre sí. Encaja con BGP cuando se quiere routing nativo entre clusters; tiene CRDs propios.&lt;/li>
&lt;li>&lt;strong>L7 Policies y Envoy embebido&lt;/strong>: política HTTP/gRPC/Kafka. Otra capa de eBPF + proxy que merece artículo propio.&lt;/li>
&lt;li>&lt;strong>Hubble&lt;/strong>: observabilidad de tráfico basada en eBPF que Cilium expone. Dashboards de flow logs con cero impacto en latencia.&lt;/li>
&lt;li>&lt;strong>Wireguard transparente&lt;/strong>: encryption pod-a-pod sin sidecars, controlado por Cilium via eBPF redirect a un dataplane WireGuard del kernel.&lt;/li>
&lt;li>&lt;strong>Gateway API en Cilium&lt;/strong>: el sucesor de Ingress, con soporte de primera clase desde Cilium 1.16+.&lt;/li>
&lt;li>&lt;strong>eBPF para LLM serving&lt;/strong>: la conexión natural con la serie anterior de inferencia. Hay trabajos recientes que usan eBPF para fairness multi-tenant en GPUs y para tracking de tokens; territorio de papers, aún no production.&lt;/li>
&lt;/ul>
&lt;p>Es decir, queda material para otros tres artículos de la serie de hoy. Vamos en orden.&lt;/p>
&lt;h2 id="referencias">Referencias&lt;/h2>
&lt;p>Conceptuales y de proyecto:&lt;/p>
&lt;ul>
&lt;li>&lt;a href="https://ebpf.io/">eBPF.io&lt;/a> — documentación canónica del ecosistema eBPF.&lt;/li>
&lt;li>&lt;a href="https://github.com/iovisor/bcc">The BPF Compiler Collection (bcc)&lt;/a> y &lt;a href="https://github.com/bpftrace/bpftrace">bpftrace&lt;/a> — herramientas para empezar.&lt;/li>
&lt;li>&lt;a href="https://www.programming-helper.com/tech/ebpf-2026-extended-berkeley-packet-filter-observability-security">eBPF en 2026: How Extended Berkeley Packet Filter Became the Engine of Linux Observability and Networking&lt;/a> — estado del arte.&lt;/li>
&lt;/ul>
&lt;p>XDP, TC y firewalling:&lt;/p>
&lt;ul>
&lt;li>&lt;a href="https://docs.redhat.com/en/documentation/red_hat_enterprise_linux/10/html/configuring_firewalls_and_packet_filters/getting-started-with-xdp-and-ebpf">Getting started with XDP and eBPF (Red Hat docs)&lt;/a>.&lt;/li>
&lt;li>&lt;a href="https://medium.com/@majidbasharat21/full-guide-to-bpf-firewalls-xdp-tc-and-ebpf-integration-81951f19354b">Full Guide to BPF Firewalls: XDP, tc, and eBPF Integration (Medium, 2025)&lt;/a>.&lt;/li>
&lt;li>&lt;a href="https://blog.cloudflare.com/xdp-on-bpf-and-bonding/">Cloudflare blog: XDP for DDoS mitigation&lt;/a>.&lt;/li>
&lt;li>&lt;a href="https://github.com/facebookincubator/katran">Facebook Katran (GitHub)&lt;/a> — L4 LB con XDP, código y paper.&lt;/li>
&lt;/ul>
&lt;p>Cilium:&lt;/p>
&lt;ul>
&lt;li>&lt;a href="https://docs.cilium.io/">Cilium documentation&lt;/a> — siempre el primer puerto.&lt;/li>
&lt;li>&lt;a href="https://docs.cilium.io/en/stable/network/kubernetes/kubeproxy-free/">Kubernetes Without kube-proxy&lt;/a> — la guía oficial del replacement.&lt;/li>
&lt;li>&lt;a href="https://docs.cilium.io/en/stable/network/bgp-control-plane/bgp-control-plane-configuration/">Cilium BGP Control Plane Resources (docs)&lt;/a> — referencia de los CRDs v2.&lt;/li>
&lt;li>&lt;a href="https://oneuptime.com/blog/post/2026-03-13-cilium-bgp-control-plane-configuration/view">Configuring Cilium BGP Control Plane (OneUptime blog, mar 2026)&lt;/a> — walkthrough.&lt;/li>
&lt;li>&lt;a href="https://sigridjin.medium.com/a-guide-to-bgp-control-plane-and-cluster-mesh-in-cilium-networking-f20dbf64c5ed">A Guide to BGP Control Plane and Cluster Mesh in Cilium Networking (Sigrid Jin, Medium)&lt;/a> — artículo más profundo con casos de uso.&lt;/li>
&lt;/ul>
&lt;p>Cross-references:&lt;/p>
&lt;ul>
&lt;li>Artículo previo en este blog: &lt;a href="https://blog.lo0.es/posts/rke2-cilium-bgp/">Kubernetes con Cilium BGP: servicios accesibles sin Ingress&lt;/a> — el primer paso, con la versión v1 (que ya hay que migrar).&lt;/li>
&lt;li>Series sobre 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 Kubernetes&lt;/a>, &lt;a href="https://blog.lo0.es/posts/pagedattention-deep-dive/">PagedAttention deep dive&lt;/a>, &lt;a href="https://blog.lo0.es/posts/operators-llm-kubernetes/">Operators LLM K8s&lt;/a> — donde la red rápida (que veremos en los siguientes posts de esta serie) determina el rendimiento real.&lt;/li>
&lt;/ul></description></item></channel></rss>