Kubernetes - Installation de Matrix - RaspberryPI (arm64)

Contexte

Pour exécuter Matrix, il nous faut :

  • Une base de données Postgresql
  • Un volume gluster pour stocker les fichiers relatifs au “rooms” (images, etc…), nom du volume pour l’exemple : “nsmatrix-data”
  • Deux services réseaux :
    • Accès à Matrix
    • Accès aux metriques utilisées par prometheus
graph TD A[Matrix] -->|access| B(Postgresql) A[Matrix] -->|access| C(Glusterfs)

Pour appliquer une méthode “devops”, utiliser un repository git, qui contiendra le manifest et éventuellement le pipeline de mise à jour par CI/CD avec par exemple “drone”.

Préparation

  • Créer un volume sur le serveur glusterfs “nsmatrix-data”

  • Créer un nom de domaine permettant l’accès au service Matrix :

    • accès à matrix : ‘https://monurlmatrix’ Pour être accessible de l’internet, l’url d’accès à Matrix devra disposer d’un certificats SSL valide (Letsencrypt par exemple), et notamment pour autoriser la fédération.
  • Créer une base de données postgresql et un utilisateur pour l’accès à cette base :

    • Nom de la base : matrix
    • utilisateur postgres : matrix
    • mot de passe postgres : mypassword

Connecté au serveur postgresql :

su - postgres
psql
CREATE USER matrix with password 'mypassword';
CREATE DATABASE matrix WITH TEMPLATE = template0 ENCODING = 'UTF8' LC_COLLATE = 'C' LC_CTYPE = 'C';
GRANT ALL PRIVILEGES ON DATABASE matrix to matrix;
\q
exit

Modifiez le fichier pg_hba.conf pour que la nouvelle base de données “matrix” soit accessible de tous les workers du cluster Kubernetes.

Exemple, mon cluster kubernetes comporte deux “Workers”, dont les adresses IP respectives sont :

  • 192.168.1.20
  • 192.168.1.21

Ajoutez au fichier pg_hba.conf :

host matrix    matrix   192.168.1.20/32  md5
host matrix    matrix   192.168.1.21/32  md5

puis exécuter : systemctl reload postgresql

Les informations de comptes (utilisateur/mot de passe, addresseIP/port du serveur postgresql) seront nécessaires pour effectuer le paramétrage de “Matrix”.

Manifest

Créer le fichier “manifest.yml”, qui va permettre :

  • la création du namespace “nsmatrix”
  • la déclaration du volume Glusterfs
  • la création du “Deployment” avec l’image Matrix-version 1.55.0
  • la création du service réseau (cette partie est à adapter à votre infrastructure)

et adaptez le contenu à votre infrastructure :

apiVersion: "v1"
kind: "Namespace"
metadata:
  name: "nsmatrix"
  labels:
    name: "nsmatrix"
---
apiVersion: "v1"
kind: "Service"
metadata:
  name: "glusterfs-cluster"
  namespace: "nsmatrix"
spec:
  ports:
    - port: 1
---
apiVersion: "v1"
kind: "Endpoints"
metadata:
  name: "glusterfs-cluster"
  namespace: "nsmatrix"
subsets:
  - addresses:
      - ip: "[Addresse IP du service Glusterfs]"
    ports:
      - port: 1
---
apiVersion: "v1"
kind: "PersistentVolume"
metadata:
  name: "glusterfs-pv-nsmatrix-data"
spec:
  ## Le PV est accessible uniquement du namespace nsmatrix
  claimRef:
    name: "claimref-glusterfs-pv-nsmatrix-data"
    namespace: "nsmatrix"
  capacity:
    ## ici j'autorise l'utilisation de 20G de stockage
    storage: "20Gi"
  accessModes:
    - "ReadWriteOnce"
  storageClassName: ""
  persistentVolumeReclaimPolicy: "Recycle"
  glusterfs:
    endpoints: "glusterfs-cluster"
    path: "nsmatrix-data"
    readOnly: false
---
apiVersion: "v1"
kind: "PersistentVolumeClaim"
metadata:
  ## Référence à PV.claimRef.name
  name: "claimref-glusterfs-pv-nsmatrix-data"
  namespace: "nsmatrix"
spec:
  ## Nom du volume utilisé uniquement pour ce namespace
  volumeName: "glusterfs-pv-nsmatrix-data"
  accessModes:
    - "ReadWriteOnce"
  resources:
    requests:
      ## ici j'autorise l'utilisation de 20G de stockage
      storage: "20Gi"
---
apiVersion: "apps/v1"
kind: "Deployment"
metadata:
  name: "matrixdotorg"
  namespace: "nsmatrix"
spec:
  revisionHistoryLimit: 1
  strategy:
    type: "Recreate"
  selector:
    matchLabels:
      app: "matrixdotorg"
  replicas: 1
  template:
    metadata:
      labels:
        app: "matrixdotorg"
    spec:
      containers:
        - name: "matrixdotorg"
          env:
            - name: TZ
              value: "Europe/Paris"
            - name: UID
              value: "115"
            - name: GID
              value: "1001"
          image: "matrixdotorg/synapse:v1.55.0"
          # imagePullPolicy : Always IfNotPresent None
          imagePullPolicy: "IfNotPresent"
          ports:
            - containerPort: 8008
              protocol: "TCP"
              name: "nsmatrix-app-port-0-8008"
          volumeMounts:
            - mountPath: "/data"
              name: "glusterfsvol-data"
      volumes:
        - name: "glusterfsvol-data"
          persistentVolumeClaim:
            ## appel reférent à claimRef du pv
            claimName: "claimref-glusterfs-pv-nsmatrix-data"
---
##
## Le service dans mon infrastructure est de type NodePort exposé au travers de haproxy (hors cadre pour cette documentation).
## Cette partie est à adapter à votre infrasctructure
##
apiVersion: "v1"
kind: Service
metadata:
  name: "nsmatrix-app-port-0-8008"
  namespace: "nsmatrix"
  annotations:
    balance: "roundrobin"
    url: "https://monurlmatrix"
spec:
  type: "NodePort"
  ports:
    - port: 8008
      protocol: "TCP"
      targetPort: 8008
  selector:
    app: "matrixdotorg"

Pour ajouter l’application, connecté au master : kubectl apply -f manifest.yml

Le déploiement fonctionne, opérer un “commit” de ce fichier dans votre repository git.

ATTENTION Matrix n’est pas en état de fonctionnement, il manque le fichier de configuration “homeserver.yaml”. Pour consulter les logs : kubectl logs -n nsmatrix [nom du pod]

Paramétrage de l’application

Le volume de stockage est un volume gluster, votre master kubernetes dispose du package glusterfs-client, montons le volume matrix (data) sur le master : le nom du volume gluster est : “nsmatrix-data” (ce qui est indiqué dans le manifest ci-avant)

La variable (obligatoire) SYNAPSE_REPORT_STATS permet ou non d’envoyer des rapports anonymes auprès de Matrix.org, selon votre choix indiquez “yes” pour “oui” ou “no” pour “non”.

mkdir /tmp/volmatrix
mount -t glusterfs [adresse IP du serveur gluster]:nsmatrix-data /tmp/volmatrix
docker run -it --rm \
 --mount type=volume,src=/tmp/volmatrix,dst=/data \
 -e SYNAPSE_SERVER_NAME=my.matrix.host \
 -e SYNAPSE_REPORT_STATS=no \
 matrixdotorg/synapse:latest generate

Editez maintenant le nouveau fichier : vim /tmp/volmatrix/homeserver.yaml et rendez-vous sur la partie “database”

#database:
# name: psycopg2
# txn_limit: 10000
# args:
# user: synapse_user
# password: secretpassword
# database: synapse
# host: localhost
# port: 5432
# cp_min: 5
# cp_max: 10

décommentez cette partie et adapter à votre infrasctructure :

database:
name: psycopg2
txn_limit: 10000
args:
user: [nom utilisateur postgres]
password: [Mot de passe utilisateur postgres]
database: [Nom de la base de donnée]
host: [Adresse IP du serveur de base de données postgres]
port: [Adresse IP du serveur de base de données postgres - communément 5432]
cp_min: 5
cp_max: 10

Enregistrer les modifications et procéder au nettoyage local

# Nettoyage local
umount /tmp/volmatrix
rmdir /tmp/volmatrix

Redémarrer l’application matrix : kubeclt delete pod -n nsmatrix [nom du pod]

Matrix est en état de fonctionnement, utilisez votre navigateur et indiquer votre domaine matrix, Matrix présente une page d’accueil.

Mise à jour de la version

Pour mettre à jour votre version, utilisez ce même manifest en modifiant la valeur de la version matrix au niveau de l’attribut : “image”, dans cette présentation: image: "matrixdotorg/synapse:v1.55.0" à remplacer par image: "matrixdotorg/synapse:v1.56.0"

puis exécuter la commande : kubectl apply -f manifest.yml.

PS : Cette opération de mise à jour devrait être réalisée par la chaîne CI/CD du Datacenter (j’utilise “drone”).

Sauvegarde de l’application

La sauvegarde de l’application doit permettre la restauration de :

  • la base de données
  • du volume Glusterfs

Utiliser pg_dump pour la partie postgresql, et rsync ou borgbackup pour le volume Gluster et sauvegarder le tout sur un disque externe ou dans une “storage box” disponible dans les datacenters du marché.

Conclusion

Ceci est une approche permettant d’expliquer le déploiement d’une application dans Kubernetes, pas facile d’un premier abord. Avec le temps et l’expérience, vous allez trouver des astuces, créer des outils, par exemple, créer un manifest Kubernetes complet à partir d’un fichier de description “yaml”, réutilisable dans le processus de mise à jour applicatif pour la chaîne CI/CD…