Équilibrage de charge groupé avec MetalLB

Ce document explique comment configurer GKE sur VMware pour utiliser l'équilibrage de charge groupé avec l'équilibreur de charge MetalLB.

Dans GKE sur VMware, MetalLB s'exécute en mode couche 2.

Exemple de configuration MetalLB

Voici un exemple de configuration pour les clusters exécutant l'équilibreur de charge MetalLB :

Configuration de l'équilibreur de charge MetalLB.
Configuration de l'équilibreur de charge MetalLB

Le schéma ci-dessus montre un déploiement MetalLB. MetalLB s'exécute directement sur les nœuds du cluster. Dans cet exemple, le cluster d'administrateur et le cluster d'utilisateur se trouvent sur deux VLAN distincts, et chaque cluster se trouve dans un sous-réseau distinct :

Cluster Sous-réseau
Cluster d'administrateur 172.16.20.0/24
Cluster d'utilisateur 172.16.40.0/24

admin-cluster.yaml

L'exemple suivant de fichier de configuration de cluster d'administrateur montre la configuration observée dans le schéma précédent :

  • de l'équilibreur de charge MetalLB ;

  • des adresses IP virtuelles sur MetalLB pour le serveur d'API Kubernetes et les modules complémentaires du cluster d'administrateur.

network:
  hostConfig:
  ...

  ipMode:
    type: "static"
    ipBlockFilePath: "config-folder/admin-cluster-ipblock.yaml"
...

loadBalancer:
  kind: "MetalLB"
  ...

  vips:
    controlPlaneVIP: "172.16.20.100"
    addonsVIP: "172.16.20.101"

admin-cluster-ipblock.yaml

L'exemple suivant de fichier de bloc d'adresses IP indique la désignation des adresses IP pour les nœuds du cluster d'administrateur. Il inclut également l'adresse du nœud de plan de contrôle pour le cluster d'utilisateur et une adresse IP à utiliser lors de la mise à niveau du cluster.

blocks:
- netmask: "255.255.255.0"
  gateway: "17.16.20.1"
  ips:
  - ip: 172.16.20.50
    hostname: admin-vm-1
  - ip: 172.16.20.51
    hostname: admin-vm-2
  - ip: 172.16.20.52
    hostname: admin-vm-3
  - ip: 172.16.20.53
    hostname: admin-vm-4
  - ip: 172.16.20.54
    hostname: admin-vm-5

user-cluster.yaml

L'exemple suivant de fichier de configuration de cluster d'utilisateur montre la configuration :

  • des pools d'adresses du contrôleur MetalLB pour choisir et attribuer des services de type LoadBalancer. L'adresse IP virtuelle d'entrée se trouve dans l'un de ces pools ;

  • de l'adresse IP virtuelle désignée pour le serveur d'API Kubernetes du cluster d'utilisateur, et l'adresse IP virtuelle d'entrée que vous avez choisie de configurer pour le proxy d'entrée. L'adresse IP virtuelle du serveur d'API Kubernetes se trouve sur le sous-réseau du cluster d'administrateur, car le plan de contrôle d'un cluster d'utilisateur s'exécute sur un nœud du cluster d'administrateur ;

  • d'un pool de nœuds permettant d'utiliser MetalLB. MetalLB sera déployé sur les nœuds du cluster d'utilisateur appartenant à ce pool de nœuds.

network:
  hostConfig:
  ...

  ipMode:
    type: "static"
    ipBlockFilePath: "config-folder/user-cluster-ipblock.yaml"
...

loadBalancer:
  kind: MetalLB
  metalLB:
    addressPools:
    - name: "address-pool-1"
      addresses:
      - "172.16.40.100/32"
      - "172.16.40.101-172.16.40.112
      avoidBuggyIPs: true
  ...

  vips:
    controlPlaneVIP: "172.16.20.102"
    ingressVIP: "172.16.40.102"
...

nodePools:
- name: "node-pool-1"
  cpus: 4
  memoryMB: 8192
  replicas: 3
  enableLoadBalancer: true

La configuration de l'exemple précédent spécifie un ensemble d'adresses disponibles pour les services. Lorsqu'un développeur d'applications crée un service de type LoadBalancer dans le cluster d'utilisateur, le contrôleur MetalLB choisit une adresse IP parmi ce pool.

user-cluster-ipblock.yaml

L'exemple suivant de fichier de bloc d'adresses IP indique la désignation des adresses IP pour les nœuds du cluster d'utilisateur. Il inclut une adresse IP à utiliser lors de la mise à niveau du cluster.

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

Configurer MetalLB

Ouvrir les ports de pare-feu

MetalLB utilise la bibliothèque de liste des membres Go pour effectuer l'élection du Leader. La bibliothèque memberlist utilise le port TCP 7946 et le port UDP 7946 pour échanger des informations. Assurez-vous que ces ports sont accessibles pour le trafic entrant et sortant sur tous les nœuds d'équilibreur de charge.

Activer MetalLB pour un nouveau cluster d'administrateur

Dans votre fichier de configuration de cluster d'administrateur, définissez loadBalancer.kind sur "MetalLB".

loadBalancer:
  kind: "MetalLB"

Renseignez le reste du fichier de configuration de votre cluster d'administrateur, puis créez le cluster d'administrateur comme décrit dans la section Créer un cluster d'administrateur.

Spécifier des pools d'adresses

Le contrôleur MetalLB gère les adresses IP des services. Ainsi, lorsqu'un développeur d'applications crée un service de type LoadBalancer dans un cluster d'utilisateur, il n'a pas besoin de spécifier manuellement une adresse IP pour le service. À la place, le contrôleur MetaLB choisit une adresse IP d'un pool d'adresses que vous spécifiez au moment de la création du cluster.

Déterminez le nombre de services de type LoadBalancer susceptibles d'être actifs dans votre cluster d'utilisateur à un moment donné. Dans la section loadBalancer.metalLB.addressPools du fichier de configuration de votre cluster d'utilisateur, spécifiez suffisamment d'adresses IP pour ces services.

L'adresse IP virtuelle d'entrée de votre cluster d'utilisateur doit faire partie des adresses que vous spécifiez dans un pool d'adresses. Cela est dû au fait que le proxy d'entrée est exposé par un service de type LoadBalancer.

Si vos développeurs d'applications n'ont pas besoin de créer de services de type LoadBalancer, vous n'avez pas besoin de spécifier d'adresses autres que l'adresse IP virtuelle d'entrée.

Les adresses doivent être au format CIDR ou au format de plage. Si vous souhaitez spécifier une adresse individuelle, utilisez un masque CIDR /32. Exemple :

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

Si vous devez ajuster les adresses dans un pool après la création du cluster, vous pouvez utiliser gkectl update cluster. Pour plus d'informations, consultez Mettre à jour MetalLB.

Activer MetalLB pour un nouveau cluster d'utilisateur

Dans le fichier de configuration du cluster d'utilisateur, procédez comme suit :

  • Définissez loadBalancer.kind sur "MetalLB".
  • Spécifiez un ou plusieurs pools d'adresses pour les services. L'adresse IP virtuelle d'entrée doit appartenir à l'un de ces pools.
  • Définissez enableLoadBalancer sur true pour au moins un pool de nœuds de votre cluster.

Renseignez le reste de votre fichier de configuration de cluster d'utilisateur, puis créez le cluster d'utilisateur comme décrit dans la section Créer un cluster d'utilisateur.

Attribuer manuellement des adresses de service

Si vous ne souhaitez pas que le contrôleur MetalLB attribue automatiquement les adresses IP d'un pool particulier aux services, définissez le champ manualAssign du pool sur true. Un développeur peut ensuite créer un service de type LoadBalancer et spécifier manuellement l'une des adresses du pool. Exemple :

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

Éviter les adresses IP susceptibles aux bugs

Si vous définissez le champ avoidBuggyIPs d'un pool d'adresses sur true, le contrôleur MetalLB n'utilise pas les adresses du pool qui se terminent par .0 ou .255. Cela évite le problème des bugs avec les appareils grand public qui suppriment par erreur le trafic envoyé à ces adresses IP spéciales. Exemple :

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

Créer un service de type LoadBalancer

Voici deux fichiers manifestes, un pour un déploiement et un pour 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

Notez que le fichier manifeste du service ne spécifie pas d'adresse IP externe. Le contrôleur MetalLB choisit une adresse IP externe dans le pool d'adresses que vous avez spécifié dans le fichier de configuration du cluster d'utilisateur.

Enregistrez les fichiers manifestes dans un fichier nommé my-dep-svc.yaml. Créez ensuite les objets Deployment et Service :

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

Consultez le Service :

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

La sortie affiche l'adresse IP externe qui a été attribuée automatiquement au service. Exemple :

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

Vérifiez que l'adresse IP externe attribuée provient du pool d'adresses que vous avez spécifié dans le fichier de configuration de votre cluster d'utilisateur. Par exemple, 192.0.2.2 se trouve dans ce pool d'adresses :

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

Appelez le service :

curl EXTERNAL_IP_ADDRESS:60000

La sortie affiche un message Hello, world! :

Hello, world!
Version: 2.0.0

Mettre à jour MetalLB

Après avoir créé votre cluster, vous pouvez mettre à jour les pools d'adresses MetalLB et le champ enableLoadBalancer dans vos pools de nœuds. Apportez les modifications souhaitées au fichier de configuration du cluster d'utilisateur, puis appelez gkectl update cluster :

gkectl update cluster --kubeconfig ADMIN_CLUSTER_KUBECONIFG --config USER_CLUSTER_CONFIG

Pods MetalLB et ConfigMap

Le contrôleur MetalLB s'exécute en tant que déploiement et le Speaker MetalLB s'exécute en tant que DaemonSet sur les nœuds des pools dont enableLoadBalancer est défini sur true. Le contrôleur MetaLB gère les adresses IP attribuées aux services. Le Speaker MetalLB procède à l'élection du Leader et annonce les adresses IP virtuelles du service.

Affichez tous les pods MetalLB :

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

Vous pouvez utiliser les journaux des pods MetalLB pour résoudre les problèmes.

La configuration de MetalLB est stockée dans un ConfigMap dans un format connu de MetalLB. Ne modifiez pas directement le ConfigMap. Utilisez plutôt gkectl update cluster comme décrit précédemment. Pour afficher le ConfigMap afin de résoudre des problèmes, procédez comme suit :

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

Avantages de l'utilisation de MetalLB

  • MetalLB s'exécute directement sur vos nœuds de cluster et ne nécessite donc pas de VM supplémentaires.

  • Le contrôleur MetalLB gère les adresses IP des services. Vous n'avez donc pas besoin de choisir manuellement une adresse IP pour chaque service.

  • Les instances actives de MetalLB pour différents services peuvent s'exécuter sur différents nœuds.

  • Vous pouvez partager une adresse IP entre différents services.

MetalLB par rapport à F5 BIG-IP et Seesaw

  • Les adresses IP virtuelles doivent se trouver dans le même sous-réseau que les nœuds de cluster. Il s'agit également d'une exigence pour Seesaw, mais pas pour F5 BIG-IP.

  • Il n'existe aucune métrique pour le trafic.

  • Il n'y a pas de basculement sans discontinuité (hitless). Les connexions existantes sont réinitialisées lors du basculement.

  • Le trafic externe vers les pods d'un service particulier passe par un seul nœud exécutant le Speaker MetalLB. Cela signifie que l'adresse IP du client n'est généralement pas visible par les conteneurs s'exécutant dans le pod.