Kubernetes : monter un volume iscsi dans un pod

Dans cet article, nous allons voir comment monter un volume persistant stocké sur un san iscsi dans un pod sous Kubernetes.

Actuellement, Kubernetes ne propose que 2 modes de montages pour les volumes iscsi : ReadWriteOnce (le volume peut être monté en lecture-écriture par un seul noeud) ou ReadOnlyMany (le volume peut être monté en lecture seule par plusieurs noeuds).

Prérequis

Nous allons nous baser sur l’architecture installée dans cet article. Sur les noeuds Worker-1, Worker-2 et Master-1 nous allons ajouter une interface réseau qui sera connectée via un switch ethernet au san iscsi. Cette interface permettra aux pods qui seront déployés sur Worker-1 et Worker-2 de monter le volume iscsi. Sur Master-1, cette interface permettra uniquement d’initialiser le volume et d’y placer des données.

La plage réseau reservée pour le réseau dédié au traffic iscsi sera 192.168.0.0/24. Les interfaces réseaux du san iscsi sont configurées sur les adresses 192.168.0.21, ,192.168.0.22, 192.168.0.23, 192.168.0.24 et le portail sur l’adresse 192.168.0.20. Le san utilisé prend en charge le multipathing.

Nous assignerons les adresses 192.168.0.10, 192.168.0.11, 192.168.0.12 respectivement à Master-1,Worker-1, Worker-2.
Par exemple, pour Worker-1, créons le fichier /etc/sysconfig/network-scripts/ifcfg-iSCSI :

TYPE=Ethernet
PROXY_METHOD=none
BROWSER_ONLY=no
BOOTPROTO=none
IPADDR=192.168.0.11
PREFIX=24
DEFROUTE=yes
IPV4_FAILURE_FATAL=no
IPV6_DISABLED=yes
NAME=iSCSI
UUID=7c0ad515-f084-3fa1-9764-bf7974e23ee8
DEVICE=ens224
ONBOOT=yes
MTU="9000"

Un volume iscsi est créé sur le san. L’accès à ce volume utilise CHAP pour l’authentification de l’initiateur par la cible ainsi que pour l’authentification de l’initiateur par la cible lors de la session discovery.

Configuration

Les étapes suivantes sont à faire sur  Worker-1, Worker-2 et Master-1.

Tout d’abord nous installons les logiciels requis :

dnf -y install iscsi-initiator-utils device-mapper-multipath

Nous allons modifier le nom de l’initiateur dans /etc/iscsi/initiatorname.iscsi en fonction de l’hôte sur lequel nous nous trouvons :

 InitiatorName=iqn.1994-05.com.redhat:k8s-worker1

Puis nous créons le fichier /etc/multipath.conf :

defaults {

       polling_interval        10
       path_grouping_policy    multibus
       path_checker            tur
       rr_min_io               10
       max_fds                 8192
       rr_weight               priorities
       failback                immediate
       no_path_retry           fail
       user_friendly_names     yes
}

Nota : le fichier multipath.conf peut varier en fonction du SAN utilisé. A adapter en fonction des préconisations du constructeur

Préparation du volume

Sur Master-1, nous allons modifier le fichier /etc/iscsi/iscsid.conf :

# *************
# CHAP Settings
# *************

node.session.auth.authmethod = CHAP
node.session.auth.username = nom_utilisateur
node.session.auth.password = mot_de_passe
discovery.sendtargets.auth.authmethod = CHAP
discovery.sendtargets.auth.username = nom_utilisateur
discovery.sendtargets.auth.password = mot_de_passe

Bien évidemment, nom_utilisateur et mot_de_passe sont à adapter en fonction de ce qui a été défini sur le SAN par rapport à l’accès au volume.

Sur Master-1, Worker-1 et Worker-2, nous pouvons à présent démarrer les services :

systemctl enable --now iscsid
systemctl enable --now multipathd 

Sur Master-1, nous pouvons à présent nous connecter au SAN :

iscsiadm -m discovery -t sendtargets -p 192.168.0.20
iscsiadm -m node --login

Nous pouvons ensuite vérifier que le lun iscsi est bien détecté :

Nous allons maintenant le formater :

mkfs.ext4 /dev/mapper/mpatha

Puis le monter :

mount /dev/mapper/mpatha /mnt

Nous créons ensuite le fichier /mnt/index.html :

<html>
<body>
<h1> This index.html is on an iscsi lun</h1>
</body>
</html>

Puis nous pouvons démonter le volume :

umount /mnt

Création du volume persistant

Sur Master-1, nous allons créer un fichier chap-secret.yaml comportant les identifiants CHAP :

---
apiVersion: v1
kind: Secret
metadata:
  name: chap-secret
type: "kubernetes.io/iscsi-chap"
stringData:
  discovery.sendtargets.auth.username: nom_utilisateur
  discovery.sendtargets.auth.password: mot_de_passe
  node.session.auth.username: nom_utilisateur
  node.session.auth.password: mot_de_passe

Puis nous exécutons la commande :

kubectl create -f chap-secret.yaml

Nous allons ensuite créer un fichier pv-iscsi.yaml définissant le Persistant Volume ainsi qu’un Persistant Volume Claim :

---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv001
spec:
  capacity:
    storage: 10Gi
  accessModes:
    - ReadOnlyMany
  iscsi:
     targetPortal: 192.168.0.20
     portals:  ['192.168.0.21:3260', '192.168.0.22:3260','192.168.0.23:3260','192.168.0.24:3260' ]
     iqn:  iqn.2001-05.com.mysan:0-af1ff6-9689a88eb-1c29e1debb962875-k8s-volume1
     lun: 0
     fsType: 'ext4'
     readOnly: true
     chapAuthDiscovery: true
     chapAuthSession: true
     secretRef:
       name: chap-secret
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
   name: pv001-pvc
spec:
   accessModes:
      - ReadOnlyMany
   resources:
      requests:
        storage: 1Gi

Bien évidemment, l’iqn est à modifier en fonction de l’iqn du volume exporté par le SAN.

Puis nous exécutons la commande :

kubectl create -f pv-iscsi.yaml

Test avec un pod NGINX

Nous allons tester le bon fonctionnement en déployant un pod nginx. Nous monterons le volume sous /usr/share/html afin de pouvoir afficher notre fichier html.

Créons le fichier nginx-test.yaml :

---
apiVersion: v1
kind: Service
metadata:
  name: test-nginx
  labels:
    run: test-nginx
spec:
  type: NodePort
  ports:
  - port: 8080
    nodePort: 30080
    targetPort: 80
    protocol: TCP
    name: http
  - port: 443
    protocol: TCP
    name: https
  selector:
    run: test-nginx
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: test-nginx
spec:
  selector:
    matchLabels:
      run: test-nginx
  replicas: 1
  template:
    metadata:
      labels:
        run: test-nginx
    spec:
      containers:
      - name: nginx
        image: nginx
        ports:
          - containerPort: 80
        volumeMounts:
          - name: www
            mountPath: "/usr/share/nginx/html"
      volumes:
        - name: www
          persistentVolumeClaim:
            claimName: pv001-pvc

Puis lançons la création avec :

kubectl create -f nginx-test.yaml

Nous pouvons ensuite vérifier le bon fonctionnement de l’ensemble :

Et lorsque nous ouvrons un navigateur à l’adresse http://xxx.xxx.xxx.xxx:30080 nous pouvons y voir notre fichier index.html (xxx.xxx.xxx.xxx étant l’adresse ip d’un noeud du cluster kubernetes).

One thought on “Kubernetes : monter un volume iscsi dans un pod”

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.