Le multihoming, qui implique l’association de plusieurs réseaux à un nœud, permet de gérer l’utilisation de réseaux hétérogènes dans un cluster Hadoop. Cet article est une introduction au concept de multihoming et à ses applications sur des cas d’usages concrets.

Contexte

Tout d’abord, pour un aperçu général du multi-réseau sur Hadoop, je vous conseille l’article de Matt Foley. C’est un bon début pour comprendre de façon générale en quoi consiste la configuration réseau dans Hadoop.

Dans cet article, nous aborderons certains de ses points et ajouterons des cas d’utilisation concrets, ainsi qu’une explication détaillée pour Apache HDFS en particulier.

Qu’est ce que le multihoming ?

Dans les environnements de production complexes, les serveurs disposent généralement de plusieurs cartes d’interface réseau (performances, isolement du réseau, besoins professionnels ou toute autre raison à laquelle les administrateurs réseau peuvent penser).

Parfois, ces cartes réseau sont reliées pour multiplier leur débit. Dans ce cas, elles fonctionnent comme une seule interface haute performance. Ce type d’interface n’a pas besoin de configurations de routage réseau spécifiques. Dans un environnement multi-NIC, cela ne peut pas être considéré comme une situation de multihoming.

Cependant, il arrive que plusieurs hôtes partagent plusieurs réseaux. Par défaut, la première carte réseau connectée à un réseau commun sera choisie. L’ordre dans lequel chaque carte réseau est vérifiée est alors le facteur décisif et un même réseau sera choisi pour toutes les communications entre ces deux hôtes.

Le comportement par défaut n’est parfois pas suffisant. Dans Hadoop, par exemple, nous souhaitons peut-être diviser la communication réseau en fonction des composants logiciels ou même en fonction de la tâche qu’ils exécutent actuellement. Hadoop doit donc pouvoir gérer ces réseaux multiples et utiliser les bons pour chaque tâche.

Pourquoi voudrions-nous du multihoming?

Avoir plusieurs réseaux dans les environnements de production permet de faciliter la mise en place de la gouvernance. Par exemple, vous pouvez utiliser un réseau local dédié pour votre cluster Hadoop et un réseau distinct pour communiquer avec des composants externes. Autre exemple, au sein d’un cluster, vous souhaitez que vos composants HDP puissent communiquer entre eux sur leur propre réseau et permettre aux clients d’y accéder via un autre réseau. Ou tout cela dans le cas d’une architecture de reprise après sinistre, où vous avez un réseau haut débit dédié aux tâches de sauvegarde de données entre clusters, chacun d’eux ayant sa propre architecture multi-réseau pour séparer la communication intra-composants et l’accès client.

Il peut y avoir d’autres raisons, mais ce sont celles que nous rencontrons le plus souvent dans nos environnements clients.

Soyons un peu plus précis ici. Nous nous limiterons aux composants HDFS, dans lesquels il existe deux cas d’utilisation principaux.

Cas 1: client-service vs service-service

Dans une tâche hdfs dfs -put , les hôtes DataNode gèrent deux types de communication réseau.

Le premier se situe entre le client (celui qui a lancé la tâche) et le DataNode sur lequel le premier bloc HDFS sera écrit. Nous appellerons cela la communication client-service.

Une fois le bloc écrit commence le deuxième type de communication entre l’hôte DataNode sur lequel il vient d’être écrit et un autre hôte DataNode sur lequel une réplique du bloc doit être écrite : une communication service-service.

Dans l’illustration précédente, la communication client-service est représentée par la flèche bleue et hébergée sur le réseau mappé sur la carte réseau eth0  du client et de l’hôte DN1 (composant de service DataNode). La communication service-service est représentée par la flèche orange et hébergée sur le réseau mappé sur la carte réseau eth1  de chaque hôte DataNode.

Ce cas est particulièrement utile pour séparer un réseau frontal dépendant de l’utilisateur sur lequel vous n’avez peut-être pas le contrôle de la charge de travail et un réseau principal dédié aux communications critiques entre services.

Cas 2: intra-cluster vs inter-cluster

Toujours à propos de HDFS, prenons la tâche hdfs distcp  comme exemple cette fois. C’est une commande courante utilisée pour transférer des données HDFS d’un cluster à un autre.

Le client qui a lancé la commande et tous les composants HDFS de chaque cluster communiquent via trois réseaux différents au maximum :

  • celui entre le client et le NameNode et les DataNodes du cluster source
  • celui entre les composants HDFS du cluster source et ceux du cluster de destination
  • celui situé entre les composants HDFS du cluster de destination

Dans l’illustration précédente, nous l’avons simplifiée en prenant en compte uniquement les communications entre le client et les deux NameNode actifs de chaque cluster, en supposant que la commande a été lancée sur le cluster source.

Pour commencer à collecter des informations de métadonnées à partir du NameNode du cluster source, le client utilisera le réseau intra-cluster mappé sur la carte réseau eth0  représentée par la flèche bleue.

Ensuite, pour obtenir des informations supplémentaires sur l’état du cluster de destination, le NameNode du cluster source utilisera le réseau inter-cluster mappé sur la carte réseau eth1  représentée par une flèche orange pour communiquer avec son homologue distant.

Ce cas est très souvent utilisé pour la reprise après sinistre dans laquelle deux clusters physiquement distants ont chacun leur propre réseau interne pour dialoguer avec des composants du même environnement et un réseau séparé pour les communications externes entre eux.

Que cela implique t-il ?

Ceci est la dernière partie de la collecte de connaissances avant de passer à la mise en œuvre pratique. Dans la section précédente, nous avons expliqué que le multihoming implique le choix d’un réseau pour une communication donnée entre deux hôtes. Cela s’appelle la résolution de réseau.

Il existe deux manières de choisir un réseau de communiquer avec un hôte distant:

  • Choix d’une carte réseau (rappel: connecteur d’interface réseau) liée à un seul réseau
  • Résolution du nom d’hôte, directement à partir du système local ou via un DNS

Les configurations basées sur une carte réseau prennent différents types de valeurs pour différents cas d’utilisation. Pour définir l’identité d’un hôte spécifique sur un réseau donné, la valeur est généralement une adresse IP unique telle que 192.168.100.1 . Pour un groupe d’hôtes, cette valeur est étendue à une plage IP pouvant ressembler à 192.168.100.1:32 .

Par ailleurs, pour ouvrir les communications à partir de et / ou vers plusieurs réseaux, certaines configurations peuvent être définies sur une valeur telle que 0.0.0.0  ou 0.0.0.0:0 . Ceci est utilisé par exemple pour que le processus NameNode écoute sur tous les NIC du nœud sur lequel il est hébergé ou ouvre une topologie Knox à tous les hôtes partageant son réseau.

Parfois, une configuration est spécifiquement conçue pour définir une seule carte réseau pour les hôtes sur lesquels elle est appliquée. L’hôte utilise ensuite directement le nom de la carte réseau comme valeur: eth0 , eth1 , wlp2s0 , virbr0 , etc.

À la place d’une adresse IP, les configurations acceptent également les FQDN. Vous pouvez ensuite utiliser par exemple myhost.domain1  et myhost.domain2  pour définir les communications de et vers myhost. Attention, la plupart des composants Hadoop ne gèrent pas plusieurs noms abrégés pour un seul hôte. L’utilisation de myhost.domain1  et otherhost.domain2 en tant que FQDN pour le même nœud n’est donc pas prise en charge !

Comment faisons-nous ça?

Hadoop (HDFS et YARN), Apache HBase, Apache Oozie et d’autres services Big Data de base partagent un modèle commun pour les configurations de leurs composants. Par souci de simplicité, seules les configurations de HDFS NameNode seront détaillées, mais le concept est le même pour la plupart des composants.

Le composant HDFS NameNode possède trois propriétés distinctes pour chaque moyen d’interaction et une propriété supplémentaire pour différencier les communications inter-services des autres :

  • dfs.namenode.http*  pour les communications HTTP (obsolète si HTTPS_ONLY est activé) vers WebHDFS
  • dfs.namenode.https*  pour les communications HTTPS (obsolète si HTTP_ONLY est activé) vers WebHDFS
  • dfs.namenode.rpc*  pour les communications RPC avec NameNode
  • dfs.namenode.servicerpc*  pour les communications RPC vers NameNode à partir d’autres composants HDFS (par exemple, DataNodes)

À qui suis-je en train de parler ? (propriété -address )

Le premier groupe de propriétés est utilisé par des sources externes (clients, composants d’autres services) pour savoir avec qui communiquer pour une tâche donnée. Le nom de protocole de ces propriétés est suffixé par -address. Même dans un environnement sans multi-hébergement, ces configurations sont nécessaires.

Un cluster HDFS hautement disponible et multi-hôte qui sépare les communications RPC inter-services et par défaut peut avoir les propriétés suivantes:

Où est-ce que j’écoute? (propriété -bind-host)

Le second groupe de propriétés est principalement utilisé dans un environnement multi-hôte. Il est utilisé par un composant qui sait sur quel réseau écouter. Le nom de protocole de ces propriétés est suffixé par -bind-host.

Le même cluster HDFS hautement disponible et multi-hôte qui sépare les communications RPC inter-services et par défaut peut avoir les propriétés suivantes:

Cependant, dans la plupart des cas d’utilisation, les NameNodes doivent écouter tous les réseaux disponibles:

Autres propriétés impliquées

Pour communiquer avec les composants HDFS, la plupart des processus ont tendance à demander des informations au NameNode. Cela inclut la résolution du nom d’hôte pour communiquer avec un autre NameNode ou un DataNode. Mais parfois, les DataNodes et les clients doivent utiliser leur propre résolution de nom d’hôte au lieu de celle de NameNode. Pour ce faire, les propriétés suivantes doivent être définies à “true”:

  • dfs.client.use.datanode.hostname = true pour que le client résolve sa recherche DNS localement
  • dfs.datanode.use.datanode.hostname = true  pour que les DataNodes résolvent leur recherche DNS localement

Les configurations de sécurité Hadoop incluent également des propriétés permettant de remplacer le comportement par défaut de la recherche DNS en forçant une carte réseau ou un serveur de noms donné:-

  • hadoop.security.dns.interface = eth0  pour verrouiller la recherche DNS sur un ensemble de cartes réseau (séparées par une virgule)
  • hadoop.security.dns.nameserver = 192.168.101.1  pour forcer l’utilisation d’un DNS donné