Balanceo de carga agrupado con MetalLB

En este documento se muestra cómo configurar Google Distributed Cloud para usar el balanceo de carga agrupado con el balanceador de carga MetalLB. Este documento está dirigido a especialistas en redes que diseñan y desarrollan la red de su organización, así como a quienes instalan, configuran y ofrecen asistencia para los equipos de red. Para obtener más información sobre los roles habituales y las tareas de ejemplo a las que hacemos referencia en el contenido, consulta Roles y tareas de usuario habituales de GKE. Google Cloud

En Google Distributed Cloud, MetalLB se ejecuta en modo de capa 2.

Ejemplo de configuración de MetalLB

A continuación, se muestra un ejemplo de configuración de clústeres que ejecutan el balanceador de carga MetalLB:

Configuración del balanceador de carga de MetalLB.
Configuración del balanceador de carga de MetalLB

En el diagrama anterior se muestra una implementación de MetalLB. MetalLB se ejecuta directamente en los nodos del clúster. En este ejemplo, el clúster de administrador y el clúster de usuario están en dos VLANs independientes y cada clúster se encuentra en una subred independiente:

Clúster Subred
Clúster de administradores 172.16.20.0/24
Clúster de usuarios 172.16.40.0/24

admin-cluster.yaml

En la siguiente parte de un archivo de configuración de clúster de administrador se muestra la configuración que se ve en el diagrama anterior:

  • Plano de control de alta disponibilidad

  • Balanceador de carga MetalLB

  • VIP en MetalLB para el servidor de la API de Kubernetes del clúster de administrador

network:
  ...
  controlPlaneIPBlock:
    netmask: "255.255.255.0"
    gateway: "172.16.20.1"
    ips:
    - ip: "172.16.20.50"
      hostname: "admin-cp-1"
    - ip: "172.16.20.51"
      hostname: "admin-cp-2"
    - ip: "172.16.20.52"
      hostname: "admin-cp-3"
loadBalancer:
  kind: "MetalLB"
  ...
  vips:
    controlPlaneVIP: "172.16.20.100"
...
adminMaster:
  cpus: 4
  memoryMB: 16384
  replicas: 3

user-cluster.yaml

En la siguiente parte de un archivo de configuración de clúster de usuarios se muestra la configuración de lo siguiente:

  • Grupo de direcciones para que el controlador de MetalLB elija y asigne a los servicios de tipo LoadBalancer. El VIP de entrada está en este grupo.

  • VIP asignada al servidor de la API de Kubernetes del clúster de usuario y VIP de entrada que has elegido para configurar el proxy de entrada.

  • Un grupo de nodos habilitado para usar MetalLB. MetalLB se desplegará en los nodos de este grupo de nodos.

enableControlplaneV2: true
...
network:
  hostConfig:
  ...

  ipMode:
    type: "static"
    ipBlockFilePath: "config-folder/user-cluster-ipblock.yaml"
...
  controlPlaneIPBlock:
    netmask: "255.255.255.0"
    gateway: "172.16.40.1"
    ips:
    - ip: "172.16.40.21"
      hostname: "user-cp"
loadBalancer:
  kind: MetalLB
  metalLB:
    addressPools:
    - name: "address-pool-1"
      addresses:
      - "172.16.40.101-172.16.40.112
      avoidBuggyIPs: true
  ...

  vips:
    controlPlaneVIP: "172.16.20.100"
    ingressVIP: "172.16.40.101"
...
nodePools:
- name: "node-pool-1"
  cpus: 4
  memoryMB: 8192
  replicas: 3
  enableLoadBalancer: true

La configuración del ejemplo anterior especifica un conjunto de direcciones disponibles para los servicios. Cuando un desarrollador de aplicaciones crea un servicio de tipo LoadBalancer en el clúster de usuario, el controlador de MetalLB elegirá una dirección IP de este pool.

user-cluster-ipblock.yaml

En el siguiente ejemplo de un archivo de bloqueo de IP se muestra la designación de direcciones IP para los nodos de trabajo del clúster de usuario. Esto incluye una dirección IP adicional que se puede usar durante las actualizaciones, las actualizaciones de versiones y las reparaciones automáticas de los clústeres.

blocks:
- netmask: "255.255.255.0"
  gateway: "17.16.40.1"
  ips:
  - ip: 172.16.40.22
    hostname: user-vm-1
  - ip: 172.16.40.23
    hostname: user-vm-2
  - ip: 172.16.40.24
    hostname: user-vm-3
  - ip: 172.16.40.25
    hostname: user-vm-4
  - ip: 172.16.40.26
    hostname: user-vm-5
  - ip: 172.16.40.27
    hostname: user-vm-6

Configurar MetalLB

Abrir puertos de cortafuegos

MetalLB usa la biblioteca de listas de miembros de Go para elegir el líder. La biblioteca memberlist usa el puerto TCP 7946 y el puerto UDP 7946 para intercambiar información. Asegúrate de que se pueda acceder a esos puertos para el tráfico entrante y saliente en todos los nodos del balanceador de carga.

Habilitar MetalLB en un clúster de administrador nuevo

En el archivo de configuración del clúster de administrador, asigna el valor loadBalancer.kind a "MetalLB".

loadBalancer:
  kind: "MetalLB"

Rellena el resto del archivo de configuración del clúster de administrador y crea el clúster de administrador tal como se describe en Crear un clúster de administrador.

Especificar grupos de direcciones

El controlador de MetalLB asigna direcciones IP a los servicios. Cuando un desarrollador de aplicaciones crea un servicio de tipo LoadBalancer en un clúster de usuario, el controlador MetalLB asigna automáticamente una dirección IP al servicio. El controlador de MetalLB selecciona una dirección IP de un grupo de direcciones que especifiques.

Para asegurarte de que tu clúster de usuarios tenga suficientes direcciones IP, ten en cuenta el número máximo de servicios LoadBalancer que probablemente estén activos. A continuación, especifica suficientes direcciones IP en la sección loadBalancer.metalLB.addressPools del archivo de configuración de tu clúster de usuarios.

Las direcciones del grupo deben estar en formato CIDR o de intervalo. Para especificar una dirección concreta, usa un /32 CIDR. Por ejemplo:

addresses:
  -   "192.0.2.0/26"
  -   "192.0.2.64-192.0.2.72"
  -   "192.0.2.75/32"

Si necesitas ajustar las direcciones de un pool después de crear el clúster, puedes usar gkectl update cluster. Para obtener más información, consulta Actualizar MetalLB.

Habilitar MetalLB en un clúster de usuario nuevo

En el archivo de configuración de clúster de usuarios, haz lo siguiente:

  • Asigna el valor "MetalLB" a loadBalancer.kind.
  • Especifica uno o varios grupos de direcciones para los servicios. El VIP de entrada debe estar en uno de estos grupos.
  • Define enableLoadBalancer como true en al menos un grupo de nodos de tu clúster. Si se define como true, este campo permite que el altavoz de MetalLB se ejecute en los nodos del grupo.

    Ten en cuenta las siguientes diferencias en el comportamiento del campo enableLoadBalancer cuando se enableAdvancedCluster establece en true (clúster avanzado habilitado): en la versión 1.31, cuando el clúster avanzado está habilitado, este campo no tiene ningún efecto porque el altavoz de MetalLB siempre se ejecuta en los nodos del plano de control del clúster de usuario. En la versión 1.32, cuando se habilita el clúster avanzado, se elimina esta limitación y debes especificar al menos un grupo de nodos en el que se ejecute el altavoz de MetalLB.

Rellena el resto del archivo de configuración del clúster de usuarios y crea el clúster de usuarios como se describe en Crear un clúster de usuarios.

Asignación manual de direcciones de servicio

Si no quieres que el controlador de MetalLB asigne automáticamente direcciones IP de un pool concreto a los servicios, define el campo manualAssign del pool como true. Después, un desarrollador puede crear un servicio de tipo LoadBalancer y especificar manualmente una de las direcciones del grupo. Por ejemplo:

loadBalancer:
  metalLB:
    addressPools:
    - name: "my-address-pool-2"
      addresses:
      - "192.0.2.73-192.0.2.80"
      manualAssign: true

Evitar direcciones IP con errores

Si asignas el valor true al campo avoidBuggyIPs de un grupo de direcciones, el controlador de MetalLB no usará las direcciones del grupo que terminen en .0 o .255. De esta forma, se evita el problema de que los dispositivos de consumo con errores descarten por error el tráfico enviado a esas direcciones IP especiales. Por ejemplo:

loadBalancer:
  metalLB:
    addressPools:
    - name: "my-address-pool-1"
      addresses:
      - "192.0.2.0/24"
      avoidBuggyIPs: true

Crear un servicio de tipo LoadBalancer

Aquí tienes dos manifiestos: uno para un Deployment y otro para un Service:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-deployment
spec:
  selector:
    matchLabels:
      greeting: hello
  replicas: 3
  template:
    metadata:
      labels:
        greeting: hello
    spec:
      containers:
      - name: hello
        image: gcr.io/google-samples/hello-app:2.0
---
apiVersion: v1
kind: Service
metadata:
  name: my-service
spec:
  type: LoadBalancer
  selector:
    greeting: hello
  ports:
  - name: metal-lb-example-port
    protocol: TCP
    port: 60000
    targetPort: 8080

Ten en cuenta que el manifiesto de servicio no especifica una dirección IP externa. El controlador de MetalLB elegirá una dirección IP externa del grupo de direcciones que hayas especificado en el archivo de configuración del clúster de usuario.

Guarda los manifiestos en un archivo llamado my-dep-svc.yaml. A continuación, crea los objetos Deployment y Service:

kubectl --kubeconfig USER_CLUSTER_KUBECONFIG apply -f my-dep-svc.yaml

Ver el servicio:

kubectl --kubeconfig USER_CLUSTER_KUBECONIFG get service my-service --output wide

En la salida se muestra la dirección IP externa que se ha asignado automáticamente al servicio. Por ejemplo:

NAME         TYPE           CLUSTER-IP    EXTERNAL-IP   PORT(S)           AGE   SELECTOR
my-service   LoadBalancer   10.96.2.166   192.0.2.2   60000:31914/TCP   28s

Verifica que la dirección IP externa asignada se haya tomado del grupo de direcciones que has especificado en el archivo de configuración del clúster de usuario. Por ejemplo, 192.0.2.2 está en este grupo de direcciones:

metalLB:
  addressPools:
  - name: "address-pool-1"
    addresses:
     - "192.0.2.0/24"
     - "198.51.100.1-198.51.100.3"

Llamar al servicio:

curl EXTERNAL_IP_ADDRESS:60000

El resultado muestra un mensaje Hello, world!:

Hello, world!
Version: 2.0.0

Actualizar MetalLB

Después de crear el clúster, puedes actualizar los grupos de direcciones de MetalLB y el campo enableLoadBalancer de tus grupos de nodos. Haz los cambios que quieras en el archivo de configuración del clúster de usuario y, a continuación, llama a gkectl update cluster:

gkectl update cluster --kubeconfig ADMIN_CLUSTER_KUBECONIFG --config USER_CLUSTER_CONFIG

Pods y ConfigMap de MetalLB

El controlador de MetalLB se ejecuta como un Deployment y el altavoz de MetalLB se ejecuta como un DaemonSet en los nodos de los grupos que tienen enableLoadBalancer definido como true. El controlador de MetalLB gestiona las direcciones IP asignadas a los servicios. El altavoz de MetalLB realiza la elección del líder y anuncia los VIPs de los servicios.

Ver todos los pods de MetalLB:

kubectl --kubeconfig USER_CLUSTER_KUBECONIFG get pods --namespace kube-system --selector app=metallb

Puedes usar los registros de los pods de MetalLB para solucionar problemas.

La configuración de MetalLB se almacena en un ConfigMap en un formato conocido por MetalLB. No cambies el ConfigMap directamente. En su lugar, usa gkectl update cluster como se ha descrito anteriormente. Para ver el ConfigMap y solucionar problemas, haz lo siguiente:

kubectl --kubeconfig USER_CLUSTER_KUBECONIFG get configmap metallb-config --namespace kube-system

Ventajas de usar MetalLB

  • MetalLB se ejecuta directamente en los nodos de tu clúster, por lo que no requiere máquinas virtuales adicionales.

  • El controlador de MetalLB gestiona las direcciones IP de los servicios, por lo que no tienes que elegir manualmente una dirección IP para cada servicio.

  • Las instancias activas de MetalLB de diferentes servicios pueden ejecutarse en diferentes nodos.

  • Puedes compartir una dirección IP entre diferentes servicios.

Comparación de MetalLB con F5 BIG-IP y Seesaw

  • Las IPs virtuales deben estar en la misma subred que los nodos del clúster. Este requisito también se aplica a Seesaw, pero no a F5 BIG-IP.

  • No hay métricas de tráfico.

  • No hay conmutación por error sin interrupciones; las conexiones se reinician durante la conmutación por error.

  • El tráfico externo a los pods de un servicio concreto pasa por un solo nodo que ejecuta el altavoz de MetalLB. Esto significa que la dirección IP del cliente no suele ser visible para los contenedores que se ejecutan en el pod.

  • Cisco Application Centric Infrastructure (ACI) con Dataplane IP Learning no es compatible con los balanceadores de carga Seesaw y MetalLB. Te recomendamos que uses el balanceo de carga manual o que inhabilites Dataplane IP Learning cuando uses Seesaw o MetalLB como balanceador de carga. Además, Seesaw está en modo de mantenimiento. Desde la versión 1.32 de Google Distributed Cloud, las actualizaciones están bloqueadas para los clústeres que usan Seesaw. Debes migrar los clústeres a las funciones recomendadas antes de actualizar a la versión 1.32.