Anuncia las IP de los Services con BGP
¿Sin balanceador de carga en la nube? Cilium puede anunciar las IP de los Services directamente a tu red física mediante BGP.
El tipo de Service LoadBalancer de un proveedor de nube funciona porque la nube tiene una API para aprovisionar un balanceador de carga externo bajo demanda. En bare metal, o en cualquier entorno sin esa API, un Service LoadBalancer se queda en Pending para siempre a menos que otra cosa cumpla ese papel. El plano de control BGP de Cilium es una forma de hacerlo: enruta la IP de un Service directamente hacia tu red física hablando BGP desde los nodos del clúster hacia los routers upstream. Esta guía cubre los cuatro recursos que lo configuran y cómo verificar que una sesión BGP está realmente establecida desde ambos lados.
Cuándo BGP es la herramienta adecuada
Establecer peering BGP desde los nodos del clúster con los routers upstream es una integración de red real: requiere coordinación con quien gestiona la red física (o virtual), configuración en los routers de su lado que coincida con la configuración de peers en el lado de Kubernetes, y una familiaridad operativa genuina con conceptos de BGP como los sistemas autónomos y el anuncio de rutas. Es la herramienta adecuada para un clúster on-premises o bare metal que necesita que las IP de los Services sean realmente enrutables desde el resto de la red, igual que lo haría un LoadBalancer de la nube. Para necesidades más simples, la función de anuncios L2 de Cilium (anunciar la IP de un Service mediante ARP/NDP en el segmento de red local, sin protocolo de enrutamiento) es una alternativa más ligera que vale la pena considerar primero si tu clúster vive en un único segmento de red y no necesita enrutamiento de capa 3 entre segmentos o centros de datos.
Los cuatro recursos
Cuatro recursos personalizados CiliumBGP* trabajan juntos:
CiliumLoadBalancerIPPooldefine un rango de direcciones IP que Cilium puede asignar a los ServicesLoadBalancer.CiliumBGPAdvertisementdefine qué se anuncia por BGP, en este caso, las IP de Services tomadas de ese pool.CiliumBGPPeerConfigdefine cómo hablar BGP: temporizadores, comportamiento de graceful restart, familias de direcciones.CiliumBGPClusterConfiglo une todo: qué nodos participan (mediante un selector de etiquetas), su número de AS local y a qué peers upstream (por IP y número de AS) se conectan.
Define el pool de IP
apiVersion: cilium.io/v2alpha1
kind: CiliumLoadBalancerIPPool
metadata:
name: apps-pool
spec:
allowFirstLastIPs: "No"
blocks:
- cidr: "10.10.211.0/24"
allowFirstLastIPs: "No" excluye las direcciones de red y de broadcast (.0 y .255) del rango asignable, una convención habitual heredada de la asignación tradicional de subredes. Ajusta el CIDR al rango que tu equipo de redes te haya asignado realmente para este fin; debe ser espacio de direcciones real y enrutable desde su perspectiva, no un rango privado arbitrario que elegiste sin coordinar.
Define qué se anuncia
apiVersion: cilium.io/v2alpha1
kind: CiliumBGPAdvertisement
metadata:
name: bgp-advertisements
labels:
advertise: bgp
spec:
advertisements:
- advertisementType: Service
service:
addresses:
- LoadBalancerIP
selector:
matchExpressions:
- key: io.kubernetes.service.namespace
operator: Exists
Esto anuncia la LoadBalancerIP de los Services que coincidan. El campo labels de aquí (advertise: bgp) es lo que la configuración de peers de abajo referencia para vincular ambos recursos, no una etiqueta en los Services mismos.
Define el comportamiento de los peers
apiVersion: cilium.io/v2alpha1
kind: CiliumBGPPeerConfig
metadata:
name: bgp-peer-config
spec:
timers:
holdTimeSeconds: 9
keepAliveTimeSeconds: 3
gracefulRestart:
enabled: true
restartTimeSeconds: 15
families:
- afi: ipv4
safi: unicast
advertisements:
matchLabels:
advertise: bgp
El families.advertisements.matchLabels de aquí es lo que conecta esta configuración de peers con el recurso de anuncio definido arriba, al coincidir con su etiqueta.
Únelo todo: configuración del clúster y selección de nodos
apiVersion: cilium.io/v2alpha1
kind: CiliumBGPClusterConfig
metadata:
name: bgp-cluster-config
spec:
nodeSelector:
matchLabels:
role: bgp-node
bgpInstances:
- name: instance-1
localASN: 65011
peers:
- name: leaf-switch-1a
peerASN: 65002
peerAddress: "10.10.210.2"
peerConfigRef:
name: bgp-peer-config
- name: leaf-switch-1b
peerASN: 65002
peerAddress: "10.10.210.3"
peerConfigRef:
name: bgp-peer-config
nodeSelector es lo que limita el peering BGP a un subconjunto deliberado de nodos, los etiquetados como role: bgp-node, en lugar de que todos los nodos del clúster intenten hacer peering con los routers upstream:
kubectl label node worker-4 worker-5 worker-6 role=bgp-node
Un rango razonable es de dos a ocho nodos con peering, suficiente para evitar un punto único de fallo sin obligar a tu equipo de redes a configurar y mantener sesiones BGP contra cada nodo de un clúster que podría tener decenas o cientos. Cuántos tienen sentido depende de la disposición física de tu clúster: si se reparte en varios racks o filas, en general conviene hacer peering desde nodos de cada uno, en lugar de concentrar todas las sesiones BGP en un solo lugar.
Aplica los cuatro recursos y luego comprueba desde el lado de Kubernetes:
kubectl apply -f bgp-pool.yaml -f bgp-advertisement.yaml -f bgp-peer-config.yaml -f bgp-cluster-config.yaml
Verifica que la sesión realmente se estableció
Desde la perspectiva de un nodo, usando la CLI de depuración de Cilium dentro del Pod de Cilium que se ejecuta en un nodo con la etiqueta BGP:
kubectl -n kube-system exec <cilium-pod-on-bgp-node> -- cilium-dbg bgp peers
Busca un estado de sesión established. Cualquier otro (idle, connect, active) significa que la sesión realmente no se ha levantado, y las causas más comunes son una discrepancia de número de AS entre los dos lados, una dirección de peer inalcanzable, o que el router upstream simplemente aún no esté configurado para esperar a este peer; confirma que la configuración del peer en el lado de la red coincide exactamente con lo que has declarado aquí antes de asumir que la configuración del lado de Kubernetes es la incorrecta.
Confirma que una dirección realmente se está anunciando
Crea un Service LoadBalancer que tome su dirección del pool:
kubectl get svc -o wide
Su EXTERNAL-IP debería ser una dirección del CIDR del pool. Desde el router upstream (o desde lo que haya más allá, un firewall, un router core), comprueba que esa dirección aparece como una ruta /32 aprendida por BGP, anunciada desde las direcciones de los nodos con peering. Ver aparecer esa /32 concreta y llegar con éxito al Service a través de ella es la verdadera confirmación de extremo a extremo de que la asignación del pool de IP, el anuncio BGP y el enrutamiento propio de la red física están correctamente conectados entre sí, y no solo que los recursos del lado de Kubernetes se aplicaron sin errores.
Guías populares
-
Cómo usa Cilium eBPF: identidad, políticas y sockets Qué ocurre realmente en el kernel cuando un Pod arranca, habla con otro Pod o recibe una decisión de política sobre un paquete, y por qué es rápido. -
Prepara un clúster para Cilium: desactiva primero la CNI predeterminada Cilium reemplaza por completo el networking de tu clúster, lo que significa que el orden de las operaciones importa más que con la mayoría de los complementos. -
Expón Services con el soporte de Gateway API de Cilium GatewayClass, Gateway y HTTPRoute: enrutamiento por host, coincidencia de rutas, reescrituras de URL y TLS, sin Pods de gateway separados. -
Escribe network policies: de reglas L3/L4 a L7 Kubernetes parte de que todo Pod puede alcanzar a cualquier otro Pod; CiliumNetworkPolicy es la forma de acotarlo, hasta el método HTTP si lo necesitas.