lundi 19 octobre 2015

Auto Configuration

Principe

Il n’est pas question de configurer à la main la carte micro-SD de chaque Raspberry Pi 2 du cluster. Nous allons plutôt construire une image unique, un master, que l’on dupliquera. A chaque boot le Rasperry Pi s’auto configurera pour fonctionner comme nœud du cluster. Ce système d’auto configuration devra donner une adresse IP unique, ainsi qu’un nom (hostname) unique, à chaque nœud.

L’affectation d’une adresse IP spécifique à chaque nœud se fera par DHCP. L’affectation du hostname pourrait aussi se faire via DHCP, mais tous les serveurs DHCP ne le permettent pas (en particulier ceux inclus dans les box des opérateurs internet). L’affectation du hostname unique se fera donc via un script exécuté sur le nœud à chaque fois qu’il recevra une adresse IP du serveur DHCP.

Concrètement

  • Les IP seront allouées dans le réseau privé 192.168.0.0/24
  • Sur la base de son adresse MAC, chaque nœud obtiendra du serveur DHCP une IP fixe spécifique, de la forme 192.168.0.XXX
  • Au moment de l’allocation de cette adresse IP un script extraira du fichier /etc/hosts le hostname associé a cette IP et l'affectera au système.
Le lien entre adresse MAC et adresse IP sera configuré une fois pour toutes dans le serveur DHCP. Donc, au lieu de configurer chaque carte micro-SD individuellement avec sa propre ip et son hostname, on configurera de manière centralisé le serveur DHCP.

Exemple :
    Adresse MAC envoyée au serveur DHCP: b8 27 eb c6 3f 77
    Adresse IP retournée par le DHCP: 192.168.0.105
    Hostname assigné: node05

PAS à PAS

Si rien n'est dit c'est qu'il faut faire la même chose avec Raspberian et avec CentOS.

a) Désactiver ipv6
Ajouter disable_ipv6=1 à la fin de l'unique ligne de /boot/cmdline.txt
et/ou ajouter au fichier /etc/sysctl.conf la ligne
net.ipv6.conf.all.disable_ipv6=1


b) Mettre à jour /etc/hosts

(on en profite pour enlever tout ce qui concerne ipv6)

> cat /etc/hosts
127.0.0.1       localhost
 

192.168.0.101   node01
192.168.0.102   node02
192.168.0.103   node03
 ...

192.168.0.115   node15
c) Configuration du daemon client dhcpcd (Raspbian)
Son vrai nom est dhcpcd5 bien que ce soit la version 6 !

> cat /etc/dhcpcd.conf
# debug
ipv4only
noarp
option domain_name_servers, domains_name
nohook lookup-hostname, hostname

TOUT le reste doit être supprimé ou mis en commentaire avec #

Pour CentOS rien à faire (le fichier /etc/dhcpcd.conf n'existe pas) et le client s’appelle dhclient.


d) interfaces (Raspbian)


cat /etc/network/interfaces
auto  lo eth0
iface lo   inet loopback
iface eth0 inet manual

Même si c’est dhcpcd qui configurera l’interface eth0 il ne faut pas utiliser ‘dhcp’ mais ‘manual’.

Pour CentOS toujours rien à faire, eth0 est par défaut configurée par dhcp.

e) Attribution du hostname (Raspbian)

Dans le répertoire /lib/dhcpcd/dhcpcd-hooks créer le fichier 99-set-hostname

cat /lib/dhcpcd-hooks/99-set-hostname
get_hostname()
{

    [ -z "$new_ip_address" ] && return 1
    local h="$(/usr/bin/getent hosts $new_ip_address)"
    if [ $? = 0 ]; then
        echo "$h" | sed 's/[^ ]* *\([^ ]*\).*/\1/'
        return 0
    fi
    return 1
}

if $if_up ; then
    if [ -z "$new_host_name" -a -z "$new_fqdn_name" ]; then
        export new_host_name="$(get_hostname)"
        hostname $new_host_name
    fi
fi
Ce script utilise l'adresse ip assignée par le serveur DHCP pour trouver le hostname dans le fichier /etc/hosts et l'assigner au système. (c'est du reverse DNS sans DNS)

Note: dans ce même répertoire les deux scripts 29-loopup-hostname et 30-hostname ont été désactivés dans /etc/dhcpcd.conf par la commande :
nohook lookup-hostname, hostname
e) Attribution du hostname (CentOS 7.x)

A chaque changement dans la config réseau le NetworkManager exécute les scripts qui sont dans /etc/NetworkManager/dispatcher.d Dans ce répertoire il y a déjà le script 11-dhclient qui source  les scripts xxxx.sh qui sont dans  le répertoire /etc/dhcp/dhclient.d et invoque la fonction xxxx_config quand interface devient  ‘up’, ou xxxx_restore quand une interface passe ‘down’. Les variables d’environnement donnant les info sur l’interface concernée (ip, netmask, gateway ..)
On va donc mettre notre script sethostname.sh dans /etc/dhcp/dhclient.d

cat /etc/dhcp/dhclient.d/sethostname.sh

function sethostname_config {
  local ip_addr=127.0.0.1
  if [ -n "$IP4_ADDRESS_0" ]; then
    ip_addr="$(echo "$IP4_ADDRESS_0" | /usr/bin/cut -d'/' -f1)"
  else
    ip_addr=$DHCP4_IP_ADDRESS
  fi
  local h="$(/usr/bin/getent hosts $ip_addr)"
  if [ $? = 0 ]; then
    export new_hostname=$(echo "$h" | /usr/bin/awk '{print $2}')
    /usr/bin/hostnamectl --static set-hostname $new_hostname
    echo "Set my hostname to '$new_hostname' "
  else
    echo "ERROR: Cannot find $ip_addr in /etc/hosts"
  fi
}

function sethostname_restore {
  : # nothing todo

}

Note: Suivant la version du client dhcp ce sont les variables $IP4_* ou $DHCP4_* qui sont utilisées. D'où le test en début de script pour initialiser $ip_addr. Si le nom de host est 'localhost' c'est que aucune des deux variables n'existe, ou que le fichier /etc/hosts n'est pas à jour.

Ne pas oublier:

chmod +x /etc/dhcp/dhclient.d/sethostname.sh


f) Configurer le serveur DHCP
Se loguer sur chaque Raspberry Pi 2 pour noter l’adresse MAC de son interface Ethernet. Le plus simple est de faire cela via la console (HDMI/clavier usb), sans câble réseau. Ne pas être connecter au réseau évitera des problèmes de cache DHCP.

Une fois connecté à la console du Raspberry taper la commande :

cat /sys/class/net/eth0/address


Note : L’adresse MAC (Media Access Control Address) est constituée de 6 octets. Les 3 octets de poids fort dépendent du fabriquant. Pour Raspberry ces 3 octets sont toujours : b8 27 eb. Les 3 octets de poids faible identifient l’interface. Dans le cas des RPi ce sont les 3 octets de poids faible du numéro de série que l’on peut voir avec la commande : cat /proc/cpuinfo


Pour chaque adresse MAC ajouter une entrée dans la configuration du serveur DHCP. (voir la doc de cotre serveur DHCP. Exemple ci-contre)

La routine à répéter 15 fois est donc :
- se loger a un Raspberry en console et sans câble réseau
- noter l'adresse mac afficher par cat /sys/class/net/eth0/address
- mettre à jour le serveur DHCP (adresse mac, adresse ip)
- brancher le réseau
- rebooter le RPi (alt-ctrl-del)
- Au boot on doit avoir l'IP et le hostname voulus.
- shutdown
- deplacer la carte micro-sd au raspberry suivant
répéter...


Patience, ne dupliquez pas encore cette carte.
A SUIVRE...

dimanche 18 octobre 2015

Customisation


Le but est de créer une carte micro-SD master qui sera dupliquée en 15 exemplaires et sera installée sur chaque Raspberry du cluster. Le point de départ est l’une des images « Raspbian Jessie » ou CentOS 7 pour armv7hl. On crée une micro-SD master en se basant sur les instructions données par les liens précédant, puis on customise pour nos besoins de programmation parallèle en cluster.
Dans le cas de CentOS l'installation de depart est minimale, on ajoutera des packages. Dans le cas de Raspbian l'installation de départ est très complète, on enlèvera beaucoup de packages puis on en ajoutera.

  1. L’adresse MAC de la carte Ethernet du Raspberry jouant un rôle important dans l’auto configuration on va modifier le fichier .bash_profile de 'root' (pour CentOS) ou de 'pi' pour Raspbian afin d'afficher cette adresse MAC au login.

    echo My MAC address is $(cat /sys/class/net/eth0/address)
     
  2. On effectua plusieurs modifications pour qu’au boot chaque Raspberry PI 2 se configure automatiquement avec sa propre adresse IP et son propre nom sans que cette ip et ce nom ne soient hardcodé sur la carte. Auto Configuration
     
  3. Pour Raspbian supprimer tous les packages inutiles pour nous, principalement ceux liés au multimédia, à XWindow/X11 et libérer ainsi plus de 1Go de place sur la carte micro-SD.
     
  4. Installer, enfin, les packages spécifiques à la programmation parallèle en cluster.
  5. Installation de nos propres outils de gestion du cluster.
Le résultat est la carte micro-SD master qui sera dupliquée et installée dans chaque nœud du cluster.

samedi 17 octobre 2015

Montage en images

Voici en quelques images les principales étapes du montage dans son boitier du cluster de Raspberry Pi 2.


1: De chaque coté du boitier percer les 4 trous pour la ligne de RPi du haut, les 4 trous pour la ligne  de RPi du bas, les 4 trous pour la fixation du switch. Pour pouvoir passer les tiges filetées dans les trous des circuits imprimés des Raspberry il faut les agrandir légèrement avec une mèche bois de 3mm.


2: Découper à la bonne longueur et passer les tiges filetées (3mm)
Fixer le switch. (Le switch n'est pas traversé de part en part  ;-)


3: Enfiler les Raspberry.


Pour maintenir un écartement constant, et éviter les contacts entre RPi, enfiler entre chaque RPi un tronçon de paille à boire.


4: Mettre en place l'alimentation 5 Volts.


6: Câbles USB-A / micro USB-B : Couper le coté USB-A.



7: Mettre en place les câbles (proprement)


8: Relier les câbles USB à l'alim, sans se tromper de sens: noir= -V (masse), rouge= +V (5 Volts) .
Ne pas relier les fils de data (blanc et vert).

Brancher.

Après c'est du logiciel.

vendredi 16 octobre 2015

Coût du cluster

Voici le détail du coût de construction d'un cluster avec 15 Raspberry Pi 2 Modèle B. L'explication du choix des composants est détaillé dans ce post sur le design du cluster.

Notes: Dans toutes les commandes soit les frais de ports étaient 'offerts' car la commande dépassait un seuil (RadioSpare et Farnell), soit la livraison était faite en relais-colis (LDLC).


Description
Vendeur
Quantité
PU TTC
Total TTC
Raspberry Pi 2
Farnell
15
40 
600 
Carte micro usb 8Go Sandisk
LDLC
15
120 
Câble USB-A/micro usb-B (alim)
RadioSpare
15
45 
Câble réseau  Cat 5e UTP 50cm
RadioSpare
15
1.5 
23 





Switch Ethernet
LDLC
1
57 
57 
Alimentation régulée 5V 20A
RadioSpare
1
70 
70 
Boitier bois 35x35x33cm
Castorama
1
Tiges filetées 3mm de 1m
Castorama
4
0.90 
Divers (visserie, pailles …)



10 
TOTAL



938 



Notez que l'alim, plus les 15 câbles usb, revient à  (70+45 )/15 ~ 7.5 € / RPi2. Donc une solution économique et pourtant plus fiable que les bloc secteurs low-cost à 8€.

Le total de 938€ peut être vu comme 15 x 62.5€. Soit 22.5€ en plus des 40€ d'un RPi2B. Ces 22 € incluent boitier, alim, carte mémoire et mise en réseau. C'est le coût de mise en œuvre d'un RPi2B dans notre cluster.

Si on regarde ce que coute individuellement une alimentation basique (8 €), un boitier (9 €), et une carte mémoire (8€) on obtient un coût de mise en œuvre de 25€ donc plus que nos 22.5 € alors que dans notre cas il y a la mise en réseau inclue.

Notre mise en œuvre en cluster est donc nettement plus économique qu'une mise en œuvre individuelle.




Design du cluster

UNITÉ CENTRALE

On ne va pas tourner autour du pot, ce qui a déclenché ce projet de cluster c’est l’arrivé du Raspberry Pi 2 modèle B en Février 2015. Pour 50€ TTC (Raspberry + carte micro SD + alim) on a un véritable ordinateur. Le cœur de notre cluster sera donc un certain nombre de Raspberry Pi2 B.

Pour répondre à la question « combien de RPi2B ? », il faut se pencher sur un autre composant : le réseau.

SWITCH ETHERNET

La programmation concurrente repose sur la communication entre les taches. Quand les taches s’exécutent sur la même machine on utilise les techniques classiques mais quand elles sont reparties sur plusieurs machines il faut établir un réseau entre ces machines. Le RPi2B possède une interface Ethernet 100Mb. Pour relier les RPI2B entre eux il faut donc un switch Ethernet.

On trouve tous les types de switch Ethernet sur Internet. Du switch 10Mb au switch 10Gb, du switch 4 ports au switch 48 ports, du switch à 25€ au switch à plus de 10000€.

Compte tenu des caractéristiques du RPi2B inutile de prendre plus rapide que 100Mb, le POE (Power Over Ethernet) aurait été très pratique mais n’est pas  supporté par le RPi2B.

Il faut noter qu’avec un switch N ports on pourra connecter (N-1) RPi, puisque il faut garder un port pour se connecter au reste du réseau local et/ou à Internet. Il nous a semblé que 8 ports (donc 7 RPi) risquaient d’être un peu limités mais que 24 ports (23 RPi) allaient couter trop cher. Nous avons opté pour un switch 16 ports 100Mbits.

On trouve plusieurs switchs de ce type dans la gamme de prix 35€ à 60€ (Cisco, D-Link, Netgear). Nous avons opté pour le Cisco Small Business « SF-100 16 » à 57€. Il est rackable et a une alim intégrée.



La réponse à la question « Combien de RPi2B ? » est donc 15 (maximum).

ALIMENTATION

Mais 15 RPi2 impliquent 15 blocs d’alimentations secteur 220V/5V micro-usb, sur 15 prises secteur. Il est hors de question de faire ce type de montage ! Surtout que ces alimentations sont TOUTES, et j’insiste sur TOUTES, inadaptées, y compris celle vendue par Raspberry !


C’est pourquoi, comme indiqué en détail dans ce post sur l'alimentation d'un Raspberry Pi, nous avons opté pour une alimentation stabilisée 5 Volts 20 Ampères (100W) ajustable dont la qualité est supérieure, et le cout inférieur, à 15 blocs secteur 220V/5V.

L’inconvénient de l’alimentation unique c’est qu’il faut y ajouter 15 câbles se terminant par 15 prises micro-usb. Après avoir étudié en détail les pièces nécessaires pour  faire ces câbles, il s’est avéré qu’acheter des câbles standards USB/micro-usb était moins cher, et plus fiable, que de se les faire soit même.
Alimentation 5V ajustable

[EDIT]
Après plusieurs semaines d’utilisation intensive du cluster (15 Raspberry Pi 2 B) sa consommation globale n’a jamais atteint 5 ampères ! Ce qui signifie que :
1) la consommation individuelle d’un RPi2B ne dépasse pas 300mA !
3) Notre alim  20 A est surdimensionnée d'un facteur 3 ! Une 10 A aurait très largement suffit.
2) Même si le chip vidéo n’est pas mis à contribution dans ce type d’utilisation, et qu’il n’y a pas de périphériques USB branchés, les recommandations d’une alim de 2 A pour une utilisation basique me semblent bien exagérées ! Une tension de 5.3 volts serait bien plus appropriée.

 BOITIER

Mon fils ayant passé l’âge de jouer aux Lego l’option du boitier en Lego est encartée…  et en plus c’est cher ! Là aussi, faire les choses soit même ne donne pas le meilleur rapport qualité/prix. C’est chez Castorama que l’on a trouvé un cube en bois de 35x35x33cm pour 9€. Suffisant pour contenir notre cluster : les 15 Raspberry Pi 2 modèle B, le switch Ethernet Cisco et l’alimentation stabilisée 5V.

Pour fixer les 15 Raspberry Pi on a utiliser 4 tiges filetées 3mm de 1m de de longs à 0.95€ la tige.

Et voila !



mardi 13 octobre 2015

Alimentation des Raspberry

Pour une raison inhérente au design des Raspberry Pi il est impératif d’avoir une alimentation (régulée) dont la tension de sortie pourra être réglée à légèrement plus que 5 Volts. Si vous utilisez un bloc d’alimentation basique (type chargeur de téléphone) vous aurez à l’entrée du RPi au maximum 5 Volts (souvent moins pour les bas de gamme de eBay) et toujours moins à l’intérieur du RPi. C’est mathématique ! 

Vin = I . (R1+R2) = U1 + U2


Alimentation 5V d'un Raspberry Pi



Explications

A l’entrée du RPi il y a un fusible (F3) de type Polymeric PTC (Positive Temperature Coefficient). Sa résistance, faible en temps normal (~0.4 Ohm) augmente quand le courant qui le traverse dépasse un seuil. La vitesse de réaction du ce type de fusible est proportionnelle au carré de l’intensité traversant le fusible.


Par effet Joule le courant qui traverse le fusible fait augmenter sa température ce qui modifie la structure cristalline du fusible. Les molécules de graphite s’éloignant les unes des autres avec la dilatation du polymère, la résistance augmente.




Sur le schéma du RPi la légende de F3 est « miniSDM  1A1 6V », et sur le composant il y a indiqué T075 (ou juste 07). Cela signifie que sa résistance augmente à partir de 0.75A (point 1) et qu’elle devient très élevée à partir de 1.1A (Point 3). Le temps pour revenir à une très faible résistance est de quelques secondes en temps normal mais peu atteindre plusieurs heures en cas de très fort courant.

On revient à moins de 1 Ohm en 3 secondes et à la valeur de base ~0.4 Ohm en 30secondes.

 Conséquences

Si la résistance du fusible F3 est de 0.4 Ohm et le courant consommé par le Raspberry de 0.7 Ampère, alors la chute de tension aux bornes du fusible est de l’ordre de 0.3 Volt (U = R I ). La tension disponible dans le RPi n'est alors que de 4.7 Volts.


Le noyau Linux compilé pour les RPi (Raspbian) détecte si la tension chute sous les 4.65 Volts et

 - affiche un carré coloré en haut à droite de l’écran de la console (pas visible en ssh)

 - empêche le processeur ARM d’utiliser le mode turbo.


Dans un environnement desktop cette perte du turbo n’est pas dramatique, mais dans le cadre de notre projet de cluster, dont le but est d’utiliser tous les processeurs à leur maximum pendant des heures, ce blocage du mode turbo serait très dommageable pour les performances.

Donc, pour éviter l’enchevêtrement de 15 blocs d’alimentation médiocres, et pour préserver les performances, nous allons utiliser une alimentation stabilisée externe 5V 20A que nous règlerons à environ 5.20 Volts.

Pour faire le réglage on mesure la tension sur un port USB (pin1, pin4). On ajuste (avec précaution) la tension de sortie de l’alimentation régulée pour avoir 5 Volts sur le port USB. (NB: Il faut que le RPi ai booté pour que ses ports USB soient alimentés. Ce dernier point reste un mystère car rien sur le schéma du RPi n’explique comment le 5 Volts des ports USB est contrôlé…)

ATTENTION : La diode D17 est une diode de type Transil bidirectionnel (ou TVS  Transient Voltage Supression). Sa fonction est de limiter la tension U2 à moins de 6.5 Volts (Vbr). Plus cette tension s’élèvera au-dessus de 5 Volt (Vr) plus la diode absorbera de courant pour maintenir une tension proche de 5 Volts à ses bornes. Donc inutile de sur-volter vos RPi !

Diode TVS SMBJ5