GlusterFS comme stockage externe pour Kubernetes

image
Trouver le stockage optimal est un processus assez compliqué, tout a ses avantages et ses inconvénients. Bien sûr, le leader dans cette catégorie est CEPH, mais c'est un système assez complexe, mais avec des fonctionnalités très riches. Pour nous, un tel système est redondant, étant donné que nous avions besoin d'un stockage répliqué simple en mode maître-maître pour quelques téraoctets. Après avoir étudié beaucoup de matériel, il a été décidé de tester le produit le plus en vogue du marché pour le circuit qui nous intéresse. Étant donné qu'aucune solution toute faite d'un tel plan n'a été trouvée, je voudrais partager mes meilleures pratiques sur ce sujet et décrire les problèmes que nous avons rencontrés dans le processus de déploiement.

Buts


Qu'attendions-nous du nouveau dépôt:

  • Possibilité de travailler avec un nombre pair de nœuds pour la réplication.
  • Installation, configuration et assistance faciles
  • Le système doit être adulte, éprouvé et utilisateurs
  • Possibilité d'agrandir l'espace de stockage sans interruption
  • Le stockage doit être compatible avec Kubernetes
  • Il devrait y avoir un basculement automatique lorsque l'un des nœuds plante

C'est sur le dernier point que nous avons beaucoup de questions.

Déploiement


Pour le déploiement, deux machines virtuelles ont été créées sur CentOs 8. Chacune d'entre elles est connectée via un disque supplémentaire avec stockage.

Préparation préliminaire


Pour GlusterFS, vous devez allouer un disque séparé avec XFS afin qu'il n'affecte en rien le système.

Sélectionnez la partition:

$ fdisk /dev/sdb
Command (m for help): n
Partition type
   p   primary (0 primary, 0 extended, 4 free)
   e   extended (container for logical partitions)
Select (default p): p
Partition number (1-4, default 1):  1
First sector (2048-16777215, default 2048): 
Last sector, +sectors or +size{K,M,G,T,P} (2048-16777215, default 16777215): 
 
Created a new partition 1 of type ‘Linux’ and of size 8 GiB.
Command (m for help): w 

The partition table has been altered.
Calling ioctl() to re-read partition table. Syncing disks.

Format en XFS et montage:

$ mkfs.xfs /dev/sdb1
$ mkdir /gluster
$ mount /dev/sdb1 /gluster

Et pour couronner le tout, déposez l'entrée dans / etc / fstab pour monter automatiquement le répertoire au démarrage du système:

/dev/sdb1       /gluster        xfs     defaults        0       0

Installation


Concernant l'installation, de nombreux articles ont été écrits, à cet égard nous n'entrerons pas en profondeur dans le processus, nous allons juste réfléchir à ce à quoi il faut prêter attention.

Sur les deux nœuds, installez et exécutez la dernière version de glusterfs:

$ wget -P /etc/yum.repos.d  https://download.gluster.org/pub/gluster/glusterfs/LATEST/CentOS/glusterfs-rhel8.repo
$ yum -y install yum-utils
$ yum-config-manager --enable PowerTools
$ yum install -y glusterfs-server
$ systemctl start glusterd

Ensuite, vous devez indiquer au glaster où se trouve son nœud voisin. Cela se fait avec un seul nœud. Un point important: si vous avez un réseau de domaine, vous devez spécifier le nom du serveur avec le domaine, sinon à l'avenir vous devrez tout refaire.

$ gluster peer probe gluster-02.example.com

S'il a réussi, nous vérifions la connexion avec la commande des deux serveurs:

$ gluster peer status
Number of Peers: 1

Hostname: gluster-02.example.com
Uuid: a6de3b23-ee31-4394-8bff-0bd97bd54f46
State: Peer in Cluster (Connected)
Other names:
10.10.6.72

Vous pouvez maintenant créer un volume dans lequel nous écrirons.

gluster volume create main replica 2 gluster-01.example.com:/gluster/main gluster-02.example.com:/gluster/main force

Où:

  • main - nom Volume
  • réplique - type Volume (plus de détails peuvent être trouvés dans la documentation officielle )
  • 2 - nombre de répliques

Exécutez Volume et vérifiez ses performances:

gluster volume start main
gluster volume status main

Pour le volume répliqué, il est recommandé de définir les paramètres suivants:

$ gluster volume set main network.ping-timeout 5
$ gluster volume set main cluster.quorum-type fixed
$ gluster volume set main cluster.quorum-count 1
$ gluster volume set main performance.quick-read on

Avec ces étapes simples, nous avons construit un cluster GlusterFS. Reste à s'y connecter et à vérifier les performances. Ubuntu est installé sur la machine client, pour le montage, vous devez installer le client:

$ add-apt-repository ppa:gluster/glusterfs-7
$ apt install glusterfs-client
$ mkdir /gluster
$ mount.glusterfs gluster-01.example.com:/main /gluster

Gluster, lorsqu'il est connecté à l'un des nœuds, donne les adresses de tous les nœuds et se connecte automatiquement à tous. Si le client est déjà connecté, la panne d'un des nœuds n'entraînera pas d'arrêt. Mais si le premier nœud n'est pas disponible, il ne sera pas possible de se connecter en cas de rupture de session. Pour ce faire, lors du montage, vous pouvez passer le paramètre backupvolfile indiquant le deuxième noeud.
mount.glusterfs gluster-01.example.com:/main /gluster -o backupvolfile-server=gluster-02.example.com

Un point important: gluster synchronise les fichiers entre les nœuds uniquement si leur modification a été effectuée via le volume monté. Si vous apportez des modifications directement sur les nœuds, le fichier sera désynchronisé.

Connectez-vous à Kubernetes


À ce stade, les questions ont commencé: «Comment le connecter?». Et il y a plusieurs options. Considérez-les.

Heketi


Le plus populaire et recommandé est d'utiliser un service externe: heketi. heketi est une couche entre kubernetes et gluster, qui vous permet de gérer et de travailler avec le stockage via http. Mais heketi sera ce seul point d'échec, car le service n'est pas en cluster. La deuxième instance de ce service ne pourra pas fonctionner de manière indépendante, car toutes les modifications sont stockées dans la base de données locale. L'exécution de ce service dans kubernetes ne convient pas non plus, car il a besoin d'un disque statique sur lequel sa base de données sera stockée. À cet égard, cette option s'est avérée la plus inappropriée.

Endpoint chez Kubernetes


Si vous avez Kubernetes sur des systèmes avec des gestionnaires de packages, alors c'est une option très pratique. Le fait est que pour tous les serveurs GlusteFS de Kubernetes, un point de terminaison commun est créé. Un service est suspendu sur ce point de terminaison et nous serons déjà montés sur ce service. Pour que cette option fonctionne, il est nécessaire d'installer glusterfs-client sur chaque nœud Kubernetes et de vous assurer qu'il peut être monté. Dans Kubernetes, déployez la configuration suivante:

apiVersion: v1
kind: Endpoints
metadata: 
  name: glusterfs-cluster
subsets:
  - addresses:
      #  ip  
      - ip: 10.10.6.71
    ports:
      #    1,    
      - port: 1
  - addresses:
      - ip: 10.10.6.72
    ports:
      - port: 1

---
apiVersion: v1
kind: Service
metadata:
  name: glusterfs-cluster
spec:
  ports:
  - port: 1

Nous pouvons maintenant créer un déploiement de test simple et vérifier le fonctionnement du montage. Voici un exemple de déploiement de test simple:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: gluster-test
spec:
  replicas: 1
  selector:
    matchLabels:
      app: gluster-test
  template:
    metadata:
      labels:
        app: gluster-test
    spec:
      volumes:
      - name: gluster
        glusterfs:
          endpoints: glusterfs-cluster
          path: main
      containers:
      - name: gluster-test
        image: nginx
        volumeMounts:
        - name: gluster
          mountPath: /gluster

Cette option ne nous convenait pas, car nous avons container-linux sur tous les nœuds Kubernetes. Le gestionnaire de paquets n'est pas là, il n'a donc pas été possible d'installer gluster-client pour le montage. À cet égard, la troisième option a été trouvée, qu'il a été décidé d'utiliser.

GlusterFS + NFS + keepalived


Jusqu'à récemment, GlusterFS offrait son propre serveur NFS, mais maintenant le service externe nfs-ganesha est utilisé pour NFS. Beaucoup a été écrit à ce sujet, à ce sujet, nous allons voir comment le configurer.

Le référentiel doit être enregistré manuellement. Pour ce faire, dans le fichier /etc/yum.repos.d/nfs-ganesha.repo nous ajoutons:

[nfs-ganesha]
name=nfs-ganesha
baseurl=https://download.nfs-ganesha.org/2.8/2.8.0/RHEL/el-8/$basearch/
enabled=1
gpgcheck=1
[nfs-ganesha-noarch]
name=nfs-ganesha-noarch
baseurl=https://download.nfs-ganesha.org/2.8/2.8.0/RHEL/el-8/noarch/
enabled=1
gpgcheck=1

Et installez:

yum -y install nfs-ganesha-gluster --nogpgcheck

Après l'installation, nous effectuons la configuration de base dans le fichier /etc/ganesha/ganesha.conf.

# create new
NFS_CORE_PARAM {
    # possible to mount with NFSv3 to NFSv4 Pseudo path
    mount_path_pseudo = true;
    # NFS protocol
    Protocols = 3,4;
}
EXPORT_DEFAULTS {
    # default access mode
    Access_Type = RW;
}
EXPORT {
    # uniq ID
    Export_Id = 101;
    # mount path of Gluster Volume
    Path = "/gluster/main";
    FSAL {
        # any name
        name = GLUSTER;
        # hostname or IP address of this Node
        hostname="gluster-01.example.com";
        # Gluster volume name
        volume="main";
    }
    # config for root Squash
    Squash="No_root_squash";
    # NFSv4 Pseudo path
    Pseudo="/main";
    # allowed security options
    SecType = "sys";
}
LOG {
    # default log level
    Default_Log_Level = WARN;
}

Nous devons démarrer le service, activer nfs pour notre volume et vérifier qu'il est activé.

$ systemctl start nfs-ganesha
$ systemctl enable nfs-ganesha
$ gluster volume set main nfs.disable off
$ gluster volume status main

Par conséquent, l'état doit indiquer que le serveur nfs a démarré pour notre volume. Vous devez faire monter et vérifier.

mkdir /gluster-nfs
mount.nfs gluster-01.example.com:/main /gluster-nfs

Mais cette option n'est pas tolérante aux pannes, vous devez donc créer une adresse VIP qui se déplacera entre nos deux nœuds et aidera à commuter le trafic si l'un des nœuds tombe.

L'installation de keepalived dans CentOs se fait immédiatement via le gestionnaire de paquets.

$ yum install -y keepalived

Nous configurons le service dans le fichier /etc/keepalived/keepalived.conf:

global_defs {
    notification_email {
        admin@example.com
    }
    notification_email_from alarm@example.com
    smtp_server mail.example.com
    smtp_connect_timeout 30

    vrrp_garp_interval 10
    vrrp_garp_master_refresh 30
}

#C   ,   .    , VIP .
vrrp_script chk_gluster {
    script "pgrep glusterd"
    interval 2
}

vrrp_instance gluster {
    interface ens192
    state MASTER #     BACKUP
    priority 200 #      ,  100
    virtual_router_id 1
    virtual_ipaddress {
        10.10.6.70/24
    }

    unicast_peer {
        10.10.6.72 #        
    }

    track_script {
        chk_gluster
    }
}

Nous pouvons maintenant démarrer le service et vérifier que le VIP sur le nœud apparaît:

$ systemctl start keepalived
$ systemctl enable keepalived
$ ip addr
1: ens192: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
    link/ether 00:50:56:97:55:eb brd ff:ff:ff:ff:ff:ff
    inet 10.10.6.72/24 brd 10.10.6.255 scope global noprefixroute ens192
       valid_lft forever preferred_lft forever
    inet 10.10.6.70/24 scope global secondary ens192
       valid_lft forever preferred_lft forever

Si tout a fonctionné pour nous, il reste à ajouter PersistentVolume à Kubernetes et à créer un service de test pour vérifier le fonctionnement.

---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: gluster-nfs
spec:
  capacity:
    storage: 10Gi
  accessModes:
    - ReadWriteMany
  persistentVolumeReclaimPolicy: Retain
  nfs:
    server: 10.10.6.70
    path: /main

---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
 name: gluster-nfs
spec:
 accessModes:
 - ReadWriteMany
 resources:
   requests:
     storage: 10Gi
 volumeName: "gluster-nfs"

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: gluster-test
  labels:
    app: gluster-test
spec:
  replicas: 1
  selector:
    matchLabels:
      app: gluster-test
  template:
    metadata:
      labels:
        app: gluster-test
    spec:
      volumes:
      - name: gluster
        persistentVolumeClaim:
          claimName: gluster-nfs
      containers:
      - name: gluster-test
        image: nginx
        volumeMounts:
        - name: gluster
          mountPath: /gluster

Avec cette configuration, en cas de chute du noeud principal, il restera inactif pendant environ une minute jusqu'à ce que le montage tombe en timeout et passe. Simple pendant une minute pour ce stockage, disons que ce n'est pas une situation régulière et nous le rencontrerons rarement, mais dans ce cas, le système basculera automatiquement et continuera de fonctionner, et nous serons en mesure de résoudre le problème et d'effectuer la récupération sans se soucier du simple.

Sommaire


Dans cet article, nous avons examiné 3 options possibles pour connecter GlusterFS à Kubernetes, dans notre version, il est possible d'ajouter un provisionneur à Kubernetes, mais nous n'en avons pas encore besoin. Il reste à ajouter les résultats des tests de performances entre NFS et Gluster sur les mêmes nœuds.

Fichiers sur 1 Mo:

sync; dd if=/dev/zero of=tempfile bs=1M count=1024; sync
Gluster: 1073741824 bytes (1.1 GB, 1.0 GiB) copied, 2.63496 s, 407 MB/s
NFS: 1073741824 bytes (1.1 GB, 1.0 GiB) copied, 5.4527 s, 197 MB/s

Fichiers sur 1 Ko:

sync; dd if=/dev/zero of=tempfile bs=1K count=1048576; sync
Gluster: 1073741824 bytes (1.1 GB, 1.0 GiB) copied, 70.0508 s, 15.3 MB/s
NFS: 1073741824 bytes (1.1 GB, 1.0 GiB) copied, 6.95208 s, 154 MB/s

NFS fonctionne de la même manière pour n'importe quelle taille de fichier, la différence de vitesse n'est pas particulièrement perceptible, contrairement à GlusterFS, qui est très dégradé avec de petits fichiers. Mais en même temps, avec des fichiers de grande taille, NFS affiche des performances 2 à 3 fois inférieures à Gluster.

All Articles