Implemente rápidamente el entorno Cilium BGP con Containerlab + Kind

1 Pre-conocimiento

1.1 Introducción a Cilio

Cilium es un complemento CNI de Kubernetes basado en la tecnología eBPF. Cilium posiciona el producto como "Redes, observabilidad y seguridad basadas en eBPF" en su sitio web oficial , y se compromete a proporcionar redes, observabilidad y seguridad basadas en eBPF para cargas de trabajo de contenedores una variedad de soluciones Al insertar dinámicamente alguna lógica de control dentro de Linux utilizando la tecnología eBPF, Cilium se puede aplicar y actualizar sin modificar el código de la aplicación o la configuración del contenedor, lo que permite funciones relacionadas con la red, la observabilidad y la seguridad.

1.2 Introducción a Cilium BGP

BGP (Border Gateway Protocol, Border Gateway Protocol) es un protocolo de enrutamiento dinámico utilizado entre AS (Sistema autónomo, sistema autónomo). El protocolo BGP proporciona estrategias de control de enrutamiento ricas y flexibles, y se utilizó principalmente para la interconexión entre AS de Internet en los primeros días. Con el desarrollo de la tecnología, el protocolo BGP también se ha utilizado ampliamente en los centros de datos.Las redes modernas de centros de datos generalmente se basan en la arquitectura de hoja espinal, en la que BGP se puede usar para propagar la información de accesibilidad de los puntos finales.

La capa de hoja consta de conmutadores de acceso que agregan el tráfico de los servidores y se conectan directamente a la columna vertebral o al núcleo de la red. Los conmutadores de columna están interconectados con todos los conmutadores de hoja en una topología de malla completa.

Con la creciente aplicación de Kubernetes en las empresas, estos puntos finales pueden ser Kubernetes Pods. Para permitir que la red fuera del clúster de Kubernetes obtenga dinámicamente las rutas de los Pods accedidos a través del protocolo BGP, es obvio que Cilium debe introducir soporte para el Protocolo BGP. .

En Cilium, BGP se introdujo por primera vez en la versión 1.10 Al asignar un servicio de tipo LoadBalancer a las aplicaciones y combinarlo con MetalLB, la información de enrutamiento se anuncia a los vecinos de BGP.

Sin embargo, a medida que el uso de IPv6 continúa creciendo, está claro que Cilium necesita capacidades de BGP IPv6, incluido Segment Routing v6 (SRv6). MetalLB actualmente tiene soporte limitado para IPv6 a través de FRR y aún es experimental. El equipo de Cilium evaluó varias opciones y decidió pasar a GoBGP [1] , que tiene más funciones .

En la última versión de Cilium 1.12, habilitar la compatibilidad con BGP solo requiere configurar --enable-bgp-control-plane=trueparámetros , y un nuevo CRD CiliumBGPPeeringPolicypermite una configuración más detallada y extensible.

  • La misma configuración de BGP se puede aplicar a varios nodos utilizando la selección de nodeSelectorparámetros por etiqueta.
  • Cuando el exportPodCIDRparámetro se establece en verdadero, todos los CIDR de pod se pueden anunciar dinámicamente sin especificar manualmente qué prefijos de ruta deben anunciarse.
  • neighborsLos parámetros se utilizan para configurar la información del vecino BGP, generalmente dispositivos de red fuera del clúster.
apiVersion: "cilium.io/v2alpha1"
kind: CiliumBGPPeeringPolicy
metadata:
 name: rack0
spec:
 nodeSelector:
   matchLabels:
     rack: rack0
 virtualRouters:
 - localASN: 65010
   exportPodCIDR: true
   neighbors:
   - peerAddress: "10.0.0.1/32"
     peerASN: 65010

1.3 Introducción al tipo

Kind [2] (Kubernetes en Docker) es una herramienta que utiliza contenedores Docker como nodos Node para ejecutar clústeres locales de Kubernetes. Solo necesitamos instalar Docker y podemos crear rápidamente uno o más clústeres de Kubernetes en minutos. Para facilitar el experimento, este artículo utiliza Kind para crear un entorno de clúster de Kubernetes.

1.4 Introducción a Containerlab

Containerlab [3] proporciona una solución simple, liviana y basada en contenedores para orquestar experimentos de red, compatible con varios sistemas operativos de red en contenedores, como Cisco, Juniper, Nokia, Arista, etc. Containerlab puede lanzar contenedores y crear conexiones virtuales entre ellos para construir topologías de red definidas por el usuario basadas en perfiles definidos por el usuario.

name: sonic01

topology:
  nodes:
    srl:
      kind: srl
      image: ghcr.io/nokia/srlinux
    sonic:
      kind: sonic-vs
      image: docker-sonic-vs:2020-11-12

  links:
    - endpoints: ["srl:e1-1", "sonic:eth1"]

La interfaz de administración del contenedor está conectada a la red Docker de tipo puente llamada clab, y la interfaz comercial está conectada a través de las reglas de enlaces definidas en el archivo de configuración. Esto es como los modos de gestión fuera de banda y dentro de banda correspondientes a la gestión de red en el centro de datos.

Containerlab también nos proporciona una gran cantidad de casos experimentales, que se pueden encontrar en Ejemplos de laboratorio [4] . Incluso podemos crear una arquitectura de red a nivel de centro de datos a través de Containerlab (consulte la estructura Clos de 5 etapas [5] )

2 requisitos previos

Seleccione el método de instalación adecuado según la versión del sistema operativo correspondiente:

Los archivos de configuración utilizados en este artículo se pueden obtener en https://github.com/cr7258/kubernetes-guide/tree/master/containerlab/cilium-bgp .

3 Inicie un clúster de Kubernetes con Kind

Prepare un archivo de configuración Kind y cree un clúster de Kubernetes de 4 nodos.

# cluster.yaml
kind: Cluster
name: clab-bgp-cplane-demo
apiVersion: kind.x-k8s.io/v1alpha4
networking:
  disableDefaultCNI: true # 禁用默认 CNI
  podSubnet: "10.1.0.0/16" # Pod CIDR
nodes:
- role: control-plane # 节点角色
  kubeadmConfigPatches:
  - |
    kind: InitConfiguration
    nodeRegistration:
      kubeletExtraArgs:
        node-ip: 10.0.1.2 # 节点 IP
        node-labels: "rack=rack0" # 节点标签

- role: worker
  kubeadmConfigPatches:
  - |
    kind: JoinConfiguration
    nodeRegistration:
      kubeletExtraArgs:
        node-ip: 10.0.2.2
        node-labels: "rack=rack0"

- role: worker
  kubeadmConfigPatches:
  - |
    kind: JoinConfiguration
    nodeRegistration:
      kubeletExtraArgs:
        node-ip: 10.0.3.2
        node-labels: "rack=rack1"

- role: worker
  kubeadmConfigPatches:
  - |
    kind: JoinConfiguration
    nodeRegistration:
      kubeletExtraArgs:
        node-ip: 10.0.4.2
        node-labels: "rack=rack1"

Ejecute el siguiente comando para crear un clúster de Kubernetes a través de Kind.

kind create cluster --config cluster.yaml

Compruebe el estado del nodo del clúster. Dado que no hemos instalado el complemento CNI, el estado del nodo es NotReady.

kubectl get node

4 Iniciar Containerlab

Defina el archivo de configuración para Containerlab, cree la infraestructura de red y conéctese al clúster de Kubernetes creado por Kind:

  • router0, tor0, tor1 son dispositivos de red fuera del clúster de Kubernetes y establecen la información de la interfaz de red y la configuración de BGP en el parámetro exec. router0 establece vecinos BGP con tor0, tor1, tor0 establece vecinos BGP con server0, server1, router0 y tor1 establece vecinos BGP con server2, server3, router0.
  • La configuración de Containerlab network-mode: container:<容器名>puede compartir el espacio de nombres de red de los contenedores iniciados fuera de Containerlab y configurar los contenedores server0, server1, server2, server3 para conectarse a los 4 nodos del clúster de Kubernetes creado por Kind en la Sección 3, respectivamente.
# topo.yaml
name: bgp-cplane-demo
topology:
  kinds:
    linux:
      cmd: bash
  nodes:
    router0:
      kind: linux
      image: frrouting/frr:v8.2.2
      labels:
        app: frr
      exec:
      - iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
      - ip addr add 10.0.0.0/32 dev lo
      - ip route add blackhole 10.0.0.0/8
      - touch /etc/frr/vtysh.conf
      - sed -i -e 's/bgpd=no/bgpd=yes/g' /etc/frr/daemons
      - usr/lib/frr/frrinit.sh start
      - >-
         vtysh -c 'conf t'
         -c 'router bgp 65000'
         -c ' bgp router-id 10.0.0.0'
         -c ' no bgp ebgp-requires-policy'
         -c ' neighbor ROUTERS peer-group'
         -c ' neighbor ROUTERS remote-as external'
         -c ' neighbor ROUTERS default-originate'
         -c ' neighbor net0 interface peer-group ROUTERS'
         -c ' neighbor net1 interface peer-group ROUTERS'
         -c ' address-family ipv4 unicast'
         -c '   redistribute connected'
         -c ' exit-address-family'
         -c '!'
            
          
    tor0:
      kind: linux
      image: frrouting/frr:v8.2.2  
      labels:
        app: frr
      exec:
      - ip link del eth0
      - ip addr add 10.0.0.1/32 dev lo
      - ip addr add 10.0.1.1/24 dev net1
      - ip addr add 10.0.2.1/24 dev net2
      - touch /etc/frr/vtysh.conf
      - sed -i -e 's/bgpd=no/bgpd=yes/g' /etc/frr/daemons
      - /usr/lib/frr/frrinit.sh start
      - >-
         vtysh -c 'conf t'
         -c 'frr defaults datacenter'
         -c 'router bgp 65010'
         -c ' bgp router-id 10.0.0.1'
         -c ' no bgp ebgp-requires-policy'
         -c ' neighbor ROUTERS peer-group'
         -c ' neighbor ROUTERS remote-as external'
         -c ' neighbor SERVERS peer-group'
         -c ' neighbor SERVERS remote-as internal'
         -c ' neighbor net0 interface peer-group ROUTERS'
         -c ' neighbor 10.0.1.2 peer-group SERVERS'
         -c ' neighbor 10.0.2.2 peer-group SERVERS'
         -c ' address-family ipv4 unicast'
         -c '   redistribute connected'
         -c '  exit-address-family'
         -c '!'
          
    

    tor1:
      kind: linux
      image: frrouting/frr:v8.2.2
      labels:
        app: frr
      exec:
      - ip link del eth0
      - ip addr add 10.0.0.2/32 dev lo
      - ip addr add 10.0.3.1/24 dev net1
      - ip addr add 10.0.4.1/24 dev net2
      - touch /etc/frr/vtysh.conf
      - sed -i -e 's/bgpd=no/bgpd=yes/g' /etc/frr/daemons
      - /usr/lib/frr/frrinit.sh start
      - >-
         vtysh -c 'conf t'
         -c 'frr defaults datacenter'
         -c 'router bgp 65011'
         -c ' bgp router-id 10.0.0.2'
         -c ' no bgp ebgp-requires-policy'
         -c ' neighbor ROUTERS peer-group'
         -c ' neighbor ROUTERS remote-as external'
         -c ' neighbor SERVERS peer-group'
         -c ' neighbor SERVERS remote-as internal'
         -c ' neighbor net0 interface peer-group ROUTERS'
         -c ' neighbor 10.0.3.2 peer-group SERVERS'
         -c ' neighbor 10.0.4.2 peer-group SERVERS'
         -c ' address-family ipv4 unicast'
         -c '   redistribute connected'
         -c '  exit-address-family'
         -c '!'      
    
    server0:
      kind: linux
      image: nicolaka/netshoot:latest
      network-mode: container:control-plane
      exec:
      - ip addr add 10.0.1.2/24 dev net0
      - ip route replace default via 10.0.1.1

    server1:
      kind: linux
      image: nicolaka/netshoot:latest
      network-mode: container:worker
      exec:
      - ip addr add 10.0.2.2/24 dev net0
      - ip route replace default via 10.0.2.1

    server2:
      kind: linux
      image: nicolaka/netshoot:latest
      network-mode: container:worker2
      exec:
      - ip addr add 10.0.3.2/24 dev net0
      - ip route replace default via 10.0.3.1

    server3:
      kind: linux
      image: nicolaka/netshoot:latest
      network-mode: container:worker3
      exec:
      - ip addr add 10.0.4.2/24 dev net0
      - ip route replace default via 10.0.4.1


  links:
  - endpoints: ["router0:net0", "tor0:net0"]
  - endpoints: ["router0:net1", "tor1:net0"]
  - endpoints: ["tor0:net1", "server0:net0"]
  - endpoints: ["tor0:net2", "server1:net0"]
  - endpoints: ["tor1:net1", "server2:net0"]
  - endpoints: ["tor1:net2", "server3:net0"]

Ejecute el siguiente comando para crear el entorno experimental de Containerlab.

clab deploy -t topo.yaml

La topología creada se muestra a continuación. Actualmente, solo se establecen conexiones BGP entre los dispositivos tor0, tor1 y router0. Como no hemos establecido la configuración BGP del clúster de Kubernetes a través de CiliumBGPPeeringPolicy, las conexiones BGP entre tor0, tor1 y el Nodo Kubernetes no se han establecido. sido establecido.

Ejecute los siguientes comandos respectivamente para verificar el estado actual de establecimiento de vecinos BGP de tor0, tor1, router0 tres dispositivos de red.

docker exec -it clab-bgp-cplane-demo-tor0 vtysh -c "show bgp ipv4 summary wide"
docker exec -it clab-bgp-cplane-demo-tor1 vtysh -c "show bgp ipv4 summary wide"
docker exec -it clab-bgp-cplane-demo-router0 vtysh -c "show bgp ipv4 summary wide"

Ejecute el siguiente comando para ver las entradas de ruta BGP aprendidas por router0.

docker exec -it clab-bgp-cplane-demo-router0 vtysh -c "show bgp ipv4 wide"

Actualmente hay un total de 8 entradas de enrutamiento y el enrutamiento relacionado con el Pod aún no se ha aprendido.

Con el fin de facilitar a los usuarios una comprensión más intuitiva de la estructura de red del experimento, Containerlab proporciona graphcomandos para generar la topología de red.

clab graph -t topo.yaml 

Ingrese http://<IP de host>:50080 en el navegador para ver el mapa de topología generado por Containerlab.

5 Instalar Cilio

En este ejemplo, Helm se usa para instalar Cilium, y los parámetros de configuración de Cilium que debemos ajustar se establecen en el archivo de configuración values.yaml.

# values.yaml
tunnel: disabled

ipam:
  mode: kubernetes

ipv4NativeRoutingCIDR: 10.0.0.0/8

# 开启 BGP 功能支持,等同于命令行执行 --enable-bgp-control-plane=true
bgpControlPlane:  
  enabled: true

k8s:
  requireIPv4PodCIDR: true

Ejecute los siguientes comandos para instalar Cilium 1.12 y habilitar la compatibilidad con BGP.

helm repo add cilium https://helm.cilium.io/
helm install -n kube-system cilium cilium/cilium --version v1.12.1 -f values.yaml

Después de esperar a que se inicien todos los Cilium Pods, vuelva a comprobar el estado del nodo de Kubernetes y podrá ver que todos los nodos ya están en estado Listo.

6 nodos Cilium configuran BGP

A continuación, configure CiliumBGPPeeringPolicy para los nodos de Kubernetes en rack0 y rack1 respectivamente. Rack0 y rack1 corresponden a las etiquetas de Nodo respectivamente, que se establecen en el archivo de configuración de Tipo en la Sección 3.

El Nodo de rack0 establece una relación de vecino BGP con tor0, y el Nodo de rack1 establece una relación de vecino BGP con tor1, y automáticamente anuncia el CIDR del Pod al vecino BGP.

# cilium-bgp-peering-policies.yaml 
apiVersion: "cilium.io/v2alpha1"
kind: CiliumBGPPeeringPolicy
metadata:
  name: rack0
spec:
  nodeSelector:
    matchLabels:
      rack: rack0
  virtualRouters:
  - localASN: 65010
    exportPodCIDR: true # 自动宣告 Pod CIDR
    neighbors:
    - peerAddress: "10.0.0.1/32" # tor0 的 IP 地址
      peerASN: 65010
---
apiVersion: "cilium.io/v2alpha1"
kind: CiliumBGPPeeringPolicy
metadata:
  name: rack1
spec:
  nodeSelector:
    matchLabels:
      rack: rack1
  virtualRouters:
  - localASN: 65011
    exportPodCIDR: true
    neighbors:
    - peerAddress: "10.0.0.2/32" # tor1 的 IP 地址
      peerASN: 65011

Ejecute el siguiente comando para aplicar CiliumBGPPeeringPolicy.

kubectl apply -f cilium-bgp-peering-policies.yaml 

La topología creada se muestra a continuación. Ahora tor0 y tor1 han establecido vecinos BGP con Kubernetes Node.

Ejecute los siguientes comandos respectivamente para verificar el estado actual de establecimiento de vecinos BGP de tor0, tor1, router0 tres dispositivos de red.

docker exec -it clab-bgp-cplane-demo-tor0 vtysh -c "show bgp ipv4 summary wide"
docker exec -it clab-bgp-cplane-demo-tor1 vtysh -c "show bgp ipv4 summary wide"
docker exec -it clab-bgp-cplane-demo-router0 vtysh -c "show bgp ipv4 summary wide"

Ejecute el siguiente comando para ver las entradas de ruta BGP aprendidas por router0.

docker exec -it clab-bgp-cplane-demo-router0 vtysh -c "show bgp ipv4 wide"

Actualmente hay un total de 12 entradas de ruta y las 4 rutas adicionales son las rutas del segmento de red 10.1.x.0/24 aprendidas de los 4 nodos de Kubernetes.

7 Prueba de validación

Cree un Pod en los nodos donde se encuentran rack0 y rack1 para probar la conectividad de la red.

# nettool.yaml
apiVersion: v1
kind: Pod
metadata:
  labels:
    run: nettool-1
  name: nettool-1
spec:
  containers:
  - image: cr7258/nettool:v1
    name: nettool-1
  nodeSelector:
    rack: rack0 
---
apiVersion: v1
kind: Pod
metadata:
  labels:
    run: nettool-2
  name: nettool-2
spec:
  containers:
  - image: cr7258/nettool:v1
    name: nettool-2
  nodeSelector:
    rack: rack1

Ejecute los siguientes comandos para crear 2 Pods de prueba.

kubectl apply -f nettool.yaml

Ver la dirección IP del Pod.

kubectl get pod -o wide

El pod nettool-1 está ubicado en clab-bgp-cplane-demo-worker (servidor1, rack0), la dirección IP es 10.1.2.185; el pod nettool-2 está ubicado en clab-bgp-cplane-demo-worker3 (servidor3 , rack1), la dirección IP es La dirección es 10.1.3.56.

Ejecute el siguiente comando para intentar hacer ping al pod nettool-2 desde el pod nettool-1.

kubectl exec -it nettool-1 -- ping 10.1.3.56 

Puede ver que el nettool-1 Pod puede acceder al nettool-2 Pod normalmente.

Luego, use el comando traceroute para observar la dirección de los paquetes de red.

kubectl exec -it nettool-1 -- traceroute -n 10.1.3.56

El paquete se envía desde nettool-1 Pod y pasa por:

  • 1. La interfaz cilium_host del servidor 1 : la ruta predeterminada del Pod en la red de Cilium apunta al cilium_host local. cilium_host y cilium_net son un dispositivo de par veth. Cilium utiliza tablas ARP codificadas para obligar a que el próximo salto del tráfico del Pod sea secuestrado hacia el lado del host del par veth.

  • 2. La interfaz net2 de tor0 .
  • 3. La interfaz lo0 del router0: los tres dispositivos de red tor0, tor1 y router0 establecen una relación de vecino BGP a través de la interfaz de bucle invertido local lo0. Esto puede mejorar la solidez del vecino BGP en el caso de múltiples copias de seguridad de enlaces físicos. La relación de vecino se ve afectado cuando falla una interfaz física.
  • 4. La interfaz lo0 de tor1 .
  • 5. La interfaz net0 de server3 .

8 Limpiar el medio ambiente

Ejecute los siguientes comandos para limpiar el entorno experimental creado por Containerlab y Kind.

clab destroy -t topo.yaml
kind delete clusters clab-bgp-cplane-demo

9 Referencias

{{o.nombre}}
{{m.nombre}}

Supongo que te gusta

Origin my.oschina.net/u/4923278/blog/5570602
Recomendado
Clasificación