1. Systèmes de fichiers distribués▲
Cette version est une version allégée de mon livre sur le cloud computing. La version complète se trouve ici.
Un système de fichiers distribué est un système où le poste client accède à un espace de stockage virtuel unique. Les données peuvent être réparties/dupliqués sur plusieurs machines de façon transparente pour celui-ci. C'est le moteur du système de fichiers distribué qui a la charge de répartir les données et de les dispatcher au client.
Les systèmes de fichier distribués les plus répandus sont :
- CephCeph ;
- GlusterFSGlusterFS ;
- Hadoop Distributed File System (HDFS) ;
- Lustre (utilisé par les super-calculateurs) ;
- NFSNFS - Network File System.
Sur les tests effectués, il ressort deux approches :
- une approche en blocs (chunks) répartis sur plusieurs machines et pour lesquels les métadonnées peuvent être centralisées ou distribuées et permettent de reconstruire les fichiers ;
- une approche reposant sur la notion de fichiers et utilisant ou non des métadonnées. Certains nécessitent d'avoir une ou plusieurs machines dédiées aux métadonnées, d'autres permettant d'intégrer les métadonnées sur les machines stockant les données, ou éventuellement sur des machines autonomes.
Ceci a un impact sur le minimum de machines requis pour créer le système de fichiers distribués, sur la souplesse de retrait et d’ajout de machine, sur les performances, la maintenance et la sauvegarde.
Ce tutoriel couvre les systèmes de fichiers suivants :
- GlusterFS ;
- OCFS2 couplé à DRBD ;
- Ceph ;
- Minio.
En réalité, OCFS2 (Oracle Cluster File System) n'est pas un système de fichiers distribué, mais un système de fichiers gérant la concurrence d'accès aux fichiers entre plusieurs machines. Cela permet de gérer les accès concurrentiels, la répartition de charge sur plusieurs machines (deux dans notre cas) sera à gérer à part. C'est une approche intéressante pour un petit cloud.
Ceph, à son niveau le plus bas, va stocker des objets (des couples de clé/valeur). Un cache d'abstraction nommée RBD (Rados Block Device) fournira un accès en mode bloc. Par-dessus cela, CephFS fournira une abstraction permettant l'accès en mode fichier.
1-1. NFS▲
NFS n'est pas en lui-même un système de fichiers répartis. Du point de vue utilisateur, vous pouvez le comparer à SMB : c'est un point d'exposition d'un système plus bas niveau pouvant lui être réparti. Pourquoi en parler ici alors ? Car certains systèmes de fichiers répartis comme GlusterFS – que nous allons voir dans le prochain chapitre – implémentent directement un accès NFS.
NFS (Network file System) est un protocole historique de partage réseau sous Unix. Les anciennes versions n'étaient pas sécurisées.
Sur les anciennes versions de NFS, avec un serveur NFS installé, pour partager un dossier, il suffisait d'ajouter une entrée dans le fichier /,etc/exports comme ceci :
/dossier_partage 192
.168
.1
.0
/24
(
rw)
pour permettre à toutes les machines du réseau 192.168.1.0 de se connecter au partage en lecture/écriture.
NFS fait un contrôle d'accès au niveau de l'hôte, pas du nom d'utilisateur.
L'accès client se fera soit par la commande mount, soit par une entrée dans le fichier /,etc/fstab comme ceci :
adresse_ip:/partage /point_de_montage nfs user,noauto 0
0
La version 4 a créé une réelle rupture permettant :
- la sécurisation et le chiffrement des communications (support de Kerberos) ;
- délégation de la gestion d'un document en local pour un client ;
- Migration possible d'une machine à l'autre du serveur de façon transparent pour le client.
Les systèmes Linux, Mac OS, Windows (seulement la version Pro, pour les versions home, il faut utiliser un logiciel externe) intègrent nativement un client NFS.
Mac OS, Linux, la plupart des NAS intègrent un serveur NFS (bien qu'en général on va plutôt utiliser un partage SMB). Windows Server intègre également un rôle serveur NFS.
VMWare permet de stocker ses machines virtuelles dans un partage NFS, ce sera par contre moins efficace qu'avec le filesystem VMFS natif, mais permettra par contre de facilement créer un stockage partagé.
Un volume GlusterFS, que nous verrons dans le prochain chapitre peut être monté en NFS.
1-2. GlusterFS▲
GlusterFS est un système de fichiers distribué relativement souple. Il vient se greffer sur le système de fichiers local existant. Il permet de facilement « concaténer » plusieurs volumes locaux de plusieurs machines en un seul volume. Il possède plusieurs modes (distribués ou non) de fonctionnement. Certains d’entre eux permettent la redondance. C'est un système relativement simple à mettre en place et efficace. Voici une explication des modes de fonctionnement.
Mode répliqué
Ce mode de fonctionnement réplique les fichiers sur les différents nœuds du volume. Il s'agit là uniquement de l'aspect redondance, les fichiers ne sont pas répartis sur les différentes machines, ils sont répliqués.
Mode distribué
Dans ce mode, les fichiers sont répartis entre les différentes machines du volume. Il n'y a pas de redondance. Vous devez donc vous assurer de la sauvegarde des données.
Mode distribué-répliqué
Ce mode cumule la répartition et la redondance. Chaque nœud du volume distribué est redondé sur une autre machine. Il vous faut donc au minimum X machines multiplié par 2 pour un volume consistant, X représentant le nombre de nœuds répartis.
Autres modes possibles
Volumes strippés : les fichiers sont éclatés en plusieurs morceaux, ceux-ci étant répartis sur les machines membres du volume. Ce mode pourrait être comparé à du RAID 0 via le réseau.
Volumes strippés distribués : les fichiers sont éclatés en plusieurs morceaux comme pour les volumes strippés, mais sont répliqués sur plusieurs machines. Ce mode peut être comparé à du RAID 0+1 (encapsulation de RAID 0 dans un RAID 1) via le réseau.
Volumes dispersés : les fichiers sont morcelés sur plusieurs machines avec des fragments supplémentaires permettant la reconstruction de fichiers suite à une perte de fragments présents sur une machine en panne. Ce fonctionnement est comparable à du RAID 5 via le réseau.
Volumes dispersés distribués : il s'agit de volumes distribués répliqués utilisant des sous-volumes dispersés plutôt que répliqués.
GlusterFS utilise la nomenclature suivante :
- pool de machines : machines qui sont appairées pour gérer un ou plusieurs volumes en commun ;
- brique : une brique est un point de stockage sur une machine d'un pool. Plusieurs briques font un volume.
1-2-1. Installation de GlusterFS▲
Pour créer un volume GlusterFS, il faut installer les paquets glusterfs-server et attr :
apt-get install glusterfs-server attr
Votre système de fichiers doit supporter les attributs étendus. C'est le cas pour ext4.
1-2-2. Installation mode répliqué▲
Une fois les paquets GlusterFS installés sur srv1, nous créons un dossier à la racine que nous nommons srv1_data et qui accueillera le point de partage.
Nous créons ensuite le volume que nous nommerons VOL :
gluster volume create VOL srv1:/data_srv1 force
La commande retourne l’indication suivante :
volume create: VOL: success: please start the volume to access data
Option force : GlusterFS exige ce paramètre au cas où le point de montage utilisé pour le volume est dans la partition principale (ce que GlusterFS ne recommande pas).
La commande gluster volume list permet l'affichage des volumes visibles sur le système :
root@srv1:~# gluster volume list
VOL
root@srv1:~#
Nous pouvons voir l'état du volume avec la commande gluster volume info :
gluster volume info
Volume Name: VOL
Type: Distribute
Volume ID: 3fa199d1-7e7f-4ec5-985f-abf0f1f18ed4
Status: Created
Snapshot Count: 0
Number of Bricks: 1
Transport-type: tcp
Bricks:
Brick1: srv1:/data_srv1
Options Reconfigured:
transport.address-family: inet
performance.readdir-ahead: on
nfs.disable: on
Nous pouvons voir que le volume est en mode distribué (distribute), avec une seule brique.
Une fois le volume créé, il nous faut l'activer :
root@srv1:~# gluster volume start VOL
volume start: VOL: success.
À ce stade, le volume est montable, mais nous verrons cela dans le prochain chapitre.
Une fois les paquets installés sur srv2 et le dossier du point de montage créé, nous commençons par effectuer le jumelage GlusterFS de srv2 à srv1 depuis srv1 .
root@srv1:~# gluster peer probe srv2
peer probe : success
La commande suivante permet de voir les machines membres du pool :
root@srv1:~# gluster pool list
Et qui donnera un résultat comme ceci :
root@srv1:~# gluster pool list
UUID Hostname State
bca2bdf3-ec7e-4e26-8d5e-01584b09d604 srv2 Connected
ffaa8716-0a58-4cea-b01d-70f49bcbe998 localhost Connected
Les fichiers /,etc/hosts de chaque machine doivent contenir les noms des nœuds participant aux volumes GlusterFS.
La même commande exécutée sur la seconde machine donnera le même résultat, les deux lignes seront juste interverties.
Nous ajoutons ensuite la brique de srv2 au volume :
gluster volume add-brick VOL replica 2
srv2:/data_srv2 force
volume add-brick: success
Nous affichons les informations du volume :
gluster volume info
Volume Name: VOL
Type: Replicate
Volume ID: 3fa199d1-7e7f-4ec5-985f-abf0f1f18ed4
Status: Started
Snapshot Count: 0
Number of Bricks: 1
x 2
=
2
Transport-type: tcp
Bricks:
Brick1: srv1:/data_srv1
Brick2: srv2:/data_srv2
Options Reconfigured:
nfs.disable: on
performance.readdir-ahead: on
transport.address-family: inet
Nous pouvons voir les deux briques et pouvons voir que le type de réplication est maintenant « replicate ».
Nous aurions pu également créer le volume comme ceci à partir du moment où Gluster était installé sur les deux postes et les deux machines jumelées :
root@srv1:~# gluster create volume VOL replica 2 srv1:/data_srv1 srv2:/data_srv1 force
volume create: VOL; success: please start volume to access data
Voici le détail des paramètres passés à la commande gluster create volume :
- VOL : nom du volume créé ;
- replica : nombre de machines nécessaires au volume répliqué (deux minimum) ;
- srv1:/data_srv1 : srv1 correspond au nom de la machine, /data_srv1 correspond au point de montage/dossier contenant les données du volume. Le nom de la machine et le chemin sont séparés par le caractère : ;
- srv2:/data_srv2: srv2 correspond au nom de la machine, /data_srv2 correspond au point de montage/dossier contenant les données du volume. Le nom de la machine et le chemin sont séparés par le caractère :.
Pour que la réplication fonctionne, il ne faut pas accéder au contenu directement depuis les dossiers /data_srv1 ou /data_srv2 dans notre exemple, mais depuis un point de montage GlusterFS.
1-2-2-1. Montage d'un volume gluster▲
Pour monter un volume gluster, vous aurez besoin du paquet glusterfs-client. Si vous souhaitez monter un volume gluster sur une machine faisant office de serveur gluster, vous n'en aurez pas besoin, le paquet glusterfs-client étant installé en même temps que glusterfs-server.
Le montage s’effectue de la même façon que pour tout autre type de volume :
# mount -t glusterfs [nom d'hôte ou adresse IP]:/[nom du volume] [point de montage]
Ou dans le /etc/fstab sur srv1 par exemple :
srv1:/VOL /mnt glusterfs defaults,_netdev 0
0
Il est possible de monter un volume gluster via NFS. Cela n'est pas recommandé, car la sécurité de NFS, notamment en troisième version est rudimentaire.
1-2-2-2. Ajout d'une machine supplémentaire au pool▲
Dans notre exemple, le serveur supplémentaire sera nommé srv3.
Lors de l’ajout d’une machine au pool, il ne faut pas oublier d’ajouter la nouvelle machine au fichier /,etc/hosts des machines déjà existantes ou s'assurer que l'entrée soit présente dans les DNS utilisés.
La commande suivante ajoute srv3 au pool :
root@srv1:~#gluster peer probe srv3
Nous ajoutons ensuite la nouvelle machine :
gluster volume add-brick VOL replica 3
srv3:/data_srv3 force
Il faut passer le bon nombre de machines à l'option replica.
Si nous appelons la commande gluster volume info, nous pouvons constater que le nombre de briques est passé de 1 x 2 = 2 à 1 x 3 = 3.
1-2-2-2-1. Mise à jour de srv3▲
Une fois la brique intégrée, aucune donnée n'est automatiquement répliquée dessus. À ce stade, si nous ajoutons un nouveau fichier au volume, une copie sera bien présente dans srv3, mais les anciens fichiers ne le seront pas. Pour pallier ceci, il faut lancer la commande suivante :
gluster volume heal VOL full
1-2-2-3. Retrait d'une brique▲
Dans notre cas, nous allons retirer srv2 avec la commande suivante :
gluster volume remove-brick VOL replica 2
srv2:/data_srv2 force
La commande demande confirmation avant de procéder au retrait.
replica doit être égal au nombre final de briques après opération.
Dans notre cas où les volumes sont répliqués, il est possible de diminuer le nombre de volumes jusqu’à n’en garder plus qu’un. Le volume dans ce cas passera en mode distribué.
Le retrait de la brique du volume ne supprime pas les données de celle-ci, mais il n'y a plus aucun lien entre celles-ci et le volume. Il ne sera pas possible de réintégrer la brique telle quelle.
Si vous souhaitez retirer la machine du pool :
gluster peer detach srv2
1-2-3. Test de mise en panne, simulation perte de srv1▲
L'arrêt de srv1 ne provoque aucune erreur. Comme nous avons appairé srv2 à srv1, nous pouvons voir l'état de la connexion (et donc sa perte) avec la commande :
root@srv1:~# gluster peer status
Number of Peers: 1
Hostname: srv1
Uuid: c0c487b3-1135
-41c7-b160-b8a061c10e9d
State: Peer in
Cluster (
Disconnected)
Si vous souhaitez garder l'adresse IP de la machine perdue, la reconnexion est plus complexe.
1-2-3-1. Remplacement avec une nouvelle adresse IP▲
Nous appairons le nouveau serveur :
root@srv2:~# gluster peer probe srv1
Nous remplaçons ensuite la brique :
root@srv2:~# gluster volume replace-brick VOL srv1:/data_srv1 [nouvelle ip/hote]/data commit force
Pour que les machines se synchronisent, il faut ensuite lancer la commande :
gluster volume heal VOL full
1-2-3-2. Remplacement en gardant la même adresse IP▲
Il faut d'abord retirer la brique défectueuse :
root@srv2:~# gluster volume remove-brick VOL srv1:/data_srv1 force
Removing brick
(
s) can result in
data loss. Do
you want to continue
? (
y/n) y
volume remove brick commit force:success
Puis :
root@srv2:~# gluster peer detach srv1
peer detach: success
À ce stade, et comme déjà vu, le volume ne contenant plus qu'une seule brique, passe en mode distribué.
Une fois le nouveau serveur préparé, nous le réappairons :
root@srv2:~# gluster peer probe srv1
Nous ajoutons la nouvelle brique :
root@srv2:~# gluster volume add-brick VOL replica2 srv1:/data_srv1 force
Nous resynchronisons le volume :
gluster volume heal VOL full
Launching heal operation to perform full self heal on volume VOL has been successful
Use heal info commands to check status
Comme indiqué, nous pouvons voir le résultat avec la commande :
gluster volume heal info
Si vous rencontrez des difficultés, consultez le chapitre 1.3.5.1Ajout d’une troisième machine pour la sauvegarde.
1-2-4. Installation en mode distribué▲
Certaines notions sont identiques ou de simples variantes du mode répliqué. Il est important pour la suite d'avoir lu le chapitre précédent.
Nous préparons une machine srv1 qui contiendra le fichier fichier1.txt dans /data_srv1.
Nous y créons un volume avec une brique unique.
gluster volume create VOL srv1:/data_srv1 force
volume create: VOL: success: please start volume to access data
Nous pouvons voir l'état du volume avec la commande gluster volume info :
root@srv1:~# gluster volume info
Volume Name: VOL
Type: Distribute
Volume ID: 3f0a379a-921a-4c63-a5cc-7a62c3c39d19
Status: Created
Number of Bricks: 1
Transport-type: tcp
Bricks:
Brick1: srv1:/data_srv1
Nous pouvons constater que le volume est en mode distribué (distribute)
Démarrons ensuite le volume :
root@srv1:~# gluster volume start VOL
Nous préparons ensuite un serveur srv2 avec le fichier /data_srv2/fichier2.txt. Il nous faut appairer la nouvelle machine :
root@srv1:~# gluster peer probe srv2
Puis ajouter la nouvelle brique :
root@srv1:~# gluster volume add-brick VOL srv2:/data_srv2
volume add-brick: success
Nous pouvons voir le nouvel état du volume :
root@srv1:~# gluster volume info
Volume Name: VOL
Type: Distribute
Volume ID: 3f0a379a-921a-4c63-a5cc-7a62c3c39d19
Status: Started
Number of Bricks: 2
Transport-type: tcp
Bricks:
Brick1: srv1:/data_srv1
Brick2: srv2:/data_srv2
Si nous montons le volume, nous pourrons voir les deux fichiers fichier1.txt et fichier2.txt. L'arrêt d'une des deux machines fera disparaître les fichiers présents dans le nœud coupé. Le premier accès sera lent, gluster cherchant la machine manquante. Le volume continue de fonctionner, il reste possible d'ajouter des fichiers. Le redémarrage de la machine manquante fera instantanément réapparaître les fichiers inaccessibles.
Créez quelques fichiers pour tester le comportement. J'ai créé plusieurs fichiers nommés fichier3.txt, fichier4.txt, etc. Tous restant dans /data-srv1.
Gluster gère cela lui-même et du point de vue extérieur, cela n'a pas d'importance pour l'accès. Lisez cette partie de la documentation pour plus d'informations.
Il est possible de changer la répartition avec la commande rebalance :
gluster volume rebalance VOL start
Selon le volume de données à traiter, la répartition peut prendre du temps. Il est possible de voir l'état de celle-ci via la commande :
gluster volume rebalance VOL status
J'ai pu constater que certains fichiers apparaissent en doublon dans les dossiers contenant les briques, ceux-ci restant uniques dans le point de montage GlusterFS. Je présume que gluster est suffisamment intelligent pour les conserver tant qu'il y a de la place.
Rappel : si vous insérez un fichier dans un dossier faisant partie d'un volume gluster sans passer par le point de montage gluster, celui-ci n’apparaîtra pas dans le volume et ne sera ni répliqué, ni distribué.
1-2-5. Test du mode distribué-répliqué▲
Pour ce mode, je vais repartir sur la configuration précédente : deux machines en mode distribué que je vais passer en mode distribué-répliqué.
Je vais rajouter deux machines supplémentaires aux deux machines déjà présentes de façon à ce que chacune soit répliquée.
Une fois les deux serveurs supplémentaires préparés et appairés, je les intègre au volume :
gluster peer probe srv3
gluster peer probe srv4
gluster volume add-brick VOL replica 2
srv3:/data_srv3 srv4:/data_srv4 force
Nous obtenons le résultat suivant :
Volume Name: VOL
Type: Distributed-Replicate
Volume ID: 8f4d1305-7f28-41eb-bc76-85132c009c51
Status: Started
Number of Bricks: 2
x 2
=
4
Transport-type: tcp
Bricks:
Brick1: srv1:/data_srv1
Brick2: srv3:/data_srv3
Brick3: srv2:/data_srv2
Brick4: srv4:/data_srv4
L'ajout d'un fichier dans le point de montage du volume GlusterFS, point de montage depuis srv1 et donc création du fichier depuis srv1 va générer l'ajout de celui-ci dans /data_srv2 et /data_srv4. Nous avons donc bien la réplication ainsi que la distribution répartie.
Seuls les nouveaux fichiers ou fichiers modifiés après l'ajout des briques bénéficieront de la réplication.
Pour que tous les fichiers soient répliqués, il faudra exécuter la commande rebalance comme vu précédemment.
gluster volume rebalance VOL start
La répartition devient donc :
- srv1 : fichier1.txt, fichier2.txt ;
- srv2 : fichier2.txt, fichier3.txt ;
- srv3 : fichier2.txt ;
- srv4 : fichier2.txt, fichier3.txt ;
Chaque fichier est donc bien répliqué.
1-2-5-1. Simulation de perte de srv2▲
La manipulation la plus simple est de préparer une nouvelle machine, de lui affecter une nouvelle adresse IP, de l'appairer et d'utiliser replace-brick comme vu précédemment.
Si vous souhaitez garder la même IP, il va falloir effectuer plusieurs opérations.
La difficulté ici est qu'un nouveau serveur n'aura pas le même UUID. Il y aura donc des manipulations supplémentaires à effectuer une fois le serveur préparé.
Il va nous falloir récupérer l'ancien UUID de srv2 :
root@srv1:~# grep -r uuid= /var/lib/glusterd/peers/* >fichier.txt
Uniquement valable si votre dossier ne contient qu'un seul fichier /var/lib/glusterd/peers/. Si ce n'est pas le cas, il faut identifier celui-ci et exécuter :
grep uuid= /var/lib/glusterd/peers/[nom du fichier contenant hostname=srv1] >fichier.txt
Nous transférerons ensuite cet UUID sur le nouvel srv2. Nous insérons ensuite cet UUID dans /var/lib/glusterd/glustered :
cat fichier.txt >>
/var/lib/glusterd/glusterd.info
Nous éditons le fichier afin de fixer l'UUID, puis redémarrons le service :
/etc/init.d/glusterfs-server restart
Nous appairons ensuite le serveur :
root@srv2:~# gluster peer probe srv1
Nous redémarrons le service en appelant la commande gluster pool list, vous verrez les deux machines connectées.
Il faut ensuite synchroniser les volumes.
Depuis srv2, la commande gluster volume status vous retournera :
No volumes present
Nous synchronisons les volumes avec la commande ;
root@srv1:~# gluster volume sync srv2 all
sync volume may data inaccessible while
the sync is in
progress. Do
you want to continue
? (
y/n)
volume sync success.
À ce stade, les données ne sont pas encore synchronisées.
Mises à jour des métadonnées
Il va nous falloir mettre à jour les métadonnées sur le nouveau serveur depuis un serveur actif.
root@srv1:~# getfattr -n trusted.glusterfs.volume-id /data_srv1
getfattr:suppression des « / »en tête des chemins absolus
# file: data_srv2/
trusted.glusterfs.volume-id
=
0s8VVsv3xRTa6G41mE+5E1dA
==
Il va falloir appliquer le volume id sur srv2 avec la commande :
setfattr -n trusted.glusterfs.volume-id -v '0s8VVsv3xRTa6G41mE+5E1dA=='
/data_srv2
Nous redémarrons ensuite le service et depuis srv1, nous exécutons :
gluster volume heal VOL full
1-2-6. Sauvegarder/restaurer▲
Il me parait indispensable d'avoir une sauvegarde hors ligne même en cas de système répliqué, ceci afin de se protéger de cryptolocker ou d’un effacement involontaire de fichiers. L'idéal sera une sauvegarde en ligne sur la même infrastructure, afin d'avoir une sauvegarde/restauration régulière rapide, doublé par une sauvegarde hors ligne moins fréquente.
1-2-7. Sécurité▲
Les serveurs faisant partie d'un pool gluster, ils se reconnaissent via leur UUID. Pour qu'un serveur fasse partie d'un pool, il doit être intégré par un serveur du pool (c'est la commande gluster peer probe que nous avons déjà vue).
Par défaut, n'importe quel client peut se connecter à un volume gluster. Il est possible de restreindre l'accès à certaines IP via la commande :
gluster volume set VOL auth.allow [adresse IP 1
],[adresse IP 2
]
Par défaut, le dialogue s'effectue en clair. Il est possible d'établir un dialogue SSL/TLS (documentation ici), celui-ci gérant l'authentification et le cryptage, mais pas l'autorisation. La sécurisation peut bien sûr se faire via un tunnel VPN, l'authentification et le cryptage étant alors délégué au tunnel VPN.
Comme il n'y a pas de login/mot de passe, il ne faut pas exposer directement un point de montage gluster aux utilisateurs. Par exemple, ce point de montage peut-être partagé en SMB. C'est le serveur SMB (point d'entrée exposé) qui s’occupera alors des autorisations d'accès.
1-3. DRBD/OCFS2▲
Nous allons ici cumuler l'utilisation de DRBD avec OCFS, DRBD s'occupant de la réplication, OCFS de l'accès concurrentiel.
1-3-1. DRBD▲
1-3-1-1. Qu'est-ce que DRBD ?▲
DRBD : Distributed Replicated Block Device permet la réplication de périphériques bloc entre serveurs via le réseau. Il peut être assimilé à du RAID 1 over IP.
Par défaut, DRBD utilise la notion de primaire/secondaire. Un système de fichiers ne peut être monté que depuis une machine primaire. La machine primaire transmet les modifications à la machine secondaire. Une machine en mode secondaire ne peut pas être utilisée de façon à garder la cohérence du cache.
Nous utiliserons un mode permettant d'avoir deux machines primaires et donc pouvoir faire des lectures/écritures depuis les deux nœuds.
1-3-2. Installation de DRBD▲
La version utilisée ici sera la version 8.
L'installation se fait simplement par :
apt-get install drbd-utils
Il va falloir effectuer la configuration du nœud primaire et du nœud secondaire. Nous devons donc préparer un fichier de configuration en conséquence.
DRBD va utiliser une partition en tant que périphérique bloc sur chaque nœud.
Une partition doit être mise à disposition. Utiliser une partition avec DRBD va écraser son contenu.
Le fichier de configuration suivant, nommé r0.res et placé dans /,etc/drbd.d permet d’utiliser les nœuds accessibles en 192.168.8.1 et 192.168.8.2. Sur chacun d'eux, nous utiliserons la partition /dev/sdb1. Ce fichier sera à adapter à votre cas.
resource r0 {
syncer {
rate 100M;
}
on srv1 {
device /dev/drbd0;
disk /dev/sdb1;
address 192
.168
.8
.1
:7789;
meta-disk internal;
}
on srv2 {
device /dev/drbd0;
disk /dev/sdb1;
address 192
.168
.8
.2
:7789;
meta-disk internal;
}
}
Un fichier de définition de ressource DRBD doit avoir l'extension .res
Les noms de machines utilisés avec la directive « on »
doivent correspondre aux noms des machines retournés par la commande hostname.
Ce fichier devra être recopié sur le second nœud.
Le fichier est relativement simple à comprendre. Nous créons un volume DRBD accessible depuis /dev/drbd0 sur chaque nœud.
Nous créons ensuite le volume sur le nœud primaire :
# drbdadm create-md r0
initialising activiy log
NOT initialializing bitrmap
Writing meta data …
New dbrd meta data block successfully created.
Nous activons ensuite celui-ci :
# drbdadm up r0
Nous pouvons observer le résultat avec la commande drbd-overview :
# drbd-overview
0
:r0/0
WFConnexion Secondary/Unknown Inconsistent/DUnknown
Il faut effectuer ces commandes sur les deux nœuds. Pour le second nœud, la commande drbd-overview donne :
0
:r0/0
Connected Secondary/Primary Inconsistent/ Inconsistent
Nous voyons que la connexion est effectuée, mais que le « RAID » DRBD est inconsistant.
Nous lançons ensuite la synchronisation uniquement depuis le poste maitre (192.168.8.1 ou srv1), nous passons également le nœud en primaire :
drbdadm -- --overwrite-data-of-peer primary r0
Nous pouvons voir l'évolution de la synchronisation depuis le fichier /proc/drbd ou depuis la commande drbd-overview :
version: 8
.4
.3
(
api:1
/proto:86
-101
)
srcversion: 6681A7B41C129CD2CE0624F
0
: cs:SyncSource ro:Primary/Secondary ds:UpToDate/Inconsistent C r-----
ns:417288
nr:0
dw:0
dr:418200
al:0
bm:25
lo:0
pe:0
ua:0
ap:0
ep:1
wo:f oos:7970004
[>
...................] sync'ed: 5.1% (7780/8188)Mfinish: 0:05:05 speed: 26,080 (26,080) K/sec
Une fois la synchronisation terminée, nous allons passer le second nœud en primaire. Pour cela, nous ajoutons les lignes suivantes dans le bloc ressources du fichier de configuration r0 :
net {
allow-two-primaries;
after-sb-0pri discard-zero-changes;
after-sb-1pri discard-secondary;
}
startup {
become-primary-on both;
}
Le fichier devient :
resource r0 {
syncer {
rate 100M;
}
net {
allow-two-primaries yes;
after-sb-0pri discard-zero-changes;
after-sb-1pri discard-secondary;
}
startup {
become-primary-on both;
}
on srv1 {
device /dev/drbd0;
disk /dev/sdb1;
address 192
.168
.8
.1
:7789
:
meta-disk internal;
}
on srv2 {
device /dev/drbd0;
disk /dev/sdb1;
address 192
.168
.8
.2
:7789
:
meta-disk internal;
}
}
En détails, voici les nouvelles fonctions utilisées :
- allow-two-primaries : permet d'utiliser deux nœuds en mode primaire ;
- after-sb-0pri discard-zero-changes : en cas de split-brain, et que les deux nœuds sont considérés comme primaires, DRBD va prendre les modifications les plus récentes et les appliquer à l'autre nœud ;
- after-sb-1pri discard-secondary : en cas de split-brain avec un nœud primaire et un secondaire, le primaire écrasera les modifications sur le secondaire ;
- after-sb-2pri disconnect (non utilisé) : en cas de split-brain, DRBD déconnecte les volumes et le réglage du problème (et la décision du nœud où il faut sacrifier les différences) doit être fait manuellement.
Pensez à faire une copie du fichier de configuration avant modification pour pouvoir revenir à la situation initiale en cas de problème.
Nous recopions le fichier sur le second nœud et redémarrons le service DRBD sur les deux machines.
Nous pouvons vérifier l'état sur les deux serveurs avec :
# cat /proc/drbd
version: 8
.4
.3
(
api:1
/proto:86
-101
)
srcversion: 1A9F77B1CA5FF92235C2213
0
: cs:Connected ro:Primary/Primary ds:UpToDate/Diskless C r-----
ns:912
nr:0
dw:0
dr:1824
al:0
bm:0
lo:0
pe:0
ua:0
ap:0
ep:1
wo:f oos:8387292
Rappel : Il n'est pas possible de monter un système de fichiers dans un volume DRBD en mode secondaire.
1-3-2-1. Sécurité de DRBD▲
Il est possible de sécuriser les dialogues DRBD en ajoutant les éléments suivant dans le fichier de configuration :
net {
cram-hmac-alg "sha1"
;
secret "le mot de passe"
;
}
Un transfert via une connexion sécurisée entre les nœuds hors DRBD peut aussi être utilisé. (interconnexion via cartes réseau dédiées hors réseau normal, VPN).
1-3-2-2. Surveillance des volumes DRBD▲
DRBD est fourni avec un système de handlers et des scripts pour gérer les problèmes. Par exemple, la mise en place d’une notification par mail lors d’un split-brain s’effectue en ajoutant ce qui suit dans la section resources :
handlers {
split-brain "/usr/lib/drbd/notify-split-brain.sh <adresse>"
;
...
}
Je vous invite à regarder les différents scripts à disposition dans /usr/lib/drbd.
1-3-2-3. Tests▲
Une fois la synchronisation effectuée, nous créons ensuite un système de fichiers sur /dev/drbd0 :
mkfs.ext4 /dev/drbd0
Quelle que soit la machine, le système de fichiers sera présent sur l'autre, le volume DRBD étant répliqué.
Nous y créons un fichier de test fichier1.txt après montage du volume DRBD dans un point de montage.
Nous montons ensuite /dev/drbd0 sur la seconde machine (srv2), nous voyons bien le fichier fichier1.txt.
Nous ajoutons un fichier fichier2.txt depuis srv2, celui-ci n’apparaît pas sur srv1.
Nous démontons et remontons le volume sur srv1, Après remontage, nous voyons bien le second fichier.
Explications
DRBD travaille au niveau bloc et non au niveau du système de fichiers. Nous pouvons l'utiliser tel quel en tant que sauvegarde, mais pas pour un double montage. Le monter simultanément risque de provoquer une inconsistance au niveau du système de fichiers.
Pour pallier ceci, nous allons utiliser OCFS2, un système de fichiers permettant les accès concurrents.
1-3-3. OCFS2▲
1-3-3-1. Qu'est-ce qu'OCFS2 ?▲
OCFS2 (Oracle Cluster File System) est un système de fichiers sous licence GPL qui permet l'accès concurrent à des fichiers, c'est-à-dire un accès simultané possible en lecture/écriture à un fichier sans risque d’inconsistance. Ceci nous permettra de résoudre le problème vu dans le chapitre précédent.
1-3-3-2. Installation et paramétrage d'OCFS2▲
Pour installer OCFS2, il faut installer le paquet comme ci-dessous :
apt-get install ocfs2-tools
Nous créons le système de fichiers ocfs sur le volume DRBD :
mkfs -t ocfs2 -L MYCLOUD /dev/drbd0
Avec en options :
- -L : le nom du volume OCFS2.
La configuration s'effectue via les commandes suivantes.
Création du cluster que nous nommerons « MYCLOUD » :
o2cb add-cluster MYCLOUD
Ajout des nœuds :
o2cb add-node MYCLOUD --ip 192
.168
.8
.1
--port 7777
--number 0
srv1
o2cb add-node MYCLOUD --ip 192
.168
.8
.2
--port 7777
--number 1
srv2
Ce qui nous donnera La configuration suivante dans le fichier /etc/ocfs2/cluster.conf :
cluster:
heartbeat_mode =
local
node_count =
2
name =
MYCLOUD
node:
number =
0
cluster =
MYCLOUD
ip_port =
7777
ip_address =
192
.168
.8
.1
name =
srv1
node:
number =
1
cluster =
MYCLOUD
ip_port =
7777
ip_address =
192
.168
.8
.2
name =
srv2
Afin de modifier la configuration au démarrage, nous lançons :
dpkg-reconfigure ocfs2-tools
Après un redémarrage de la machine, ou plus simplement des services o2cb et ocfs2, il suffit de monter le volume :
mount -t ocfs2 /dev/drbd0 /data
ou grâce au fichier fstab :
/dev/drbd0 /data ocfs2 _netdev 0
0
Pour avoir accès aux données sur la seconde machine, il faudra effectuer les mêmes opérations après voir copié le fichier de configuration /etc/ocfs2/cluster.conf.
Les tests depuis les deux postes sont fonctionnels. Le fichier fichier1.txt créé depuis srv1 est visible sur srv2, et le fichier fichier2.txt créé depuis srv2 est visible dans le dossier /data de srv1.
Le montage automatique au redémarrage ne semble pas fonctionnel. Peut-être un problème de configuration.
1-3-4. Couplage DRBD/OCFS2 : Simulation de panne▲
Pour simuler notre panne, nous allons arrêter srv2. Après quelques secondes, l’erreur suivante apparaît sur la console de srv1 :
drbd r0: PingAck did not arrive in
time
De plus, la commande drbd-overview retournera un message similaire à :
0
:r0/0
WFConnection Primary/Unknown UpToDate/DUnknown /data ocfs2 8
.0G 151M 7
.9G 2
%
Le premier accès à la commande drbd-overview va être long.
L'arrêt de srv2 ne perturbe pas le volume /data dans srv1, sauf si celui-ci est redémarré.
Au redémarrage de srv2, j'ai le message suivant dans la console :
A start job is running for
dev-drbd0.device (
36s/1mn 30s)
Comme nous l'avons déjà vu, nous ne pouvons pas monter un volume DRBD en mode Secondary. Le volume OCFS2 n'est pas montable. Une tentative de montage avec mount -a donnera le message suivant :
mount.ocfs2: Device name specified was not found while
opening device /dev/drbd0
Une fois le système démarré, le volume n'est pas disponible. En exécutant la commande drbd-overview, nous pouvons voir :
0
:r0/0
Unconfigured . .
La commande :
drbdadm up r0
Nous retournera :
Marked additional 12
MB as out-of-sync based on AL.
Et le rappel de drbd-overview nous donnera :
0
:r0/0
Connected Secondary/Primary UpToDate/UpToDate
Je redémarre DRBD sur les deux postes avec la commande service drbd restart.
Les deux postes repassent en mode Primary.
Il est alors possible de remonter le volume OCFS2 sur srv2 avec la commande mount -a (et sur srv1).
Nous avons donc une méthode pour redémarrer en mode dégradé.
1-3-5. Couplage DRBD/OCFS2 : redémarrage des deux serveurs▲
Le redémarrage des deux serveurs simultanément nous donnera une situation de split-brain. La commande drbd-overview nous donnera « Unconfigured » sur les deux postes.
Pour avoir accès au volume sur un des postes, il faudra lancer les commandes suivantes :
- drbdadm up r0 ;
- drbdadm primary r0 ;
-
mount -a.
Sur le second poste :
- drbdadm up r0.
À ce stade, le volume DRBD sera consistant avec le mode Primary sur le premier poste, et le mode Secondary sur le second. Un mount -a sur le second nœud réactivera le volume OCFS2.
En cas de perte complète d'un nœud (et non plus un simple arrêt), le volume sera indisponible sur le second nœud tant que la synchronisation n'a pas été refaite. Une fois celle-ci refaite, il sera possible de passer le nœud en Primary et ensuite de monter le volume OCFS2.
1-3-5-1. Ajout d’une troisième machine pour la sauvegarde▲
La version 9 de DRBD permet d’avoir jusqu'à 16 machines. Ce chapitre repose sur la version 8.4 et permet d'empiler deux volumes DRBD. Ce système est appelé stacked et correspond à cette architecture :
|
Nous allons donc mettre en place un serveur srv3 comme serveur de sauvegarde.
Nous ajoutons la nouvelle ressource imbriquée dans /etc/drbd.d/r0.res à la suite de r0 :
resource r1 {
stacked-on-top-of r0 {
device /dev/drbd10;
address 192
.168
.8
.4
:7788;
}
on srv3 {
device /dev/drbd10;
disk /dev/sdb1;
address 192
.168
.1
.3
:7788;
meta-disk internal;
}
}
Vous remarquerez que nous utilisons un port différent, chaque ressource dialoguant sur son propre port.
Nous démontons ensuite le volume sur les deux machines. La commande drbd-overview vous permet de voir si le volume est monté :
0
:0
/r0 Connected Primary/Primary UpToDate/ UpToDate /data ocfs2 63M 13m 51m 20
%
10
:r1/0
^^0
Unconfigured .
Voici le retour lorsque le volume est démonté :
0
:0
/r0 Connected Primary/Primary UpToDate/ UpToDate 11
-dev of: 10
r1/0
10
:r1/0
^^0
Unconfigured .
Nous pouvons voir que le volume r1 n'est pas configuré.
Pour cela il nous faut exécuter les commandes :
drbdadm --stacked create-md r1
md_offset 66015232
al_offset 65982464
bm_offset 65978368
Found some data
==>
This might destroy existing data!
<==
Do
you want to proceeed?
[need to type 'yes'
to confirm]
Il faudra confirmer en tapant « yes », puis vous aurez un message de ce type en retour :
Initializing activity log
NOT initializing bitmap
Writing meta data...
New drbd meta data block successfull created.
Nous tapons ensuite la commande :
drbdadm --stacked up r1
À ce stade, il n'est pas possible de monter le volume.
Comme précisé par le message lors de la commande, effectuer ceci sur un volume existant peut provoquer une perte de données.
Nous copions ensuite la configuration sur srv3, puis créons le volume DRBD dessus :
root@srv3:~# drbdadm create-md r1
initializing activity log
NOT initializing bitmap
Writing meta data...
New drbd meta data block successfully created.
Puis :
drbdadm up r1
Nous invalidons ensuite le contenu de la machine par :
drbdadm invalidate r1
La synchronisation de srv3 se déclenche immédiatement.
Nous activons le mode primaire sur srv1 :
root@srv3:~# drbdadm –stacked primary r1
il faut ensuite monter le volume avec /dev/drbd10 au lieu de /dev/drbd0.
/dev/drbd10 sera le nom de device utilisé pour un volume stacked.
En cas de perte d'une des machines, il faudra appliquer la méthode vue au chapitre 1.3.5.1Ajout d’une troisième machine pour la sauvegarde.
1-3-5-2. Perte de liaison entre deux machines : split-brain▲
Si les deux machines croient que l'autre ne fonctionne plus, vous vous trouverez dans une situation nommée split brain. Dans cette situation, les deux machines passeront en mode standalone avec le statut inconnu :
0
:r0/0
StandAlone Primary/Unknown /data ocfs2 127M 17M 1111M 14
%
Pour régler ce problème, vous devrez en considérer une comme « sacrifiable » et la resynchroniser entièrement à partir de l'autre. Si la situation a perduré un moment, et qu'il y a des différences entre les deux, les différences de la machine sacrifiée seront perdues.
Nous commençons par effectuer un redémarrage des deux machines. À ce stade aucune des deux ne devrait être connectée au volume OCFS2.
Vous pouvez voir un peu plus haut que la commande drbd-overview indique des informations sur le volume monté.
Nous pouvons voir que le volume est monté dans /data. Si aucun volume n'est monté, vous ne verrez que l'information Primary/Unknown (ou Secundary/Unknown).
Nous allons basculer la machine « victime » en secondaire si nécessaire.
Avant ce redémarrage, nous commentons dans le fichier /etc/drbd.d/r0 les lignes concernant la gestion du double primaire.
Après redémarrage. Avec drbd-overview, vous devriez avoir quelque chose comme :
0
:r0/0
WFConnection Secondary/Unknown UpToDate/Unknown
Nous allons ensuite déclarer une des machines comme obsolète, commande à effectuer sur la machine concernée :
drbdadm – --discard-my-data connect r0
La resynchronisation se déclenche. Pendant celle-ci, vous pouvez basculer la machine servant de source en primaire et remonter le volume OCFS.
Une fois la synchronisation terminée, nous décommentons les lignes concernant l'utilisation de deux machines primaires et redémarrons le service sur les machines une à une.
1-3-6. DRBD 9▲
DRBD 9 permet d'utiliser LVM comme conteneur de volume. Il permet aussi d'avoir jusqu'à 16 nœuds par ressource sans devoir recourir à l'empilement comme vu avec la version 8.4. La version fournie avec Debian 9 étant la 8,4, il va falloir compiler :
- le module noyau ;
- les outils drbd (drbd-utils).
Avant de commencer, nous installerons LVM (apt-get install lvm2).
1-3-6-1. Installation du module noyau :▲
Commençons par télécharger les sources du module :
wget https://www.linbit.com/downloads/drbd/9
.0
/drbd-9
.0
.19
-1
.tar.gz
Je n'ai pas pris la dernière version pour des questions de soucis de compilation sur Debian 9 utilisé (Debian 9 étant une ancienne version maintenant).
Les liens de téléchargements peuvent changer avec le temps et devront donc être adaptés
Décompression :
gunzip drbd-9
.0
.19
-1
.tar.gz
Désarchivage :
tar -xvf drbd-9
.0
.19
-1
.tar
La compilation se fera avec la commande make dans le dossier décompressé. Les prérequis sont make bien sûr, et les en-têtes de votre noyau (installable avec la commande apt-get install linux-headers-$(uname -r)).
Une fois la compilation effectuée, l'installation se fera par :
make install
1-3-6-2. Installation des outils ▲
wget https://www.linbit.com/downloads/drbd/utils/drbd-utils-9
.13
.1
.tar.gz
gunzip drbd-utils-9
.13
.1
.tar.gz
tar -xvf drbd-utils-9
.13
.1
.tar
Les prérequis avant compilation seront gcc, flex, xlstproc (pour la documentation). La compilation se fera ensuite par :
./configure
make
À la fin de la compilation, j'ai eu le message d'erreur suivant :
Makefile:108
: la recette pour la cible « doc » a échoué
Cela n’empêche pas le make install.
Nous faisons ensuite l'installation :
make install
1-3-6-3. Préparation du volume LVM▲
Nous commençons par préparer la partition à l'usage de LVM (dans notre cas sdb1) :
pvcreate /dev/sdb1
Nous créons ensuite un volume Group que nous appellerons vg01 :
vgcreate vg01 /dev/sdb1
Et créons enfin le volume logique lv01 (volume de 1900 Mo sur un disque de 2 Go pour l'essai) :
lvcreate -L 1900
-n lv01 vg01
Nous créons ensuite un fichier de configuration dans un premier temps avec une machine unique :
resource r0 {
protocol C;
on srv1 {
disk /dev/vg01/lv01;
device /dev/drbd0;
address 192
.168
.1
.201
:7789;
meta-disk internal;
node-id 0;
}
}
Comme nous utilisons une version compilée de DRBD, les fichiers de configuration devront être placés dans /usr/local/,etc/drbd.d au lieu de /,etc/drbd.d.
Remarquez la présence de l'option node-id 0;. Cette option, apparue avec DRBD 9 permet de numéroter chaque nœud participant au cluster.
La procédure sera ensuite la même que pour la version 8.4.
Création des métadonnées sur le volume :
drbdadm create-md r0
Activation du volume :
drbdadm up r0
À ce stade, nous pouvons voir l'état du volume avec la commande drbdadm status, qui remplace drbd-overview :
~# drbdadm status
r0 role:Secondary
disk:Inconsistent
Nous allons ensuite passer celui-ci en primaire. La syntaxe a été simplifiée par rapport aux versions précédentes :
drbdadm primary r0 --force
Résultat de drbdadm status :
# drbdadm status
r0 role:Primary
disk:UpToDate
Nous modifions le fichier de configuration pour intégrer la seconde machine :
resource r0 {
protocol C;
on srv1 {
disk /dev/vg01/lv01;
device /dev/drbd0;
address 192
.168
.1
.201
:7789;
meta-disk internal;
node-id 0;
}
on srv2 {
disk /dev/vg01/lv01;
device /dev/drbd0;
address 192
.168
.1
.202
:7789;
meta-disk internal;
node-id 1;
}
}
Rappel : la valeur node-id doit être unique à chaque nœud.
Une fois le fichier mis à jour, la commande suivante permet de prendre en compte les changements :
drbdadm adjust r0
La commande drbdadm status nous montre l'attente de connexion pour srv2 non encore préparé.
~# drbdadm status
r0 role:Primary
disk:UpToDate
srv2 connection:Connecting
Reste à préparer srv2. La copie des dossiers source depuis srv1 permettra d'installer le module noyau DRBD avec make install sans devoir recompiler (le module .ko compilé sur srv1 étant dans le dossier des sources copié). Pour les outils, il faudra réexecuter ./configure, puis make et make install. Restera à copier le fichier de configuration.
Une fois le volume LVM créé, les métadonnées DRBD créées (avec drbdadm create-md r0), le lancement de la commande drbdadm up r0 déclenchera la synchronisation. Ci-dessous la synchronisation en cours :
~# drbdadm status
r0 role:Primary
disk:UpToDate
srv2 role:Secondary
replication:SyncSource peer-disk:Inconsistent done
:43
.03
Une fois les volumes synchronisés, passer srv2 en primaire ne posera pas de difficultés.
1-3-6-4. Intégration troisième poste▲
Bien que cela soit possible, je n'ai pas réussi à intégrer un troisième poste sans erreur. La documentation manque de précision.
1-3-6-5. drbdmanage▲
drbdmanage est un utilitaire simplifiant la gestion de DRBD. drbdmanage est déprécié et remplacé par linstor. Celui-ci étant toujours disponible sur github, j'ai décidé d'en faire une présentation.
Nous commençons par récupérer les sources :
git clone https://github.com/LINBIT/drbdmanage.git
Prérequis : python-dbus, python-gobject.
Une fois entre dans le dossier, l'installation se fera par :
./setup.py install
La commande drbdmanage sera alors disponible.
drbdmanage attend par défaut la présence d'un volume group LVM nommé drbdpool. Si vous souhaitez définir un nom différent décommentez la ligne drbdctrl-vg dans le fichier /etc/drbdmanage.cfg et mettez-y la valeur de notre choix, dans l'exemple suivant le volume group utilisé s’appellera « drbd », créée dans la partition /dev/sdb1 comme ceci :
~# pvcreate /dev/sdb1
Physical volume "/dev/sdb1"
successfully created.
~# vgcreate drbd /dev/sdb1
Volume group "/dev/sdb1"
successfully created.
Avant de créer le cluster, comme drbdmanage a été installé par les sources, pour éviter un message d'erreur dbus, il faut créer le lien symbolique suivant :
ln -s /usr/local
/bin/dbus-drbdmanage-service /usr/bin
Ces opérations préliminaires seront à effectuer sur les deux machines minimales qui seront mises en place.
Nous créons une liaison SSH par clé entre les deux serveurs :
root@srv1 ~# ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in
which to save the key (
/home/cloud/.ssh/id_rsa):
Enter passphrase (
empty for
no passphrase):
Enter same passphrase again:
Your identification has been saved in
/home/cloud/.ssh/id_rsa.
Your public key has been saved in
/home/cloud/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:RgvrHWfPnz6PiniTRaTL0AFHFoR6xWp/cRZb6Q1RJc8 cloud@Debian
The key's randomart image is:
+---[RSA 2048]----+
| .**. oo=|
| .o+ . o=.|
| ...+ + .=E|
| .+=.o o +..|
| .oS+oo + |
| . o ++oo |
| . . +o |
| .+. ..o |
| .....o=o.|
+----[SHA256]-----+
root@srv1 ~# ssh-copy-id root@192.168.1.202
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/home/cloud/.ssh/id_rsa.pub"
The authenticity of host '
srv1 (
192
.168
.1
.201
)' can'
t be established.
ECDSA key fingerprint is SHA256:LLALxAyQlZLXlVtPSyTrOkUaTKKC+C0UCDAQKrWTuMI.
Are you sure you want to continue
connecting (
yes/no)? yes
/usr/bin/ssh-copy-id: INFO: attempting to log in
with the new key
(
s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1
key
(
s) remain to be installed -- if
you are prompted now it is to install the new keys
root@srv1's password:
Number of key(s) added: 1
Now try logging into the machine, with: "ssh '
cloud@srv1.local
'"
and check to make sure that only the key(s) you wanted were added.
Nous initialisons ensuite le cluster :
drbdmanage init 192
.168
.1
.201
Qui nous retournera :
You are going to initialize a new drbdmanage cluster.
CAUTION!
Note that:
* Any previous drbdmanage cluster information may be removed
* Any remaining resources managed by a previous drbdmanage installation
that still exist on this system will no longer be managed by drbdmanage
Confirm:
yes/no: yes
Empty drbdmanage control volume initialized on '/dev/drbd0'
.
Empty drbdmanage control volume initialized on '/dev/drbd1'
.
Waiting for
server: .
Operation completed successfully
Nous pouvons voir la liste des nœuds (un seul pour le moment) avec la commande :
drbdmanage list-nodes
Qui nous retournera :
+------------------------------------------------------------------------------+
|
Name |
Pool Size |
Pool Free |
|
State |
|
------------------------------------------------------------------------------|
|
srv1 |
2044
|
2036
|
|
ok |
+------------------------------------------------------------------------------+
Nous ajoutons ensuite le second nœud :
drbdmanage add-node srv2 192
.168
.1
.202
Operation completed successfully
Operation completed successfully
Executing join command using ssh.
IMPORTANT: The output you see comes from srv2
IMPORTANT: Your input is executed on srv2
You are going to join an existing drbdmanage cluster.
CAUTION!
Note that:
* Any previous drbdmanage cluster information may be removed
* Any remaining resources managed by a previous drbdmanage installation
that still exist on this system will no longer be managed by drbdmanage
Confirm:
yes/no: yes
Waiting for
server to start up (
can take up to 1
min)
Waiting for
server: ........
Operation completed successfully
Give leader time to contact the new node
Operation completed successfully
Operation completed successfully
La commande drbdmanage list-nodes nous retournera ceci :
drbdmanage list-nodes
+------------------------------------------------------------------------------+
|
Name |
Pool Size |
Pool Free |
|
State |
|
------------------------------------------------------------------------------|
|
srv1 |
2044
|
2036
|
|
online/quorum vote ignored |
|
srv2 |
2044
|
2036
|
|
offline/quorum vote ignored |
+------------------------------------------------------------------------------+
Nous créons ensuite une ressource :
:~/drbdmanage# drbdmanage add-resource r0
Operation completed successfully
Puis un volume dans la ressource :
:~/drbdmanage# drbdmanage add-volume r0 1500MB
Operation completed successfully
Nous pouvons ensuite voir la liste des volumes avec la commande drbdmanage list-volumes :
~# drbdmanage list-volumes
+------------------------------------------------------------------------------+
|
Name |
Vol ID |
Size |
Minor |
|
State |
|
------------------------------------------------------------------------------|
|
r0 |
0
|
1
,40
GiB |
100
|
|
ok |
+------------------------------------------------------------------------------+
Nous pouvons voir la valeur 100 au niveau du minor, ce qui signifie que le nom du device à utiliser sera /dev/drbd100.
Nous le formatons en OCFS2 comme vu au chapitre précédent :
~# mkfs -t ocfs2 -L MYCLOUD /dev/drbd100
mkfs.ocfs2 1
.8
.4
Cluster stack: classic o2cb
Label: MYCLOUD
Features: sparse extended-slotmap backup-super unwritten inline-data strict-journal-super xattr indexed-dirs refcount discontig-bg
Block size: 4096
(
12
bits)
Cluster size: 4096
(
12
bits)
Volume size: 1500000256
(
366211
clusters) (
366211
blocks)
Cluster groups: 12
(
tail covers 11395
clusters, rest cover 32256
clusters)
Extent allocator size: 4194304
(
1
groups)
Journal size: 67108864
Node slots: 2
Creating bitmaps: done
Initializing superblock: done
Writing system files: done
Writing superblock: done
Writing backup superblock: 1
block
(
s)
Formatting Journals: done
Growing extent allocator: done
Formatting slot map: done
Formatting quota files: done
Writing lost+found: done
mkfs.ocfs2 successful
1-3-6-6. Linstor▲
Linstor est le successeur de DRBD. Il est utilisé dans les solutions comme OpenNebula et Proxmox. Celui-ci est libre.
N'ayant pas réussi à l'installer, je n'ai pu le tester.
1-4. Ceph▲
Ceph est une plateforme libre de stockage distribué. Ceph est conçu pour être automatiquement distribué et réparable et sans point unique de défaillance.
Ceph est utilisable en mode bloc ou en mode objet (comme Amazon S3 en mode HTTP REST).
Ceph pourrait à lui tout seul faire l'objet d'un tutoriel, nous allons ici le survoler. Vous pourrez avoir une installation fonctionnelle au moins à minima en suivant ce chapitre.
1-4-1. Modules Ceph▲
Ceph est composé de plusieurs démons, répartis sur plusieurs machines. Il est possible d'avoir plusieurs types de démons sur la même machine, mais cela n'a pas d’intérêt et est même contre-productif sur un important cluster.
- Monitor (Mon) : ce sont les chefs d’orchestre du cluster Ceph. S'il n'y a pas de moniteur disponible, il n'y a pas d’accès au cluster Ceph. Pour assurer la pérennité du cluster, les moniteurs doivent être sur des machines indépendantes et en nombre impair. Un minimum de trois moniteurs est recommandé.
- OSD (Object Storage Device ou OSD) : il y a un démon OSD par device OSD. Ce démon est en charge du stockage, de la réplication et de la redistribution des données en cas de défaillance. Il fournit les informations de monitoring aux monitors. Un device OSD est l'unité bas niveau de stockage des données. Un cluster Ceph va être composé d'un ensemble d'OSD.
- Meta Data Service (MDS) : nécessaire à l’utilisation de CephFS, va stocker les métadonnées de tous les fichiers et permettre le support de POSIX.
- CephFS : système de fichiers POSIX fourni avec Ceph et s’appuyant sur le stockage Ceph (objet ou bloc). C’est la couche de plus haut niveau.
Les démons MDS et CephFS ne sont nécessaires que si vous utilisez Ceph avec son système de fichiers intégré.
Éléments un peu plus avancés
- pool : regroupement logique de stockage d’objets. Des pools par défaut suffisent à la gestion d’un petit cluster Ceph, mais pour des clusters intersites, il est important d’affiner ce type de réglage. Exemple : nombre de copies/répliquas des objets, répartition des données de type RAID5, etc.
- Placement Group (PG) : peut être vu comme des unités d’allocation et/ou index internes, ils servent à la répartition dans le cluster. Plus il y a de PG, plus on consomme de ressources (CPU/RAM).
Il est possible d’augmenter le nombre de PG d’un pool, mais pas de le réduire.
1-4-2. Fonctionnement de Ceph▲
CRUSH
CRUSH est l’algorithme de répartition des données dans le cluster. La crush map est la cartographie de la répartition des données. Les crush rules sont les règles de répartition des données.
Quand vous créez un cluster Ceph, il y a une crush map par défaut qui peut fonctionner automatiquement. Mais pour un gros cluster, il est important de la gérer. Cela permet d’affiner la répartition des données (entre deux centres de données par exemple), et de repérer facilement un OSD tombé (dans quel centre de données, quelle baie, quelle machine, etc.).
Voici les différents niveaux utilisés par les crush map :
- OSD (peut être vu comme le « device ») ;
- host ;
- chassis ;
- rack ;
- row ;
- pdu ;
- pod ;
- room ;
- datacenter ;
- region ;
- root.
Schéma tiré de la documentation officielle :
Voici le processus de lecture/écriture sur un cluster Ceph :
- Le client Ceph contacte un moniteur pour obtenir la cartographie du cluster ;
- Les données sont converties en objets (contenant un identifiant d’objet et de pool) ;
- L’algorithme CRUSH détermine le groupe où placer les données et l’OSD primaire ;
- Le client contacte l’OSD primaire pour stocker/récupérer les données ;
-
L’OSD primaire effectue une recherche CRUSH pour déterminer le groupe de placement et l’OSD secondaire.
- Dans un pool répliqué, l’OSD primaire copie l’objet vers l’OSD secondaire,
- Dans un pool avec erasure coding, l’OSD primaire découpe l’objet en segments, génère les segments contenant les calculs de parité et distribue l’ensemble de ces segments vers les OSD secondaires tout en écrivant un segment en local.
1-4-3. Installation de Ceph▲
Nous utiliserons la version Ceph Luminous (v,12).
1-4-3-1. Installation d'une première machine▲
1-4-3-1-1. Préparations▲
Nous allons commencer par les prérequis.
Nous fixons le nom de notre hôte dans le fichier /,etc/hosts :
192
.168
.1
.200
srv1
Nous spécifions le hostname dans le fichier /,etc/hostname en y mettant le nom « srv1 ».
Nous lançons la commande hostname :
hostname srv1
Nous fermons et rouvrons la session pour prendre en compte le nouveau nom.
Nous installons ensuite le serveur de temps, indispensable à la synchronisation correcte entre différentes machines :
apt-get install ntp ntpdate
Ensuite, nous configurons SSH afin de permettre une connexion par clé. D’abord, nous générons une clé avec la commande ssh-keygen :
root@srv1:~# ssh-keygen
Generating public/private rsa key pair.
Enter file in
which to save the key (
/root/.ssh/id_rsa):
/root/.ssh/id_rsa already exists.
Overwrite (
y/n)? ^C
root@srv1:~# rm .ssh/* -rf
root@srv1:~# ssh-keygen
Generating public/private rsa key pair.
Enter file in
which to save the key (
/root/.ssh/id_rsa):
Enter passphrase (
empty for
no passphrase):
Enter same passphrase again:
Your identification has been saved in
/root/.ssh/id_rsa.
Your public key has been saved in
/root/.ssh/id_rsa.pub.
The key fingerprint is:
3c:38
:bc:0d:54
:45
:13
:2c:dc:bd:61
:8c:24
:d9:58
:06
root@srv1
The key's randomart image is:
+---[RSA 2048]----+
| .E%O= |
| .=o=.= |
| . . . o |
| o o . |
| = S |
| = . |
| . . |
| |
| |
+-----------------+
root@srv1:~#
Ensuite, nous copions la clé avec ssh-copy-id :
ssh-copy-id root@srv1
The authenticity of host 'srv1 (192.168.1.200)'
can't be established.
ECDSA key fingerprint is 92:27:9f:61:14:19:63:85:28:d2:1b:88:4e:86:d6:08.
Are you sure you want to continue connecting (yes/no)? yes
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
root@srv1'
s password:
Number of key
(
s) added: 1
Now try logging into the machine, with: "ssh 'root@srv1'"
and check to make sure that only the key
(
s) you wanted were added.
Toutes les commandes Ceph passent par SSH et le nom d'hôte, il faut donc créer une clé SSH même pour une communication locale.
Grâce à cela, la commande ssh root@srv1 devrait ouvrir un Shell, sans nécessité de mot de passe, ce qui nous sera nécessaire pour les commandes suivantes.
1-4-3-1-2. Installation de ceph-deploy▲
Une fois les prérequis effectués, nous allons installer et utiliser la commande ceph-deploy qui nous permettra de préparer et déployer notre cluster.
Nous commençons par télécharger le fichier de signature de dépôt :
wget download.ceph.com/keys/release.asc
Nous installons celui-ci :
apt-key add release.asc
Nous ajoutons le dépôt dans /etc/apt/sources.list :
deb https://download.ceph.com/debian-luminous/ stretch main
Puis effectuons l'installation :
apt-get update
apt-get install ceph-deploy
1-4-3-1-3. Configuration▲
Nous créons un dossier qui contiendra les fichiers de configuration du cluster :
mkdir cephdeploy
cd cephdeploy
Nous créons notre cluster :
ceph-deploy new srv1
La console nous retournera les informations suivantes :
[ceph_deploy.conf][DEBUG ] found configuration file at: /root/.cephdeploy.conf
[ceph_deploy.cli][INFO ] Invoked (
1
.5
.39
): /usr/bin/ceph-deploy new srv1
[ceph_deploy.cli][INFO ] ceph-deploy options:
[ceph_deploy.cli][INFO ] username : None
[ceph_deploy.cli][INFO ] verbose : False
[ceph_deploy.cli][INFO ] overwrite_conf : False
[ceph_deploy.cli][INFO ] quiet : False
[ceph_deploy.cli][INFO ] cd_conf : <
ceph_deploy.conf.cephdeploy.Conf instance at 0x7f2db686dc68>
[ceph_deploy.cli][INFO ] cluster : ceph
[ceph_deploy.cli][INFO ] ssh_copykey : True
[ceph_deploy.cli][INFO ] mon : ['srv1'
]
[ceph_deploy.cli][INFO ] func : <
function new at 0x7f2db6843cf8>
[ceph_deploy.cli][INFO ] public_network : None
[ceph_deploy.cli][INFO ] ceph_conf : None
[ceph_deploy.cli][INFO ] cluster_network : None
[ceph_deploy.cli][INFO ] default_release : False
[ceph_deploy.cli][INFO ] fsid : None
[ceph_deploy.new][DEBUG ] Creating new cluster named ceph
[ceph_deploy.new][INFO ] making sure passwordless SSH succeeds
[srv1][DEBUG ] connected to host: srv1
[srv1][DEBUG ] detect platform information from remote host
[srv1][DEBUG ] detect machine type
[srv1][DEBUG ] find the location of an executable
[srv1][INFO ] Running command: /bin/ip link show
[srv1][INFO ] Running command: /bin/ip addr show
[srv1][DEBUG ] IP addresses found: [u'192.168.1.200'
]
[ceph_deploy.new][DEBUG ] Resolving host srv1
[ceph_deploy.new][DEBUG ] Monitor srv1 at 192
.168
.1
.200
[ceph_deploy.new][DEBUG ] Monitor initial members are ['srv1'
]
[ceph_deploy.new][DEBUG ] Monitor addrs are ['192.168.1.200'
]
[ceph_deploy.new][DEBUG ] Creating a random mon key...
[ceph_deploy.new][DEBUG ] Writing monitor keyring to ceph.mon.keyring...
[ceph_deploy.new][DEBUG ] Writing initial config to ceph.conf...
root@srv1:~/cephdeploy#
Ceci va créer les fichiers :
- ceph.conf ;
- ceph-deploy-ceph.log ;
- ceph.mon.keyring.
le fichier ceph.conf contient :
[global]
fsid =
85967fe2-3f08-4e0b-9f3c-ca6647776383
mon_initial_members =
srv1
mon_host =
192
.168
.1
.200
auth_cluster_required =
cephx
auth_service_required =
cephx
auth_client_required =
cephx
Dans lequel on ajoute :
osd pool default size =
2
osd pool default min size =
1
public_network =
192
.168
.1
.0
/24
cluster_network =
192
.168
.1
.0
/24
C'est ce fichier qui contiendra la configuration complète du cluster. À ce stade, il n'y a qu'une machine avec les réglages minimums nécessaires au démarrage. Ce fichier sera complété au fur et à mesure de l'avancée dans le chapitre et de l'ajout des modules/machines.
Ceci va nous permettre de créer un pool OSD à deux disques et permettre l'utilisation avec un seul nœud (en mode dégradé).
Les lignes public_network/cluster_network permettent de gérer les réseaux autorisés pour le dialogue entre les entités Ceph. Dans notre cas, il n'y a aucune séparation ce qui n'est pas recommandé en production.
Nous installons ceph-deploy sur notre premier nœud :
ceph-deploy install srv1
Lire les logs peut permettre de comprendre les opérations déclenchées. Cela pourra vous être utile si vous comptez utiliser le service. Si vous ne lisez ce chapitre qu'à titre de découverte ou de veille technologique, vous pouvez passer directement à la suite.
Voici un exemple des logs affichés :
Debian GNU/Linux 8
srv1 login: root
Password:
Last login: Fri Nov 16
18
:45
:59
CET 2018
from srv1 on pts/1
Linux srv1 3
.16
.0
-4
-amd64 #1 SMP Debian 3.16.51-3 (2017-12-13) x86_64
The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for
each program are described in
the
individual files in
/usr/share/doc/*/copyright.
Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
root@srv1:~# apt-get install ca-certificates apt-transport-https
Lecture des listes de paquets... Fait
Construction de l'arbre des dépendances
Lecture des informations d'
état... Fait
apt-transport-https est déjà la plus récente version disponible.
ca-certificates est déjà la plus récente version disponible.
0
mis à jour, 0
nouvellement installés, 0
à enlever et 24
non mis à jour.
root@srv1:~# ceph-deploy install srv1
[ceph_deploy.conf][DEBUG ] found configuration file at: /root/.cephdeploy.conf
[ceph_deploy.cli][INFO ] Invoked (
1
.5
.39
): /usr/bin/ceph-deploy install srv1
[ceph_deploy.cli][INFO ] ceph-deploy options:
[ceph_deploy.cli][INFO ] verbose : False
[ceph_deploy.cli][INFO ] testing : None
[ceph_deploy.cli][INFO ] cd_conf : <
ceph_deploy.conf.cephdeploy.Conf instance at 0x7fd903c207a0>
[ceph_deploy.cli][INFO ] cluster : ceph
[ceph_deploy.cli][INFO ] dev_commit : None
[ceph_deploy.cli][INFO ] install_mds : False
[ceph_deploy.cli][INFO ] stable : None
[ceph_deploy.cli][INFO ] default_release : False
[ceph_deploy.cli][INFO ] username : None
[ceph_deploy.cli][INFO ] adjust_repos : True
[ceph_deploy.cli][INFO ] func : <
function install at 0x7fd904063410>
[ceph_deploy.cli][INFO ] install_mgr : False
[ceph_deploy.cli][INFO ] install_all : False
[ceph_deploy.cli][INFO ] repo : False
[ceph_deploy.cli][INFO ] host : ['srv1'
]
[ceph_deploy.cli][INFO ] install_rgw : False
[ceph_deploy.cli][INFO ] install_tests : False
[ceph_deploy.cli][INFO ] repo_url : None
[ceph_deploy.cli][INFO ] ceph_conf : None
[ceph_deploy.cli][INFO ] install_osd : False
[ceph_deploy.cli][INFO ] version_kind : stable
[ceph_deploy.cli][INFO ] install_common : False
[ceph_deploy.cli][INFO ] overwrite_conf : False
[ceph_deploy.cli][INFO ] quiet : False
[ceph_deploy.cli][INFO ] dev : master
[ceph_deploy.cli][INFO ] nogpgcheck : False
[ceph_deploy.cli][INFO ] local_mirror : None
[ceph_deploy.cli][INFO ] release : None
[ceph_deploy.cli][INFO ] install_mon : False
[ceph_deploy.cli][INFO ] gpg_url : None
[ceph_deploy.install][DEBUG ] Installing stable version jewel on cluster ceph hosts srv1
[ceph_deploy.install][DEBUG ] Detecting platform for
host srv1 ...
[srv1][DEBUG ] connected to host: srv1
[srv1][DEBUG ] detect platform information from remote host
[srv1][DEBUG ] detect machine type
[ceph_deploy.install][INFO ] Distro info: debian 8
.10
jessie
[srv1][INFO ] installing Ceph on srv1
[srv1][INFO ] Running command: env DEBIAN_FRONTEND
=
noninteractive DEBIAN_PRIORITY
=
critical apt-get --assume-yes -q --no-install-recommends install ca-certificates apt-transport-https
[srv1][DEBUG ] Lecture des listes de paquets…
[srv1][DEBUG ] Construction de l'arbre des dépendances…
[srv1][DEBUG ] Lecture des informations d'
état…
[srv1][DEBUG ] apt-transport-https est déjà la plus récente version disponible.
[srv1][DEBUG ] ca-certificates est déjà la plus récente version disponible.
[srv1][DEBUG ] 0
mis à jour, 0
nouvellement installés, 0
à enlever et 24
non mis à jour.
[srv1][INFO ] Running command: wget -O release.asc https://download.ceph.com/keys/release.asc
[srv1][WARNIN] --2018
-11
-16
19
:30
:22
-- https://download.ceph.com/keys/release.asc
[srv1][WARNIN] Résolution de download.ceph.com (
download.ceph.com)… 158
.69
.68
.124
, 2607
:5300
:201
:2000
::3
:58a1
[srv1][WARNIN] Connexion à download.ceph.com (
download.ceph.com)|
158
.69
.68
.124
|
:443
… connecté.
[srv1][WARNIN] requête HTTP transmise, en attente de la réponse… 200
OK
[srv1][WARNIN] Taille : 1645
(
1
,6K) [application/octet-stream]
[srv1][WARNIN] Sauvegarde en : « release.asc »
[srv1][WARNIN]
[srv1][WARNIN] 0K . 100
%
27
,7M
=
0s
[srv1][WARNIN]
[srv1][WARNIN] 2018
-11
-16
19
:30
:23
(
27
,7
MB/s) — « release.asc » sauvegardé [1645
/1645
]
[srv1][WARNIN]
[srv1][INFO ] Running command: apt-key add release.asc
[srv1][DEBUG ] OK
[srv1][DEBUG ] add deb repo to /etc/apt/sources.list.d/
[srv1][INFO ] Running command: env DEBIAN_FRONTEND
=
noninteractive DEBIAN_PRIORITY
=
critical apt-get --assume-yes -q update
[srv1][DEBUG ] Ign http://ftp.fr.debian.org jessie InRelease
[srv1][DEBUG ] Atteint http://ftp.fr.debian.org jessie-updates InRelease
[srv1][DEBUG ] Atteint http://ftp.fr.debian.org jessie/updates InRelease
[srv1][DEBUG ] Atteint http://ftp.fr.debian.org jessie Release.gpg
[srv1][DEBUG ] Atteint http://ftp.fr.debian.org jessie Release
[srv1][DEBUG ] Réception de : 1
http://ftp.fr.debian.org jessie-updates/main amd64 Packages/DiffIndex [11
,8
kB]
[srv1][DEBUG ] Réception de : 2
http://ftp.fr.debian.org jessie-updates/main Translation-en/DiffIndex [3
688
B]
[srv1][DEBUG ] Atteint https://download.ceph.com jessie InRelease
[srv1][DEBUG ] Atteint http://ftp.fr.debian.org jessie/updates/main amd64 Packages
[srv1][DEBUG ] Atteint http://ftp.fr.debian.org jessie/updates/main Translation-en
[srv1][DEBUG ] Atteint http://ftp.fr.debian.org jessie/main amd64 Packages
[srv1][DEBUG ] Atteint http://ftp.fr.debian.org jessie/main Translation-fr
[srv1][DEBUG ] Réception de : 3
https://download.ceph.com jessie/main Translation-fr_FR [178
B]
[srv1][DEBUG ] Atteint http://ftp.fr.debian.org jessie/main Translation-en
[srv1][DEBUG ] Réception de : 4
https://download.ceph.com jessie/main Translation-fr [178
B]
[srv1][DEBUG ] Réception de : 5
https://download.ceph.com jessie/main Translation-en [178
B]
[srv1][DEBUG ] Atteint https://download.ceph.com jessie/main amd64 Packages
[srv1][DEBUG ] Réception de : 6
https://download.ceph.com jessie/main Translation-fr_FR [178
B]
[srv1][DEBUG ] Réception de : 7
https://download.ceph.com jessie/main Translation-fr [178
B]
[srv1][DEBUG ] Réception de : 8
https://download.ceph.com jessie/main Translation-en [178
B]
[srv1][DEBUG ] Réception de : 9
https://download.ceph.com jessie/main Translation-fr_FR [178
B]
[srv1][DEBUG ] Réception de : 10
https://download.ceph.com jessie/main Translation-fr [178
B]
[srv1][DEBUG ] Réception de : 11
https://download.ceph.com jessie/main Translation-en [178
B]
[srv1][DEBUG ] Réception de : 12
https://download.ceph.com jessie/main Translation-fr_FR [178
B]
[srv1][DEBUG ] Réception de : 13
https://download.ceph.com jessie/main Translation-fr [178
B]
[srv1][DEBUG ] Réception de : 14
https://download.ceph.com jessie/main Translation-en [178
B]
[srv1][DEBUG ] Réception de : 15
https://download.ceph.com jessie/main Translation-fr_FR [178
B]
[srv1][DEBUG ] Ign https://download.ceph.com jessie/main Translation-fr_FR
[srv1][DEBUG ] Réception de : 16
https://download.ceph.com jessie/main Translation-fr [178
B]
[srv1][DEBUG ] Ign https://download.ceph.com jessie/main Translation-fr
[srv1][DEBUG ] Réception de : 17
https://download.ceph.com jessie/main Translation-en [178
B]
[srv1][DEBUG ] Ign https://download.ceph.com jessie/main Translation-en
[srv1][DEBUG ] 15
,5
ko réceptionnés en 5s (
3
032
o/s)
[srv1][DEBUG ] Lecture des listes de paquets…
[srv1][WARNIN] W: Duplicate sources.list entry https://download.ceph.com/debian-jewel/ jessie/main amd64 Packages (
/var/lib/apt/lists/download.ceph.com_debian-jewel_dists_jessie_main_binary-amd64_Packages)
[srv1][WARNIN] W: Vous pouvez lancer « apt-get update » pour corriger ces problèmes.
[srv1][INFO ] Running command: env DEBIAN_FRONTEND
=
noninteractive DEBIAN_PRIORITY
=
critical apt-get --assume-yes -q --no-install-recommends install -o Dpkg::Options::=
--force-confnew ceph ceph-osd ceph-mds ceph-mon radosgw
[srv1][DEBUG ] Lecture des listes de paquets…
[srv1][DEBUG ] Construction de l'arbre des dépendances…
[srv1][DEBUG ] Lecture des informations d'
état…
[srv1][DEBUG ] ceph est déjà la plus récente version disponible.
[srv1][DEBUG ] ceph-mds est déjà la plus récente version disponible.
[srv1][DEBUG ] ceph-mon est déjà la plus récente version disponible.
[srv1][DEBUG ] ceph-osd est déjà la plus récente version disponible.
[srv1][DEBUG ] radosgw est déjà la plus récente version disponible.
[srv1][DEBUG ] 0
mis à jour, 0
nouvellement installés, 0
à enlever et 24
non mis à jour.
[srv1][INFO ] Running command: ceph --version
[srv1][DEBUG ] ceph version 10
.2
.11
(
e4b061b47f07f583c92a050d9e84b1813a35671e)
root@srv1:~#
Dans les logs, nous pouvons voir ce qu'il se passe :
- connexion SSH sur srv1 ;
- téléchargement de la clé de dépôt Ceph (nous l'avons déjà fait pour l'installation de ceph-deploy, inutile ici, mais nécessaire pour le déploiement de Ceph sur une autre machine) ;
- ajout de la clé avec apt-key (déjà fait) ;
- ajout du dépôt dans /etc/apt/sources.list.d (en doublon avec ce qui a déjà été fait pour installer ceph-deploy, nous voyons un avertissement à ce sujet) ;
- installation des paquets nécessaires.
La commande se termine par l'appel de ceph –version.
La commande est prévue pour installer tout ce qu'il faut sur n'importe quelle machine via SSH.
1-4-3-1-4. Création d'un moniteur▲
Pour gérer notre cluster, nous avons besoin d’un moniteur. La création s’effectue avec la commande :
ceph-deploy mon create-initial
Qui retourne :
[ceph_deploy.conf][DEBUG ] found configuration file at: /root/.cephdeploy.conf
[ceph_deploy.cli][INFO ] Invoked (
1
.5
.39
): /usr/bin/ceph-deploy mon create-initial
[ceph_deploy.cli][INFO ] ceph-deploy options:
[ceph_deploy.cli][INFO ] username : None
[ceph_deploy.cli][INFO ] verbose : False
[ceph_deploy.cli][INFO ] overwrite_conf : False
[ceph_deploy.cli][INFO ] subcommand : create-initial
[ceph_deploy.cli][INFO ] quiet : False
[ceph_deploy.cli][INFO ] cd_conf : <
ceph_deploy.conf.cephdeploy.Conf instance at 0x7faf0fb69fc8>
[ceph_deploy.cli][INFO ] cluster : ceph
[ceph_deploy.cli][INFO ] func : <
function mon at 0x7faf0ffd4500>
[ceph_deploy.cli][INFO ] ceph_conf : None
[ceph_deploy.cli][INFO ] keyrings : None
[ceph_deploy.cli][INFO ] default_release : False
[ceph_deploy.mon][DEBUG ] Deploying mon, cluster ceph hosts srv1
[ceph_deploy.mon][DEBUG ] detecting platform for
host srv1 ...
[srv1][DEBUG ] connected to host: srv1
[srv1][DEBUG ] detect platform information from remote host
[srv1][DEBUG ] detect machine type
[srv1][DEBUG ] find the location of an executable
[ceph_deploy.mon][INFO ] distro info: debian 8
.10
jessie
[srv1][DEBUG ] determining if
provided host has same hostname in
remote
[srv1][DEBUG ] get remote short hostname
[srv1][DEBUG ] deploying mon to srv1
[srv1][DEBUG ] get remote short hostname
[srv1][DEBUG ] remote hostname: srv1
[srv1][DEBUG ] write cluster configuration to /etc/ceph/{cluster}.conf
[srv1][DEBUG ] create the mon path if
it does not exist
[srv1][DEBUG ] checking for
done
path: /var/lib/ceph/mon/ceph-srv1/done
[srv1][DEBUG ] done
path does not exist: /var/lib/ceph/mon/ceph-srv1/done
[srv1][INFO ] creating keyring file: /var/lib/ceph/tmp/ceph-srv1.mon.keyring
[srv1][DEBUG ] create the monitor keyring file
[srv1][INFO ] Running command: ceph-mon --cluster ceph --mkfs -i srv1 --keyring /var/lib/ceph/tmp/ceph-srv1.mon.keyring --setuser 64045
--setgroup 64045
[srv1][DEBUG ] ceph-mon: renaming mon.noname-a 192
.168
.1
.200
:6789
/0
to mon.srv1
[srv1][DEBUG ] ceph-mon: set fsid to 85967fe2-3f08-4e0b-9f3c-ca6647776383
[srv1][DEBUG ] ceph-mon: created monfs at /var/lib/ceph/mon/ceph-srv1 for
mon.srv1
[srv1][INFO ] unlinking keyring file /var/lib/ceph/tmp/ceph-srv1.mon.keyring
[srv1][DEBUG ] create a done
file to avoid re-doing the mon deployment
[srv1][DEBUG ] create the init path if
it does not exist
[srv1][INFO ] Running command: systemctl enable ceph.target
[srv1][INFO ] Running command: systemctl enable ceph-mon@srv1
[srv1][WARNIN] Created symlink from /etc/systemd/system/ceph-mon.target.wants/ceph-mon@srv1.service to /lib/systemd/system/ceph-mon@.service.
[srv1][INFO ] Running command: systemctl start ceph-mon@srv1
[srv1][INFO ] Running command: ceph --cluster
=
ceph --admin-daemon /var/run/ceph/ceph-mon.srv1.asok mon_status
[srv1][DEBUG ] ********************************************************************************
[srv1][DEBUG ] status for
monitor: mon.srv1
[srv1][DEBUG ] {
[srv1][DEBUG ] "election_epoch"
: 3
,
[srv1][DEBUG ] "extra_probe_peers"
: [],
[srv1][DEBUG ] "monmap"
: {
[srv1][DEBUG ] "created"
: "2018-11-16 19:53:16.240703"
,
[srv1][DEBUG ] "epoch"
: 1
,
[srv1][DEBUG ] "fsid"
: "85967fe2-3f08-4e0b-9f3c-ca6647776383"
,
[srv1][DEBUG ] "modified"
: "2018-11-16 19:53:16.240703"
,
[srv1][DEBUG ] "mons"
: [
[srv1][DEBUG ] {
[srv1][DEBUG ] "addr"
: "192.168.1.200:6789/0"
,
[srv1][DEBUG ] "name"
: "srv1"
,
[srv1][DEBUG ] "rank"
: 0
[srv1][DEBUG ] }
[srv1][DEBUG ] ]
[srv1][DEBUG ] },
[srv1][DEBUG ] "name"
: "srv1"
,
[srv1][DEBUG ] "outside_quorum"
: [],
[srv1][DEBUG ] "quorum"
: [
[srv1][DEBUG ] 0
[srv1][DEBUG ] ],
[srv1][DEBUG ] "rank"
: 0
,
[srv1][DEBUG ] "state"
: "leader"
,
[srv1][DEBUG ] "sync_provider"
: []
[srv1][DEBUG ] }
[srv1][DEBUG ] ********************************************************************************
[srv1][INFO ] monitor: mon.srv1 is running
[srv1][INFO ] Running command: ceph --cluster
=
ceph --admin-daemon /var/run/ceph/ceph-mon.srv1.asok mon_status
[ceph_deploy.mon][INFO ] processing monitor mon.srv1
[srv1][DEBUG ] connected to host: srv1
[srv1][DEBUG ] detect platform information from remote host
[srv1][DEBUG ] detect machine type
[srv1][DEBUG ] find the location of an executable
[srv1][INFO ] Running command: ceph --cluster
=
ceph --admin-daemon /var/run/ceph/ceph-mon.srv1.asok mon_status
[ceph_deploy.mon][INFO ] mon.srv1 monitor has reached quorum!
[ceph_deploy.mon][INFO ] all initial monitors are running and have formed quorum
[ceph_deploy.mon][INFO ] Running gatherkeys...
[ceph_deploy.gatherkeys][INFO ] Storing keys in
temp directory /tmp/tmpyWJn4J
[srv1][DEBUG ] connected to host: srv1
[srv1][DEBUG ] detect platform information from remote host
[srv1][DEBUG ] detect machine type
[srv1][DEBUG ] get remote short hostname
[srv1][DEBUG ] fetch remote file
[srv1][INFO ] Running command: /usr/bin/ceph --connect-timeout
=
25
--cluster
=
ceph --admin-daemon
=
/var/run/ceph/ceph-mon.srv1.asok mon_status
[srv1][INFO ] Running command: /usr/bin/ceph --connect-timeout
=
25
--cluster
=
ceph --name mon. --keyring
=
/var/lib/ceph/mon/ceph-srv1/keyring auth get client.admin
[srv1][INFO ] Running command: /usr/bin/ceph --connect-timeout
=
25
--cluster
=
ceph --name mon. --keyring
=
/var/lib/ceph/mon/ceph-srv1/keyring auth get client.bootstrap-mds
[srv1][INFO ] Running command: /usr/bin/ceph --connect-timeout
=
25
--cluster
=
ceph --name mon. --keyring
=
/var/lib/ceph/mon/ceph-srv1/keyring auth get-or-create client.bootstrap-mds mon allow profile bootstrap-mds
[srv1][INFO ] Running command: /usr/bin/ceph --connect-timeout
=
25
--cluster
=
ceph --name mon. --keyring
=
/var/lib/ceph/mon/ceph-srv1/keyring auth get client.bootstrap-mgr
[srv1][INFO ] Running command: /usr/bin/ceph --connect-timeout
=
25
--cluster
=
ceph --name mon. --keyring
=
/var/lib/ceph/mon/ceph-srv1/keyring auth get-or-create client.bootstrap-mgr mon allow profile bootstrap-mgr
[srv1][INFO ] Running command: /usr/bin/ceph --connect-timeout
=
25
--cluster
=
ceph --name mon. --keyring
=
/var/lib/ceph/mon/ceph-srv1/keyring auth get client.bootstrap-osd
[srv1][INFO ] Running command: /usr/bin/ceph --connect-timeout
=
25
--cluster
=
ceph --name mon. --keyring
=
/var/lib/ceph/mon/ceph-srv1/keyring auth get client.bootstrap-rgw
[ceph_deploy.gatherkeys][INFO ] Storing ceph.client.admin.keyring
[ceph_deploy.gatherkeys][INFO ] Storing ceph.bootstrap-mds.keyring
[ceph_deploy.gatherkeys][INFO ] Storing ceph.bootstrap-mgr.keyring
[ceph_deploy.gatherkeys][INFO ] keyring 'ceph.mon.keyring'
already exists
[ceph_deploy.gatherkeys][INFO ] Storing ceph.bootstrap-osd.keyring
[ceph_deploy.gatherkeys][INFO ] Storing ceph.bootstrap-rgw.keyring
[ceph_deploy.gatherkeys][INFO ] Destroy temp directory /tmp/tmpyWJn4J
root@srv1:~/cephdeploy#
1-4-3-1-5. Ajout d'OSD▲
Nous pouvons commencer par lister les disques d'un hôte Ceph avec la commande suivante :
ceph-deploy disk list srv1
Qui affichera dans mon exemple :
…
[srv1][INFO ] Running command: /usr/sbin/ceph-disk list
[srv1][DEBUG ] /dev/sda :
[srv1][DEBUG ] /dev/sda2 swap, swap
[srv1][DEBUG ] /dev/sda1 other, ext4, mounted on /
[srv1][DEBUG ] /dev/sdb other, unknown
[srv1][DEBUG ] /dev/sr0 other, unknown
root@srv1:~/cephdeploy#
Nous allons procéder à la préparation de l'OSD sur le disque /dev/sdb.
Ceci effacera l'éventuel contenu sur le disque.
Voici la commande :
ceph-deploy osd prepare srv1:/dev/sdb
Qui retournera :
[ceph_deploy.conf][DEBUG ] found configuration file at: /root/.cephdeploy.conf
[ceph_deploy.cli][INFO ] Invoked (
1
.5
.39
): /usr/bin/ceph-deploy osd prepare srv1:/dev/sdb
[ceph_deploy.cli][INFO ] ceph-deploy options:
[ceph_deploy.cli][INFO ] username : None
[ceph_deploy.cli][INFO ] block_db : None
[ceph_deploy.cli][INFO ] disk : [(
'srv1'
, '/dev/sdb'
, None)]
[ceph_deploy.cli][INFO ] dmcrypt : False
[ceph_deploy.cli][INFO ] verbose : False
[ceph_deploy.cli][INFO ] bluestore : None
[ceph_deploy.cli][INFO ] block_wal : None
[ceph_deploy.cli][INFO ] overwrite_conf : False
[ceph_deploy.cli][INFO ] subcommand : prepare
[ceph_deploy.cli][INFO ] dmcrypt_key_dir : /,etc/ceph/dmcrypt-keys
[ceph_deploy.cli][INFO ] quiet : False
[ceph_deploy.cli][INFO ] cd_conf : <
ceph_deploy.conf.cephdeploy.Conf instance at 0x7fc9a8963ef0>
[ceph_deploy.cli][INFO ] cluster : ceph
[ceph_deploy.cli][INFO ] fs_type : xfs
[ceph_deploy.cli][INFO ] filestore : None
[ceph_deploy.cli][INFO ] func : <
function osd at 0x7fc9a8dc6488>
[ceph_deploy.cli][INFO ] ceph_conf : None
[ceph_deploy.cli][INFO ] default_release : False
[ceph_deploy.cli][INFO ] zap_disk : False
[ceph_deploy.osd][DEBUG ] Preparing cluster ceph disks srv1:/dev/sdb:
[srv1][DEBUG ] connected to host: srv1
[srv1][DEBUG ] detect platform information from remote host
[srv1][DEBUG ] detect machine type
[srv1][DEBUG ] find the location of an executable
[ceph_deploy.osd][INFO ] Distro info: debian 8
.10
jessie
[ceph_deploy.osd][DEBUG ] Deploying osd to srv1
[srv1][DEBUG ] write cluster configuration to /etc/ceph/{cluster}.conf
[ceph_deploy.osd][DEBUG ] Preparing host srv1 disk /dev/sdb journal None activate False
[srv1][DEBUG ] find the location of an executable
[srv1][INFO ] Running command: /usr/sbin/ceph-disk -v prepare --cluster ceph --fs-type xfs -- /dev/sdb
[srv1][WARNIN] command: Running command: /usr/bin/ceph-osd --cluster
=
ceph --show-config-value
=
fsid
[srv1][WARNIN] command: Running command: /usr/bin/ceph-osd --check-allows-journal -i 0
--log-file $run_dir
/$cluster
-osd-check.log --cluster ceph --setuser ceph --setgroup ceph
[srv1][WARNIN] command: Running command: /usr/bin/ceph-osd --check-wants-journal -i 0
--log-file $run_dir
/$cluster
-osd-check.log --cluster ceph --setuser ceph --setgroup ceph
[srv1][WARNIN] command: Running command: /usr/bin/ceph-osd --check-needs-journal -i 0
--log-file $run_dir
/$cluster
-osd-check.log --cluster ceph --setuser ceph --setgroup ceph
[srv1][WARNIN] get_dm_uuid: get_dm_uuid /dev/sdb uuid path is /sys/dev/block/8
:16
/dm/uuid
[srv1][WARNIN] set_type: Will colocate journal with data on /dev/sdb
[srv1][WARNIN] command: Running command: /usr/bin/ceph-osd --cluster
=
ceph --show-config-value
=
osd_journal_size
[srv1][WARNIN] get_dm_uuid: get_dm_uuid /dev/sdb uuid path is /sys/dev/block/8
:16
/dm/uuid
[srv1][WARNIN] get_dm_uuid: get_dm_uuid /dev/sdb uuid path is /sys/dev/block/8
:16
/dm/uuid
[srv1][WARNIN] get_dm_uuid: get_dm_uuid /dev/sdb uuid path is /sys/dev/block/8
:16
/dm/uuid
[srv1][WARNIN] command: Running command: /usr/bin/ceph-conf --cluster
=
ceph --name
=
osd. --lookup osd_mkfs_options_xfs
[srv1][WARNIN] command: Running command: /usr/bin/ceph-conf --cluster
=
ceph --name
=
osd. --lookup osd_fs_mkfs_options_xfs
[srv1][WARNIN] command: Running command: /usr/bin/ceph-conf --cluster
=
ceph --name
=
osd. --lookup osd_mount_options_xfs
[srv1][WARNIN] command: Running command: /usr/bin/ceph-conf --cluster
=
ceph --name
=
osd. --lookup osd_fs_mount_options_xfs
[srv1][WARNIN] get_dm_uuid: get_dm_uuid /dev/sdb uuid path is /sys/dev/block/8
:16
/dm/uuid
[srv1][WARNIN] get_dm_uuid: get_dm_uuid /dev/sdb uuid path is /sys/dev/block/8
:16
/dm/uuid
[srv1][WARNIN] ptype_tobe_for_name: name =
journal
[srv1][WARNIN] get_dm_uuid: get_dm_uuid /dev/sdb uuid path is /sys/dev/block/8
:16
/dm/uuid
[srv1][WARNIN] create_partition: Creating journal partition num 2
size 5120
on /dev/sdb
[srv1][WARNIN] command_check_call: Running command: /sbin/sgdisk --new
=
2
:0
:+5120M --change-name
=
2
:ceph journal --partition-guid
=
2
:74a9b3f0-08b8-48db-a3ec-e6e36451d0d9 --typecode
=
2
:45b0969e-9b03-4f30-b4c6-b4b80ceff106 --mbrtogpt -- /dev/sdb
[srv1][DEBUG ] Creating new GPT entries.
[srv1][DEBUG ] Setting name!
[srv1][DEBUG ] partNum is 1
[srv1][DEBUG ] REALLY setting name!
[srv1][DEBUG ] The operation has completed successfully.
[srv1][WARNIN] update_partition: Calling partprobe on created device /dev/sdb
[srv1][WARNIN] command_check_call: Running command: /sbin/udevadm settle --timeout
=
600
[srv1][WARNIN] command: Running command: /usr/bin/flock -s /dev/sdb /sbin/partprobe /dev/sdb
[srv1][WARNIN] command_check_call: Running command: /sbin/udevadm settle --timeout
=
600
[srv1][WARNIN] get_dm_uuid: get_dm_uuid /dev/sdb uuid path is /sys/dev/block/8
:16
/dm/uuid
[srv1][WARNIN] get_dm_uuid: get_dm_uuid /dev/sdb uuid path is /sys/dev/block/8
:16
/dm/uuid
[srv1][WARNIN] get_dm_uuid: get_dm_uuid /dev/sdb2 uuid path is /sys/dev/block/8
:18
/dm/uuid
[srv1][WARNIN] prepare_device: Journal is GPT partition /dev/disk/by-partuuid/74a9b3f0-08b8-48db-a3ec-e6e36451d0d9
[srv1][WARNIN] prepare_device: Journal is GPT partition /dev/disk/by-partuuid/74a9b3f0-08b8-48db-a3ec-e6e36451d0d9
[srv1][WARNIN] get_dm_uuid: get_dm_uuid /dev/sdb uuid path is /sys/dev/block/8
:16
/dm/uuid
[srv1][WARNIN] set_data_partition: Creating osd partition on /dev/sdb
[srv1][WARNIN] get_dm_uuid: get_dm_uuid /dev/sdb uuid path is /sys/dev/block/8
:16
/dm/uuid
[srv1][WARNIN] ptype_tobe_for_name: name =
data
[srv1][WARNIN] get_dm_uuid: get_dm_uuid /dev/sdb uuid path is /sys/dev/block/8
:16
/dm/uuid
[srv1][WARNIN] create_partition: Creating data partition num 1
size 0
on /dev/sdb
[srv1][WARNIN] command_check_call: Running command: /sbin/sgdisk --largest-new
=
1
--change-name
=
1
:ceph data --partition-guid
=
1
:720e149a-ebb7-4d44-9b89-d1c017481c18 --typecode
=
1
:89c57f98-2fe5-4dc0-89c1-f3ad0ceff2be --mbrtogpt -- /dev/sdb
[srv1][DEBUG ] Setting name!
[srv1][DEBUG ] partNum is 0
[srv1][DEBUG ] REALLY setting name!
[srv1][DEBUG ] The operation has completed successfully.
[srv1][WARNIN] update_partition: Calling partprobe on created device /dev/sdb
[srv1][WARNIN] command_check_call: Running command: /sbin/udevadm settle --timeout
=
600
[srv1][WARNIN] command: Running command: /usr/bin/flock -s /dev/sdb /sbin/partprobe /dev/sdb
[srv1][WARNIN] command_check_call: Running command: /sbin/udevadm settle --timeout
=
600
[srv1][WARNIN] get_dm_uuid: get_dm_uuid /dev/sdb uuid path is /sys/dev/block/8
:16
/dm/uuid
[srv1][WARNIN] get_dm_uuid: get_dm_uuid /dev/sdb uuid path is /sys/dev/block/8
:16
/dm/uuid
[srv1][WARNIN] get_dm_uuid: get_dm_uuid /dev/sdb1 uuid path is /sys/dev/block/8
:17
/dm/uuid
[srv1][WARNIN] populate_data_path_device: Creating xfs fs on /dev/sdb1
[srv1][WARNIN] command_check_call: Running command: /sbin/mkfs -t xfs -f -i size
=
2048
-- /dev/sdb1
[srv1][DEBUG ] meta-data
=
/dev/sdb1 isize
=
2048
agcount
=
4
, agsize
=
196543
blks
[srv1][DEBUG ] =
sectsz
=
512
attr
=
2
, projid32bit
=
1
[srv1][DEBUG ] =
crc
=
0
finobt
=
0
[srv1][DEBUG ] data =
bsize
=
4096
blocks
=
786171
, imaxpct
=
25
[srv1][DEBUG ] =
sunit
=
0
swidth
=
0
blks
[srv1][DEBUG ] naming =
version 2
bsize
=
4096
ascii-ci
=
0
ftype
=
0
[srv1][DEBUG ] log =
internal log bsize
=
4096
blocks
=
2560
, version
=
2
[srv1][DEBUG ] =
sectsz
=
512
sunit
=
0
blks, lazy-count
=
1
[srv1][DEBUG ] realtime =
none extsz
=
4096
blocks
=
0
, rtextents
=
0
[srv1][WARNIN] mount: Mounting /dev/sdb1 on /var/lib/ceph/tmp/mnt.zWKFv6 with options noatime,inode64
[srv1][WARNIN] command_check_call: Running command: /bin/mount -t xfs -o noatime,inode64 -- /dev/sdb1 /var/lib/ceph/tmp/mnt.zWKFv6
[srv1][WARNIN] populate_data_path: Preparing osd data dir /var/lib/ceph/tmp/mnt.zWKFv6
[srv1][WARNIN] command: Running command: /bin/chown -R ceph:ceph /var/lib/ceph/tmp/mnt.zWKFv6/ceph_fsid.4952
.tmp
[srv1][WARNIN] command: Running command: /bin/chown -R ceph:ceph /var/lib/ceph/tmp/mnt.zWKFv6/fsid.4952
.tmp
[srv1][WARNIN] command: Running command: /bin/chown -R ceph:ceph /var/lib/ceph/tmp/mnt.zWKFv6/magic.4952
.tmp
[srv1][WARNIN] command: Running command: /bin/chown -R ceph:ceph /var/lib/ceph/tmp/mnt.zWKFv6/journal_uuid.4952
.tmp
[srv1][WARNIN] adjust_symlink: Creating symlink /var/lib/ceph/tmp/mnt.zWKFv6/journal ->
/dev/disk/by-partuuid/74a9b3f0-08b8-48db-a3ec-e6e36451d0d9
[srv1][WARNIN] command: Running command: /bin/chown -R ceph:ceph /var/lib/ceph/tmp/mnt.zWKFv6
[srv1][WARNIN] unmount: Unmounting /var/lib/ceph/tmp/mnt.zWKFv6
[srv1][WARNIN] command_check_call: Running command: /bin/umount -- /var/lib/ceph/tmp/mnt.zWKFv6
[srv1][WARNIN] get_dm_uuid: get_dm_uuid /dev/sdb uuid path is /sys/dev/block/8
:16
/dm/uuid
[srv1][WARNIN] command_check_call: Running command: /sbin/sgdisk --typecode
=
1
:4fbd7e29-9d25-41b8-afd0-062c0ceff05d -- /dev/sdb
[srv1][DEBUG ] The operation has completed successfully.
[srv1][WARNIN] update_partition: Calling partprobe on prepared device /dev/sdb
[srv1][WARNIN] command_check_call: Running command: /sbin/udevadm settle --timeout
=
600
[srv1][WARNIN] command: Running command: /usr/bin/flock -s /dev/sdb /sbin/partprobe /dev/sdb
[srv1][WARNIN] command_check_call: Running command: /sbin/udevadm settle --timeout
=
600
[srv1][WARNIN] command_check_call: Running command: /sbin/udevadm trigger --action
=
add --sysname-match sdb1
[srv1][INFO ] checking OSD status...
[srv1][DEBUG ] find the location of an executable
[srv1][INFO ] Running command: /usr/bin/ceph --cluster
=
ceph osd stat --format
=
json
[srv1][WARNIN] there is 1
OSD down
[srv1][WARNIN] there is 1
OSD out
[ceph_deploy.osd][DEBUG ] Host srv1 is now ready for
osd use.
root@srv1:~/cephdeploy#
Nous pouvons voir la création d'une table de partitions GPT et la création de partitions XFS.
Rappelons la commande ceph-deploy disk list srv1 :
…
[srv1][INFO ] Running command: /usr/sbin/ceph-disk list
[srv1][DEBUG ] /dev/sda :
[srv1][DEBUG ] /dev/sda2 swap, swap
[srv1][DEBUG ] /dev/sda1 other, ext4, mounted on /
[srv1][DEBUG ] /dev/sdb :
[srv1][DEBUG ] /dev/sdb2 ceph journal, for
/dev/sdb1
[srv1][DEBUG ] /dev/sdb1 ceph data, active, cluster ceph, osd.0
, journal /dev/sdb2
[srv1][DEBUG ] /dev/sr0 other, unknown
root@srv1:~/cephdeploy#
Nous pouvons voir qu'il y a en fait deux partitions : une partition pour les données de Ceph (ceph data) en /dev/sdb1 et une partition pour les journaux Ceph (ceph journal) en /dev/sdb2.
Pour des questions de performance, il est conseillé de mettre les journaux sur disques SSD).
Nous activons ensuite l'OSD :
ceph-deploy osd activate srv1:/dev/sdb1
Pour lister les OSD d'un cluster Ceph, vous pouvez utiliser la commande suivante :
ceph osd tree
Qui retournera dans mon exemple :
ID WEIGHT TYPE NAME UP/DOWN REWEIGHT PRIMARY-AFFINITY
-1
0
.00580
root default
-2
0
.00290
host srv1
0
0
.00290
osd.0
up 1
.00000
1
.00000
root@srv1:~#
Nous pouvons voir que notre cluster ne contient qu'un seul OSD : osd.0 sur l'hôte srv1.
1-4-3-1-6. Préparation des pools▲
Nous préparation ensuite le pool pour le système de fichiers CephFS :
ceph osd pool create cephfs_metadata 128
ceph osd pool create cephfs_data 128
La valeur de paramètre 128 correspond à la valeur de « placement group » appelé aussi PG.
Voici ce qui est préconisé par Ceph :
- moins de 5 OSD : 128 ;
- entre 5 et 10 OSD : 512 ;
- entre 10 et 50 OSD : 1024.
Au-delà de 50 OSD, il est recommandé d’utiliser la formule conseillée par les développeurs. Vous pouvez la retrouver avec l’outil en ligne pgcal.
Les « placement group » permettent d'agréger les objets en pools, permettant le suivi de ceux-ci de façon plus efficace, surtout dans des infrastructures importantes.
Listage des pool
Pour lister les pool d'un cluster Ceph, on utilisera la commande :
ceph osd lspools
Qui nous retournera :
0
rbd,1
cephfs_metadata,2
cephfs_data,
root@srv1:~#
Le pool rbd est un pool de base, qui ne nous servira pas, nous pouvons le supprimer avec la commande :
ceph osd pool delete rbd
Vous aurez un message vous expliquant qu'il faut saisir deux fois le nom du rbd suivi de –yes-i-really-really-mean-it.
1-4-3-1-7. Création d'un démon MDS▲
La création d’un démon MDS s’effectue avec la commande suivante :
ceph-deploy mds create srv1
Celui-ci sera nécessaire pour gérer les métadonnées du système de fichier CephFS.
1-4-3-1-8. Création du système de fichiers CephFS▲
La création de notre système de fichiers se fait via la commande :
root@srv1:~/cephdeploy# ceph fs new mon_fs cephfs_metadata cephfs_data
new fs with metadata pool 1
and data pool 2
root@srv1:~/cephdeploy#
mon_fs étant le nom donné au système de fichiers.
État du cluster
Nous pouvons voir l'état du cluster Ceph avec la commande :
ceph -s
Résultat :
cluster fba9a869-5b18-4feb-bd9c-5374808af689
health HEALTH_WARN
192
pgs degraded
64
pgs stuck unclean
192
pgs undersized
recovery 20
/40
objects degraded (
50
.000
%
)
monmap e1: 1
mons at {srv1
=
192
.168
.1
.200
:6789
/0
}
election epoch 3
, quorum 0
srv1
fsmap e5: 1
/1
/1
up {0
=
srv1
=
up:active}
osdmap e10: 1
osds: 1
up, 1
in
flags sortbitwise,require_jewel_osds
pgmap v22: 192
pgs, 3
pools, 2068
bytes data, 20
objects
108
MB used, 2952
MB / 3060
MB avail
20
/40
objects degraded (
50
.000
%
)
192
active+undersized+degraded
root@srv1:~#
1-4-3-1-9. Montage du volume CephFS▲
Nous commençons par déployer les fichiers de configuration avec la commande :
ceph-deploy admin srv1
Ceci va copier les fichiers suivants dans /,etc/ceph :
- ceph.client.admin.keyring ;
- ceph.conf ;
- rbdmap.
Il nous faut créer un fichier ceph.client.admin.keyring contenant la clé codée en Base64.
Le fichier a le format suivant :
[client.test]
key =
AQDR1O9bDuaFMBAAwlLxUpWYzVTtNaAAawYygA
==
Nous dupliquons le fichier client.ceph.admin.keyring dans le dossier /,etc/ceph. Nous nommons la copie client.admin.
Le fichier ne devra contenir que la clé Base64 :
AQDR1O9bDuaFMBAAwlLxUpWYzVTtNaAAawYygA
==
Exemple de commande de génération d'une clé pour un utilisateur précis :
root@srv1:~/cephdeploy# ceph auth get-or-create client.test mds 'allow' osd 'allow *' mon 'allow *' > fichier_de_keyring
Nous aurons besoin du paquet ceph-fs-common que ceph-deploy n'a pas installé :
apt-get install ceph-fs-common
Nous pourrons ensuite monter le volume avec la commande mount à laquelle nous lui aurons donné en option le nom d'utilisateur ainsi que le fichier de clé :
mount.ceph srv1:/ /mnt -o name
=
admin,secretfile
=
/etc/ceph/client.admin
Voici la ligne à ajouter dans /,etc/fstab pour un montage automatique lors du démarrage de la machine :
srv1:/ /mnt ceph name
=
admin,secretfile
=
/etc/ceph/admin.client
Il faudra garder les fichiers du dossier de configuration ceph-deploy et s'assurer d'en avoir une sauvegarde.
1-4-3-2. Ajout d'une seconde machine▲
Il faudra qu’OpenSSH, un serveur de temps et Python soit installé sur l’hôte.
Il faudra procéder à la configuration de SSH de façon à ce que srv1 puisse le contacter sans authentification. Tout cela comme pour la préparation du premier serveurPréparations.
Nous installons ensuite Ceph sur le nouveau serveur srv2 depuis srv1 :
ceph-deploy install srv2
Nous créons ensuite un OSD sur la machine srv2 de la même façon que pour srv1 :
ceph-deploy osd prepare srv2:/dev/sdb
ceph-deploy osd activate srv2:/dev/sdb1
Nous pourrons voir les deux OSD sur les deux hôtes avec la commande ceph osd tree :
root@srv1:~# ceph osd tree
ID WEIGHT TYPE NAME UP/DOWN REWEIGHT PRIMARY-AFFINITY
-1
0
.00580
root default
-2
0
.00290
host srv1
0
0
.00290
osd.0
up 1
.00000
1
.00000
-3
0
.00290
host srv2
1
0
.00290
osd.1
up 1
.00000
1
.00000
Nous pouvons voir l'état du cluster avec la commande ceph -s. Vous pourrez voir son état de reconstruction. Une fois la mise à jour des blocs sur le nouvel OSD, nous pourrons voir le cluster en mode HEALTH_OK :
root@srv1:~# ceph -s
cluster fba9a869-5b18-4feb-bd9c-5374808af689
health HEALTH_OK
monmap e1: 1
mons at {srv1
=
192
.168
.1
.200
:6789
/0
}
election epoch 4
, quorum 0
srv1
fsmap e11: 1
/1
/1
up {0
=
srv1
=
up:active}
osdmap e21: 2
osds: 2
up, 2
in
flags sortbitwise,require_jewel_osds
pgmap v140: 192
pgs, 3
pools, 6186
kB data, 34
objects
231
MB used, 5890
MB / 6121
MB avail
192
active+clean
root@srv1:~#
Nous pouvons ensuite ajouter srv2 en tant que moniteur :
ceph-deploy mon add srv2
Résultat :
…
[srv2][INFO ] monitor: mon.srv2 is currently at the state of probing
Pour rappel, le nombre de moniteurs doit être impair, et il est recommandé de mettre un moniteur sur une machine autonome hors OSD.
Sur le même principe, nous pouvons ajouter un serveur de métadonnées sur srv2 :
ceph-deploy mds create srv2
Nous modifions le fichier ceph.conf en y ajoutant l'adresse IP du second moniteur dans la ligne mon_host, puis nous mettons ensuite à jour les configurations :
ceph-deploy --overwrite-conf admin srv1 srv2
L'option -–overwite-conf étant nécessaire pour écraser une ancienne configuration (celle de srv1 dans notre cas, la commande ayant déjà été lancée dessus).
1-4-3-3. Test de panne : arrêt de srv1▲
La perte de srv1 (ou de srv2) ne provoque pas l’indisponibilité du cluster en cas de présence d'un troisième serveur hébergeant un moniteur. Dans le cas contraire, le point de montage est indisponible après quelques secondes et la commande ceph -s bloque la console.
Le redémarrage de la machine arrêtée permettra de récupérer le cluster après réparation automatique.
1-4-3-4. Procédure de réparation d'un nœud▲
Nous commençons par voir l'état de Ceph :
~# ceph -s
Qui nous affichera :
cluster 6e3c0267-1480
-4671
-9382
-9686be7e2663
health HEALTH_WARN
200
pgs degraded
200
pgs stuck degraded
200
pgs stuck unclean
200
pgs stuck undersized
200
pgs undersized
recovery 21
/63
objects degraded (
33
.333
%
)
1
mons down, quorum 0
,2
srv1,srv3
monmap e3: 3
mons at {srv1
=
192
.168
.1
.200
:6789
/0
,srv2
=
192
.168
.1
.201
:6789
/0
,srv3
=
192
.168
.1
.202
:6789
/0
}
election epoch 16
, quorum 0
,2
srv1,srv3
fsmap e9: 1
/1
/1
up {0
=
srv1
=
up:active}
osdmap e45: 3
osds: 2
up, 2
in; 200
remapped pgs
flags sortbitwise,require_jewel_osds
pgmap v189: 200
pgs, 2
pools, 23070
bytes data, 21
objects
218
MB used, 5903
MB / 6121
MB avail
21
/63
objects degraded (
33
.333
%
)
200
active+undersized+degraded
Pour voir ce qu’il en est des OSD :
~# ceph osd tree
Qui nous retournera :
ID WEIGHT TYPE NAME UP/DOWN REWEIGHT PRIMARY-AFFINITY
-1
0
.00870
root default
-2
0
.00290
host srv1
0
0
.00290
osd.0
up 1
.00000
1
.00000
-3
0
.00290
host srv2
1
0
.00290
osd.1
down 0
1
.00000
-4
0
.00290
host srv3
2
0
.00290
osd.2
up 1
.00000
1
.00000
Nous voyons que l’OSD.1 sur l'hôte srv2 est « down ». Nous le supprimons :
~# ceph osd rm osd.1
removed osd.1
Nous rappelons la commande ceph osd tree :
~# ceph osd tree
ID WEIGHT TYPE NAME UP/DOWN REWEIGHT PRIMARY-AFFINITY
-1
0
.00870
root default
-2
0
.00290
host srv1
0
0
.00290
osd.0
up 1
.00000
1
.00000
-3
0
.00290
host srv2
1
0
.00290
osd.1
DNE 0
-4
0
.00290
host srv3
2
0
.00290
osd.2
up 1
.00000
1
.00000
Nous voyons l’OSD 1 toujours présent en mode DNE (pour Do Not Exist).
Nous supprimons celui-ci définitivement avec la commande suivante :
~# ceph osd crush rm osd.1
removed item id 1
name 'osd.1'
from crush map
Nous supprimons ensuite les autorisations :
~# ceph auth del osd.1
updated
Si nous rappelons la commande ceph osd tree, l'OSD n'est plus présent, mais nous voyons toujours le nœud (sans OSD) :
ID WEIGHT TYPE NAME UP/DOWN REWEIGHT PRIMARY-AFFINITY
-1
0
.00580
root default
-2
0
.00290
host srv1
0
0
.00290
osd.0
up 1
.00000
1
.00000
-3
0
host srv2
-4
0
.00290
host srv3
2
0
.00290
osd.2
up 1
.00000
1
.00000
Pour supprimer celui-ci, nous allons l'enlever de la crush map.
Nous commençons par exporter celle-ci avec la commande getcrushmap.
~# ceph osd getcrushmap -o crush_map
got crush map from osdmap epoch 79
Il va falloir convertir ce fichier en mode texte :
~# crushtool -d crush_map -o crush_map.txt
Voici un exemple du contenu de ce fichier texte :
# begin crush map
tunable choose_local_tries 0
tunable choose_local_fallback_tries 0
tunable choose_total_tries 50
tunable chooseleaf_descend_once 1
tunable chooseleaf_vary_r 1
tunable straw_calc_version 1
# devices
device 0
osd.0
device 1
device1
device 2
osd.2
# types
type 0
osd
type 1
host
type 2
chassis
type 3
rack
type 4
row
type 5
pdu
type 6
pod
type 7
room
type 8
datacenter
type 9
region
type 10
root
# buckets
host srv1 {
id -2
# do not change unnecessarily
# weight 0.003
alg straw
hash 0
# rjenkins1
item osd.0
weight 0
.003
}
host srv3 {
id -4
# do not change unnecessarily
# weight 0.003
alg straw
hash 0
# rjenkins1
item osd.2
weight 0
.003
}
host srv2 {
id -3
# do not change unnecessarily
# weight 0.000
alg straw
hash 0
# rjenkins1
}
root default {
id -1
# do not change unnecessarily
# weight 0.006
alg straw
hash 0
# rjenkins1
item srv1 weight 0
.003
item srv3 weight 0
.003
item srv2 weight 0
.000
}
# rules
rule replicated_ruleset {
ruleset 0
type replicated
min_size 1
max_size 10
step take default
step chooseleaf firstn 0
type host
step emit
}
# end crush map
Modifier la crush map va permettre d'optimiser la gestion du cluster Ceph notamment dans le cas de nœuds importants (gestion de régions, rack, pds, etc.)
Je retire les références à srv2 (le bloc srv2 entre crochets, et la ligne item srv2...)
Pour appliquer les modifications, je recompile le fichier texte :
~# crushtool -c crush_map.txt -o crush_map
Puis applique celui-ci :
~# ceph osd setcrushmap -i crush_map
set crush map
Toute trace de srv2 dans les OSD est alors supprimée.
Nous préparons ensuite un serveur de base avec les prérequis (adresse IP de srv2, nom de machine srv2, fichier hosts renseigné avec les autres serveurs, paquets ntp, openssh-server, et python installé).
Nous recopions ensuite la clé SSH de srv1 vers srv2 :
~# ssh-copy-id root@srv2
Nous allons avoir un message d'erreur :
/usr/bin/ssh-copy-id: INFO: Source of key
(
s) to be installed: "/root/.ssh/id_rsa.pub"
/usr/bin/ssh-copy-id: INFO: attempting to log in
with the new key
(
s), to filter out any that are already installed
/usr/bin/ssh-copy-id: ERROR: @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
ERROR: @ WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!
@
ERROR: @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
ERROR: IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!
ERROR: Someone could be eavesdropping on you right now (
man-in
-the-middle attack)!
ERROR: It is also possible that a host key has just been changed.
ERROR: The fingerprint for
the ECDSA key sent by the remote host is
ERROR: SHA256:GXC4wVDCLG3a+KXA3Tb95ULTZGm2REM0pmOBBCZ371A.
ERROR: Please contact your system administrator.
ERROR: Add correct host key in
/root/.ssh/known_hosts to get rid of this message.
ERROR: Offending ECDSA key in
/root/.ssh/known_hosts:5
ERROR: remove with:
ERROR: ssh-keygen -f "/root/.ssh/known_hosts"
-R srv2
ERROR: ECDSA host key for
srv2 has changed and you have requested strict checking.
ERROR: Host key verification failed.
Nous utilisons la commande ssh-keygen :
~# ssh-keygen -f "/root/.ssh/known_hosts" -R srv2
# Host srv2 found: line 5
/root/.ssh/known_hosts updated.
Original contents retained as /root/.ssh/known_hosts.old
Nous refaisons une tentative de connexion :
ssh root@srv2
The authenticity of host 'srv2 (192.168.1.201)'
can't be established.
ECDSA key fingerprint is SHA256:GXC4wVDCLG3a+KXA3Tb95ULTZGm2REM0pmOBBCZ371A.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '
srv2' (ECDSA) to the list of known hosts.
Warning: the ECDSA host key for '
srv2' differs from the key for the IP address '
192
.168
.1
.201
'
Offending key for IP in /root/.ssh/known_hosts:5
Are you sure you want to continue connecting (yes/no)? yes
root@srv2'
s password:
Nous entrons le mot de passe. La prochaine connexion donnera :
Offending key for
IP in
/root/.ssh/known_hosts:5
Matching host key in
/root/.ssh/known_hosts:6
Are you sure you want to continue
connecting (
yes/no)? yes
Nous supprimons la ligne concernée :
~# sed -i '5d' ~/.ssh/known_hosts
La commande ssd-copy-id pourra ensuite s’exécuter sans erreur, et une connexion via ssh root@srv2 sans demande de mot de passe sera possible.
Nous réinstallons ensuite Ceph :
~# ceph-deploy install srv2
Nous recréons ensuite les OSD comme vu précédemmentAjout d'OSD.
Nous réinstallons le moniteur sur srv2 :
ceph mon add srv2
Nous lançons la commande ceph health. Une fois la réparation terminée, la commande ceph -s nous donnera un statut de HEALTH_OK.
1-5. min.io▲
min.io est un système de stockage cloud open source, crée par un ancien de l’équipe Gluster. Il peut être utilisé avec une configuration de 2 à 32 serveurs et stocker des objets jusqu’à 5 To. Il ne possède pas de limite sur le nombre de buckets (notion que nous verrons plus tard) ou d’objets par bucket.
Il peut se comporter comme le service S3 d’Amazon ou faire passerelle avec le service S3 Amazon. Il peut également faire passerelle NFS .
Il est prévu d’origine pour fonctionner dans Docker.
1-5-1. Les différents modes de fonctionnement▲
Default mode : c'est le mode par défaut de fonctionnement de min.io quand utilisé avec une seule machine et un seul disque.
Erasure coded mode : mode permettant la reconstruction des données en cas de perte de ressource. Cet algorithme est basé sur l'algorithme Reed-Solomon. Ce mode nécessite un minimum de quatre disques.
Distributed mode : le serveur min.io en mode distribué vous permet de mettre en pool plusieurs lecteurs (même sur différentes machines) sur un serveur de stockage d'objet unique. Les disques étant répartis sur plusieurs nœuds, min.io distribué peut supporter plusieurs défaillances tout en assurant une protection complète des données.
1-5-2. Installation de min.io▲
min.io est un simple exécutable. Il est récupérable sur le site officiel à l'adresse https://min.io/download ou comme ceci :
wget https://dl.min.io/server/minio/release/linux-amd64/minio
il faudra ensuite mettre les droits d’exécution :
chmod +x minio
Nous déplacerons ensuite le fichier dans /usr/local/bin.
Il est également possible d’installer min.io au travers de brew pour Mac OS X.
Il suffira ensuite de taper la commande minio pour obtenir de l’aide.
1-5-3. Test en mode simple instance▲
Nous allons lancer min.io en fournissant le dossier /data1/minio1 en paramètre :
minio server /data1/minio1
Ce qui donne :
Endpoint: http://192
.168
.1
.200
:9000
http://127
.0
.0
.1
:9000
AccessKey: minioadmin
SecretKey: minioadmin
Browser Access:
http://192
.168
.1
.200
:9000
http://127
.0
.0
.1
:9000
Command-line Access: https://docs.min.io/docs/minio-client-quickstart-guide
$
mc config host add myminio http://192
.168
.1
.200
:9000
minioadmin minioadmin
Object API (
Amazon S3 compatible):
Go: https://docs.min.io/docs/golang-client-quickstart-guide
Java: https://docs.min.io/docs/java-client-quickstart-guide
Python: https://docs.min.io/docs/python-client-quickstart-guide
JavaScript: https://docs.min.io/docs/javascript-client-quickstart-guide
.NET: https://docs.min.io/docs/dotnet-client-quickstart-guide
Detected default credentials 'minioadmin:minioadmin'
, please change the credentals immediately using 'MINIO_ACCESS_KEY'
and 'MINIO_SECRET_KEY'
Le retour de la commande nous donne toutes les méthodes d'accès possibles.
Nous pouvons notamment voir que l’accès peut se faire depuis le web via le port 9000. Il est possible de changer le port par défaut en le précisant dans la ligne d'appel sous la forme http://192.168.1.200:9000.
Il est également précisé que l’identifiant et mot de passe par défaut est « minioadmin ». Il faudra bien sûr le changer.
Pour cela il suffit d'exporter les variables MINIO_ACCESS_KEY et MINIO_SECRET_KEY.
MINIO_SECRET_KEY doit faire minium huit caractères.
~# export MINIO_ACCESS_KEY=admin
~# export MINIO_SECRET_KEY=rootroot
~# ./minio server /data1
Attempting encryption of all config, IAM users and policies on MinIO backend
Endpoint: http://192.168.1.200:9000 http://127.0.0.1:9000
AccessKey: admin
SecretKey: rootroot
Browser Access:
http://192.168.1.200:9000 http://127.0.0.1:9000
Command-line Access: https://docs.min.io/docs/minio-client-quickstart-guide
$ mc config host add myminio http://192.168.1.200:9000 admin rootroot
Object API (Amazon S3 compatible):
Go: https://docs.min.io/docs/golang-client-quickstart-guide
Java: https://docs.min.io/docs/java-client-quickstart-guide
Python: https://docs.min.io/docs/python-client-quickstart-guide
JavaScript: https://docs.min.io/docs/javascript-client-quickstart-guide
.NET: https://docs.min.io/docs/dotnet-client-quickstart-guide
1-5-3-1. Accès via le web▲
Le login et le mot de passe correspondent à l’accessKey et la SecretKey retourné par l’appel de min.io .
1-5-3-2. Gestion de fichiers depuis l'interface web▲
Une fois logué, vous obtiendrez l’écran suivant :
Il va nous falloir créer au moins un Bucket, entité de stockage de min.io, qui peut être considéré comme un dossier, ceci en cliquant sur le , puis « create Bucket » :
Après création, les Buckets apparaîtront sur la gauche (dans notre cas bucket1, puis bucket2) :
Lors de la création des Buckets, ceux-ci ne sont affichés dans l’ordre alphabétique qu’après rafraîchissement par clic sur l’adresse en bas à gauche.
La création d'un Bucket va créer un dossier du même nom dans le système de fichiers (dans le dossier /data1 dans notre cas). La création d'un dossier hors de l'interface va être vue comme un Bucket dans l'interface web.
Un sous-dossier créé en ligne de commande sera exploitable depuis l'interface web :
Il sera possible d'entrer dans le dossier, d'y uploader des fichiers. Par contre, il n’y a pas d'option dans l'interface web pour créer un sous-dossier.
La suppression d'un Bucket (un dossier) se fera en se mettant sur celui-ci et en cliquant sur les traits :
La suppression d'un Bucket va supprimer son contenu.
1-5-3-2-1. Upload de fichier▲
Pour uploader un fichier, il faut cliquer sur le , puis sur l’icône upload file
Les fichiers apparaîtront sur le disque tels quels. Si vous ajoutez un fichier manuellement dans le dossier/Bucket, celui-ci sera disponible dans l'interface.
1-5-3-2-2. Accès aux fichiers▲
L’icône en 1 permet de créer un lien de partage dont la validité peut s’étendre jusqu’à sept jours. Il n’y a pas de possibilité de créer un lien permanent. L’icône 2 permet la suppression du document. Il n’y a pas de système de versionnage. Même si on peut utiliser un accès web, il s’agit d’un espace de stockage, pas d’un service de synchronisation de fichiers comme ceux déjà vus.
Il ne semble pas possible de renommer un fichier.
Il est possible de télécharger le fichier en cliquant sur le rond à gauche du nom. Une barre apparaîtra en haut de l’écran permettant le téléchargement (ainsi que la suppression comme avec l’icône vue sur l’écran précédent) :
1-5-3-2-3. Utilisation de https▲
La clé privée (qui doit se nommer private.key) et la clé publique (qui doit se nommer public.crt) doivent être placées dans le dossier de configuration par défaut : .minio/certs (créé dans le dossier à partir duquel vous avez lancé min.io). Il est possible de préciser le chemin d'emplacement des clés avec l'option --cert.
La sécurisation de la connexion au serveur web de min.io est détaillée dans cette page de documentation : https://docs.min.io/docs/how-to-secure-access-to-minio-server-with-tls.html.
1-5-4. Test en mode distribué▲
Le mode distribué nécessite la déclaration d’au minimum quatre sources dont au moins deux accessibles. Il est possible de déclarer plusieurs sources sur le même nœud. Cela n'aura un sens qu'en cas de sources sur différents disques (un peu comme du RAID).
L’erasure code est un mécanisme permettant la redondance des données. Celui-ci utilise l’algorithme de Reed Salomon et permet de gérer l’espace utilisé pour la redondance. Par exemple : avec douze disques, vous pourrez utiliser six disques de données et six de parité ; ou bien dix disques de données et deux de parité. Plus vous avez de disques de parité, plus vous pourrez supporter de pertes de disques simultanés.
Pour créer un cluster distribué, nous préparons deux volumes data1 et data2 (sur deux disques différents) sur un même nœud.
Minio refusera de démarrer si les volumes déclarés sont sur le disque de démarrage.
Nous stockons l’AccessKey et la SecretKey dans les variables d’environnement (reprise des clés précédemment utilisées) :
export MINIO_ACCESS_KEY
=
XLI1NFFBHMAR5LFTTXD8
export MINIO_SECRET_KEY
=
+4tHexZ4EUU0Ltbo1gQVfTJ6bFcGTZGtRqYNHpmz
Puis appelons la commande :
./minio server http://192
.168
.1
.200
/data1 http://192
.168
.1
.200
/data2 http://192
.168
.1
.201
/data3 http://192
.168
.1
.201
/data4
Qui retourne :
root@ubuntu:~# ./minio server http://192.168.1.200/data1 http://192.168.1.200/data2 http://192.168.1.201/data3 http://192.168.1.201/data4
Waiting for
a minimum of 2
disks to come online (
elapsed 3s)
Waiting for
a minimum of 2
disks to come online (
elapsed 6s)
Waiting for
a minimum of 2
disks to come online (
elapsed 9s)
Il n'est pas possible de passer un volume précédemment démarré en mode unique sans effacer les métadonnées contenues dans le dossier .minio.sys présent dans le volume précédemment créé.
En mode distribué, l'utilisation de clés d'accès est obligatoire.
Nous voyons que le cluster attend la disponibilité d’au minimum deux disques pour démarrer.
Installons un second hôte.
Le second serveur devra être accessible en SSH sans demande de mot de passe.
Une fois l’exécutable minio copié, les volumes data1 et data2 préparés, puis les variables MINIO_ACCESS_KEY et MINIO_SECRET_KEY positionnées, au 1er lancement sur le second hôte, nous verrons :
root@ubuntu:~# ./minio server http://192.168.1.200/data1 http://192.168.1.200/data2 http://192.168.1.201/data3 http://192.168.1.201/data4
Waiting for
the first server to format the disks.
Waiting for
the first server to format the disks.
Waiting for
the first server to format the disks.
Waiting for
the first server to format the disks.
Status: 4
Online, 0
Offline.
Endpoint: http://192
.168
.1
.201
:9000
http://127
.0
.0
.1
:9000
AccessKey: XLI1NFFBHMAR5LFTTXD8
SecretKey: +4tHexZ4EUU0Ltbo1gQVfTJ6bFcGTZGtRqYNHpmz
Browser Access:
http://192
.168
.1
.201
:9000
http://127
.0
.0
.1
:9000
Command-line Access: https://docs.minio.io/docs/minio-client-quickstart-guide
$
mc config host add myminio http://192
.168
.1
.201
:9000
XLI1NFFBHMAR5LFTTXD8 +4tHexZ4EUU0Ltbo1gQVfTJ6bFcGTZGtRqYNHpmz
Object API (
Amazon S3 compatible):
Go: https://docs.minio.io/docs/golang-client-quickstart-guide
Java: https://docs.minio.io/docs/java-client-quickstart-guide
Python: https://docs.minio.io/docs/python-client-quickstart-guide
JavaScript: https://docs.minio.io/docs/javascript-client-quickstart-guide
.NET: https://docs.minio.io/docs/dotnet-client-quickstart-guide
La commande minio doit donc être lancée sur les deux machines.
1-5-4-1. Tests▲
Depuis l’interface web, nous créons ensuite deux buckets et uploadons quelques fichiers dans chaque bucket.
Nous pouvons ensuite observer la présence d’un dossier par bucket dans /data1 et dans /data2, sur les deux hôtes. La réplication s’effectue entre les deux disques locaux et sur les deux hôtes. Nous avons donc quatre exemplaires visibles, répartis sur deux hôtes.
Nous pouvons également observer que chaque fichier uploadé se présente sous forme d'un dossier portant le nom du fichier et contenant un fichier part.1 (ou, selon la taille, plusieurs fichiers part.x) dans un dossier avec un nom représentant un UUID, et un fichier xl.meta. Le fichier part.1 n’est pas exploitable. L’accès aux fichiers n’est donc pas possible sans passer par l’interface web.
1-5-4-2. Passage en mode démon▲
Nous allons installer minio en mode démon. Nous commençons par fixer les variables dans le fichier /,etc/default/minio :
MINIO_VOLUMES
=
https://192
.168
.1
.200
/data1 https://192
.168
.1
.201
/data1 https://192
.168
.1
.202
/data1 https://192
.168
.1
.203
/data1
MINIO_ACCESS_KEY
=
XLI1NFFBHMAR5LFTTXD8
MINIO_SECRET_KEY
=
+4tHexZ4EUU0Ltbo1gQVfTJ6bFcGTZGtRqYNHpmz
Nous allons ensuite utiliser le script de laudukang :
[Unit]
Description
=
Minio
Documentation
=
https://docs.minio.io
Wants
=
network-online.target
After
=
network-online.target
AssertFileIsExecutable
=
/usr/local
/bin/minio
[Service]
WorkingDirectory
=
/usr/local
User
=
root
Group
=
root
PermissionsStartOnly
=
true
EnvironmentFile
=
-/etc/default/minio
ExecStartPre
=
/bin/bash -c "if [ -z \"
${MINIO_VOLUMES}
\" ]; then echo \"Variable MINIO_VOLUMES not set in /etc/default/minio\"; exit 1; fi"
ExecStartPre
=
/bin/bash -c "if [ -z \"
${MINIO_ACCESS_KEY}
\" ]; then echo \"Variable MINIO_ACCESS_KEY not set in /etc/default/minio\"; exit 1; fi"
ExecStartPre
=
/bin/bash -c "if [ -z \"
${MINIO_SECRET_KEY}
\" ]; then echo \"Variable MINIO_SECRET_KEY not set in /etc/default/minio\"; exit 1; fi"
ExecStart
=
/usr/local
/bin/minio server $MINIO_OPTS
$MINIO_VOLUMES
# Let systemd restart this service only if it has ended with the clean exit code or signal.
Restart
=
on-success
StandardOutput
=
journal
StandardError
=
inherit
# Specifies the maximum file descriptor number that can be opened by this process
LimitNOFILE
=
65536
# Disable timeout logic and wait until process is stopped
TimeoutStopSec
=
0
# SIGTERM signal is used to stop Minio
KillSignal
=
SIGTERM
SendSIGKILL
=
no
SuccessExitStatus
=
0
[Install]
WantedBy
=
multi-user.target
# Built for ${project.name}-${project.version} (${project.name})
Nous pouvons voir que le démon attend la commande minio dans /usr/local/bin et en utilisateur root, ce que vous pouvez changer si vous le souhaitez. Nous pouvons également voir que le script récupère les variables dans /,etc/default/minio.
Nous plaçons donc le script dans le fichier /etc/systemd/system/minio.service avec les droits 755.
Nous enregistrons ensuite le service :
systemctl daemon-reload
systemctl enable minio
Ce qui renvoie :
Created symlink from /etc/systemd/system/multi-user.target.wants/minio.service to /etc/systemd/system/minio.service.
root@ubuntu:~#
Nous arrêtons ensuite min.io sur les deux machines et lançons le service sur les deux hôtes, après avoir effectué la copie des fichiers de configuration d'une machine à l'autre.
Pour utiliser le mode https, il faudra ajouter la ligne suivante :
MINIO_OPTS
=
"-C /,etc/minio"
puis copier les clés .key et .crt dans le dossier /,etc/minio/certs.
1-5-5. Client min.io▲
Pour accéder aux buckets min.io depuis la ligne de commande, nous pouvons utiliser le client min.io nommé mc (ne pas confondre avec Midnight Commander) téléchargeable à l’adresse :
https://dl.min.io/client/mc/release/linux-amd64/mc
Un simple appel sans paramètres donnera la liste des options :
~# ./mc
mc: Configuration written to `/root/.mc/config.json`
. Please update your access credentials.
mc: Successfully created `/root/.mc/share`
.
mc: Initialized share uploads `/root/.mc/share/uploads.json`
file.
mc: Initialized share downloads `/root/.mc/share/downloads.json`
file.
NAME:
mc - Minio Client for
cloud storage and filesystems.
USAGE:
mc [FLAGS] COMMAND [COMMAND FLAGS |
-h] [ARGUMENTS...]
COMMANDS:
ls list buckets and objects
mb make a bucket
cat display object contents
pipe stream STDIN to an object
share generate URL for
temporary access to an object
cp copy objects
mirror synchronize object
(
s) to a remote site
find search for
objects
sql run sql queries on objects
stat show object metadata
diff list differences in
object name, size, and date between two buckets
rm remove objects
event configure object notifications
watch listen for
object notification events
policy manage anonymous access to buckets and objects
admin manage minio servers
session resume interrupted operations
config configure minio client
update update mc to latest release
version show version info
GLOBAL FLAGS:
--config-dir value, -C value path to configuration folder (
default: "/root/.mc"
)
--quiet, -q disable progress bar display
--no-color disable color theme
--json enable JSON formatted output
--debug enable debug output
--insecure disable SSL certificate verification
--help, -h show help
--version, -v print the version
VERSION:
RELEASE.2018
-12
-27T00-37
-49Z
Nous reconnaissons les commandes classiques du shell.
Nous commençons par créer un alias pour faciliter l’accès, et comme indiqué lors de l’appel à la commande minio server :
mc config host add minioalias http://192
.168
.1
.200
:9000
XLI1NFFBHMAR5LFTTXD8 +4tHexZ4EUU0Ltbo1gQVfTJ6bFcGTZGtRqYNHpmz
Ce qui retourne :
mc: Configuration written to `/root/.mc/config.json`
. Please update your access credentials.
mc: Successfully created `/root/.mc/share`
.
mc: Initialized share uploads `/root/.mc/share/uploads.json`
file.
mc: Initialized share downloads `/root/.mc/share/downloads.json`
file.
Added `minioalias`
successfully.
Nous pouvons consulter le contenu de l’hôte via la commande mc ls suivi du nom de l’alias :
~# ./mc ls minioalias
[2018
-12
-27
13
:49
:34
CET] 0B dossier1/
[2018
-12
-27
13
:49
:51
CET] 0B dossier2/
~#
La commande cp permettra de copier des fichiers dans le cluster ou d’en récupérer depuis celui-ci.
Il n’y a pas de notion de sous-dossier avec min.io. Par contre, si vous copiez le fichier fichier.txt avec la commande suivante :
./mc cp fichier.txt minioalias/dossier1/textes/fichier.txt
vous pourrez voir l’arborescence texte.
Si vous copiez plusieurs fichiers dans le chemin minioalias/dossier1/textes, vous pourrez les voir avec la commande ./mc ls minioalias/dossier1/textes.
1-5-6. Fonctionnement en mode S3▲
Pour cet usage, j’ai testé s3fs qui permet de monter un volume S3 avec FUSE.
Il va nous falloir créer un fichier /etc/passwd-s3fs pour la connexion de la forme identifiant:clé
Dans notre cas, ce sera :
XLI1NFFBHMAR5LFTTXD8:+4tHexZ4EUU0Ltbo1gQVfTJ6bFcGTZGtRqYNHpmz
Ensuite, le volume peut être monté avec s3fs :
s3fs <
nom du bucket>
/mnt -o use_path_request_style,url
=
http://192
.168
.1
.200
:9000
À partir de ce point de montage, le Bucket est accessible comme n’importe quel autre point de montage.
1-5-7. Sauvegarde▲
Pour les sauvegardes, le plus simple est de sauvegarder depuis un point de montage s3fs.
1-5-8. Test d’arrêt d’un des serveurs▲
Lors de l’arrêt d’un des serveurs, les données restent accessibles, mais en lecture seule. Après redémarrage du serveur, la situation se débloque.
1-5-8-1. Perte définitive d’un serveur▲
La situation ne revient pas à la normale même si vous préparez un nouveau serveur en copiant les fichiers /usr/local/bin/minio, /,etc/default/minio, recréant les points de montages data1 et data2.
Je commence par créer un alias pour la commande mc pointant sur le serveur fonctionnel :
~# ./mc config host add minioalias http://192.168.1.200:9000 XLI1NFFBHMAR5LFTTXD8 +4tHexZ4EUU0Ltbo1gQVfTJ6bFcGTZGtRqYNHpmz
Added `minioalias`
successfully.
Je lance la réparation avec la commande ./mc admin heal minioalias :
~# ./mc admin heal minioalias
◓ dossier2
0
/0
objects; 0
B in
3s
┌────────┬───┬─────────────────────┐
│ Green │ 4
│ 100
.0
%
████████████ │
│ Yellow │ 0
│ 0
.0
%
│
│ Red │ 0
│ 0
.0
%
│
│ Grey │ 0
│ 0
.0
%
│
└────────┴───┴─────────────────────┘
Ceci va recréer l’arborescence, mais ne suffira pas pour les fichiers
Il faudra ajouter la commande ./mc admin heal minioalias --recursive.
Vous verrez défiler le nom des fichiers, la console restant sur le dernier fichier synchronisé.
~# ./mc admin heal minioalias --recursive
◐ dossier2/pydio.pdf
7
/7
objects; 2
MiB in
6s
┌────────┬────┬─────────────────────┐
│ Green │ 11
│ 100
.0
%
████████████ │
│ Yellow │ 0
│ 0
.0
%
│
│ Red │ 0
│ 0
.0
%
│
│ Grey │ 0
│ 0
.0
%
│
└────────┴────┴─────────────────────┘
1-5-9. Ajout de serveur▲
Pour ajouter un serveur supplémentaire, il faudra modifier le fichier /,etc/default/minio sur les deux serveurs existants (ajout dans la ligne MINIO_VOLUMES= du fichier /,etc/default/minio).
1-6. Bilan▲
GlusterFS est une solution souple et relativement simple. Je n'utiliserais pas la méthode DRBD/OCFS, car la désynchronisation est trop facile, et la nouvelle version, paraissant plus souple, m'a posé des difficultés (mais il s'agit ici d'un point de vue personnel).
La solution Ceph est complexe, mais offre l’avantage de s'autoréparer en cas de problème. Ceph est adapté aux solutions à grande échelle et est utilisé par OpenStack, OpenNebula. Elle reste complexe à mettre en place, mais fait référence.
1-7. Quid de Windows ?▲
Il est possible de gérer un système de fichiers distribués avec Windows via un Active Directory en utilisant DFSR (Distributed FileSystem Replication).
DFS permet de faire de la répartition de données (une partie sur chaque serveur, vue à partir d’un seul point d'accès) ou de la redondance en répliquant les données d'un serveur à un autre.
Il faudra sur un Windows Server avec Active Directory fonctionnel installer le rôle « Réplication DFS », puis depuis le menu outil du gestionnaire de serveurs aller dans « Gestion du système de fichiers distribués DFS ».
Dans le gestionnaire DFS qui va s'ouvrir, il va falloir faire un clic droit sur Espace de noms→ Nouvel espace de noms.
Une fois l'espace de nom créé, il faudra ajouter les dossiers cibles de chaque serveur.
Vous pourrez sélectionner une réplication en temps réel ou planifier la fréquence.
1-8. Quid de Mac OS X ?▲
Mac OS X ou mac OS Server ne proposent aucun système de fichiers distribués. Il pourra se connecter à un DFS Active Directory.
Pour se référer à ce qui a été vu dans ce tutoriel, GlusterFS n'est actuellement pas compatible Mac OS.
Il est possible de compiler Ceph via Homebrew, mais cela me parait trop expérimental pour une utilisation en production.
2. Conclusion▲
J'espère que ce tutoriel vous a éclairé sur les systèmes de fichier distribués.
3. Remerciements▲
Je remercie Mickael Baron, khayyam90, LittleWhite, et Louis-Guillaume Morland pour leur relecture technique.
Je remercie Claude Leloup pour sa relecture orthographique.