GlusterFS als externer Speicher für Kubernetes

Bild
Das Finden des optimalen Speichers ist ein ziemlich komplizierter Prozess, alles hat seine Vor- und Nachteile. Der Marktführer in dieser Kategorie ist natürlich CEPH, aber es ist ein ziemlich komplexes System, wenn auch mit sehr umfangreichen Funktionen. Für uns ist ein solches System redundant, da wir einen einfachen replizierten Speicher im Master-Master-Modus für einige Terabyte benötigten. Nachdem wir viel Material studiert hatten, wurde beschlossen, das modischste Produkt auf dem Markt für die Schaltung zu testen, an der wir interessiert sind. Aufgrund der Tatsache, dass keine vorgefertigte Lösung für einen solchen Plan gefunden wurde, möchte ich meine Best Practices zu diesem Thema teilen und die Probleme beschreiben, die im Bereitstellungsprozess aufgetreten sind.

Tore


Was haben wir vom neuen Repository erwartet:

  • Möglichkeit, mit einer geraden Anzahl von Knoten für die Replikation zu arbeiten.
  • Einfache Installation, Einrichtung, Support
  • Das System muss erwachsen, erprobt und Benutzer sein
  • Möglichkeit, den Speicherplatz ohne Ausfallzeiten zu erweitern
  • Der Speicher muss mit Kubernetes kompatibel sein
  • Es sollte ein automatisches Failover geben, wenn einer der Knoten abstürzt

Beim letzten Punkt haben wir viele Fragen.

Einsatz


Für die Bereitstellung wurden zwei virtuelle Maschinen auf CentOs 8 erstellt. Jede von ihnen ist über eine zusätzliche Festplatte mit Speicher verbunden.

Vorbereitende Vorbereitung


Für GlusterFS müssen Sie XFS einen separaten Datenträger zuweisen, damit das System in keiner Weise beeinträchtigt wird.

Wählen Sie die Partition aus:

$ 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.

In XFS formatieren und bereitstellen:

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

Um das Ganze abzurunden, legen Sie den Eintrag in / etc / fstab ab, um das Verzeichnis beim Systemstart automatisch bereitzustellen:

/dev/sdb1       /gluster        xfs     defaults        0       0

Installation


In Bezug auf die Installation wurden viele Artikel geschrieben. In diesem Zusammenhang werden wir nicht tief in den Prozess einsteigen, sondern nur überlegen, worauf es sich zu achten lohnt.

Installieren Sie auf beiden Knoten die neueste Version von glusterfs und führen Sie sie aus:

$ 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

Als nächstes müssen Sie dem Glaster mitteilen, wo sich sein Nachbarknoten befindet. Dies geschieht mit nur einem Knoten. Ein wichtiger Punkt: Wenn Sie ein Domänennetzwerk haben, müssen Sie den Servernamen mit der Domäne angeben, andernfalls müssen Sie in Zukunft alles wiederholen.

$ gluster peer probe gluster-02.example.com

Wenn es erfolgreich war, überprüfen wir die Verbindung mit dem Befehl von beiden Servern:

$ 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

Jetzt können Sie ein Volume erstellen, in das wir schreiben werden.

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

Wo:


Führen Sie Volume aus und überprüfen Sie die Leistung:

gluster volume start main
gluster volume status main

Für repliziertes Volume wird empfohlen, die folgenden Parameter festzulegen:

$ 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

Mit diesen einfachen Schritten haben wir einen GlusterFS-Cluster erstellt. Es bleibt eine Verbindung herzustellen und die Leistung zu überprüfen. Ubuntu ist auf dem Client-Computer installiert. Zum Mounten müssen Sie den Client installieren:

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

Wenn Gluster mit einem der Knoten verbunden ist, gibt er die Adressen aller Knoten an und stellt automatisch eine Verbindung zu allen her. Wenn der Client bereits eine Verbindung hergestellt hat, führt der Ausfall eines der Knoten nicht zum Anhalten. Wenn der erste Knoten nicht verfügbar ist, kann im Falle einer Sitzungsunterbrechung keine Verbindung hergestellt werden. Zu diesem Zweck können Sie beim Mounten den Parameter backupvolfile übergeben, der den zweiten Knoten angibt.
mount.glusterfs gluster-01.example.com:/main /gluster -o backupvolfile-server=gluster-02.example.com

Ein wichtiger Punkt: Gluster synchronisiert Dateien zwischen Knoten nur, wenn ihre Änderung über das bereitgestellte Volume erfolgte. Wenn Sie Änderungen direkt an den Knoten vornehmen, ist die Datei nicht synchron.

Stellen Sie eine Verbindung zu Kubernetes her


Zu diesem Zeitpunkt begannen die Fragen: „Wie kann man es verbinden?“. Und es gibt mehrere Möglichkeiten. Betrachten Sie sie.

Heketi


Am beliebtesten und empfohlenen ist die Verwendung eines externen Dienstes: heketi. heketi ist eine Schicht zwischen Kubernetes und Gluster, mit der Sie Speicher über http verwalten und bearbeiten können. Aber Heketi wird dieser einzige Punkt des Scheiterns sein, weil Dienst ist nicht geclustert. Die zweite Instanz dieses Dienstes kann nicht unabhängig arbeiten, weil Änderungen werden in der lokalen Datenbank gespeichert. Das Ausführen dieses Dienstes in Kubernetes ist ebenfalls nicht geeignet, da Er benötigt eine statische Festplatte, auf der seine Datenbank gespeichert wird. In dieser Hinsicht erwies sich diese Option als die unangemessenste.

Endpunkt bei Kubernetes


Wenn Sie Kubernetes auf Systemen mit Paketmanagern haben, ist dies eine sehr praktische Option. Der Punkt ist, dass für alle GlusteFS-Server in Kubernetes ein gemeinsamer Endpunkt erstellt wird. Auf diesem Endpunkt ist ein Dienst aufgehängt, und wir werden bereits auf diesen Dienst gemountet. Damit diese Option funktioniert, muss glusterfs-client auf jedem Kubernetes-Knoten installiert und sichergestellt werden, dass er bereitgestellt werden kann. Stellen Sie in Kubernetes die folgende Konfiguration bereit:

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

Jetzt können wir eine einfache Testbereitstellung erstellen und überprüfen, wie die Montage funktioniert. Unten finden Sie ein Beispiel für eine einfache Testbereitstellung:

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

Diese Option passte nicht zu uns, da wir auf allen Kubernetes-Knoten Container-Linux haben. Der Paketmanager ist nicht vorhanden, daher konnte der Gluster-Client für die Bereitstellung nicht installiert werden. In diesem Zusammenhang wurde die dritte Option gefunden, für die entschieden wurde, sie zu verwenden.

GlusterFS + NFS + Keepalived


Bis vor kurzem bot GlusterFS einen eigenen NFS-Server an, jetzt wird der externe Dienst nfs-ganesha für NFS verwendet. Es wurde einiges darüber geschrieben, in diesem Zusammenhang werden wir herausfinden, wie man es konfiguriert.

Das Repository muss manuell registriert werden. Dazu fügen wir in der Datei /etc/yum.repos.d/nfs-ganesha.repo Folgendes hinzu:

[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

Und installieren:

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

Nach der Installation führen wir die Grundkonfiguration in der Datei /etc/ganesha/ganesha.conf durch.

# 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;
}

Wir müssen den Dienst starten, nfs für unser Volume aktivieren und überprüfen, ob es aktiviert ist.

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

Infolgedessen sollte der Status anzeigen, dass der NFS-Server für unser Volume gestartet wurde. Sie müssen mounten und überprüfen.

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

Diese Option ist jedoch nicht fehlertolerant. Sie müssen daher eine VIP-Adresse festlegen, die zwischen unseren beiden Knoten übertragen wird und den Datenverkehr umschaltet, wenn einer der Knoten ausfällt.

Die Installation von keepalived in CentOs erfolgt sofort über den Paketmanager.

$ yum install -y keepalived

Wir konfigurieren den Dienst in der Datei /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
    }
}

Jetzt können wir den Dienst starten und überprüfen, ob der VIP auf dem Knoten angezeigt wird:

$ 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

Wenn bei uns alles funktioniert hat, müssen Sie Kubernetes weiterhin PersistentVolume hinzufügen und einen Testdienst erstellen, um den Betrieb zu überprüfen.

---
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

Bei dieser Konfiguration bleibt der Hauptknoten im Falle eines Ausfalls etwa eine Minute lang im Leerlauf, bis der Mount im Timeout abfällt und wechselt. Nehmen wir für eine Minute an, dass dies keine normale Situation ist und wir uns selten damit treffen werden. In diesem Fall schaltet das System jedoch automatisch um und arbeitet weiter. Wir können das Problem lösen und die Wiederherstellung durchführen, ohne uns um die einfache Situation kümmern zu müssen.

Zusammenfassung


In diesem Artikel haben wir drei mögliche Optionen für die Verbindung von GlusterFS mit Kubernetes untersucht. In unserer Version ist es möglich, Kubernetes einen Provisioner hinzuzufügen, den wir jedoch noch nicht benötigen. Die Ergebnisse von Leistungstests zwischen NFS und Gluster müssen noch auf denselben Knoten hinzugefügt werden.

Dateien auf 1 MB:

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

Dateien auf 1 KB:

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 funktioniert für jede Dateigröße gleich, der Geschwindigkeitsunterschied ist im Gegensatz zu GlusterFS, das bei kleinen Dateien stark beeinträchtigt ist, nicht besonders auffällig. Gleichzeitig zeigt NFS bei großen Dateien eine 2-3-mal niedrigere Leistung als Gluster.

All Articles