<<< Chap 9 | Sommaire | Chap 11>>>
Chap. 10 Les différentes méthodes de Stockage de Données
I. Différences entre Conteneurs et Machines Virtuelles
Du point de vue d’un système hôte linux, voici ce que représente un conteneur.
- Forme de virtualisation qui, contrairement à une virtualisation matérielle (virtualisation), se fait au niveau de l’OS/Application (conteneurisation)
- Un conteneur n’est pas une machine virtuelle, mais juste un autre processus du système hôte
- Un conteneur est une « implémentation avancée du mécanisme de « chroot »[1]
De ce fait, il n’y a pas de système d’exploitation installé dans un conteneur.
- Seuls les programmes nécessaires pour faire tourner ses applications y sont présentes. Et ces applications sont dépendantes des resources de l’hôte (OS denpendencies).
- Chaque conteneur possède son propre répertoire racine et ses propres processus, isolés du reste du système (jail) – cf. exercice vers la fin de ce chapitre
Il est possible d’installer un conteneur directement sur une machine physique, à condition que la machine hôte tourne avec un noyau linux, et quelque soit la distribution. Vous pouvez par exemple, monter un cluster kubernetes avec des Raspberry-Pi.
Cependant, l’utilisation de machines virtuelles peut être indispensable si:
- La machine hôte ne tourne pas sous linux
Puisque les programmes requis par les conteneurs risquent de ne pas être compatibles avec ceux de l’hôte. - Le système hôte utilise une version incompatible du noyau linux
Certaines versions particulières de bibilothèques et binaires, nécessaire au bon fonctionnement du conteneur peuvent ne pas être présentes dans le noyau de l’hôte. Par exemple, avec une vieille distribution, vous ne pouvez pas faire tourner un conteneur installé avec des programmes plus récents.
II. Espace disque
Les méthodes pour présenter un espace disque aux conteneurs sont,
- Bind-mounts
Utilisé pour partager des fichiers entre le machine hôte et ses conteneurs via la méthode de « mount« . L’option de « bind » (lier) associé au « mount », permet de protéger les fichiers sources contre toutes modifications à partir de ces conteneurs. - tmpfs mounts
Fichiers temporaires du conteneur, directement monté à partir de la mémoire physique du l’hôte. - Volumes
Répertoires dédiés à chacun des conteneurs, et qui seront créés automatiquement s’ils n’existent pas. Ces répertoires peuvent se trouver sur les machines hôtes respectifs au conteneurs, ou sur un serveur de stockage.
Parmis toutes ces méthodes, l’utilisation des Volumes
comme système de stockage de données, est celle préconisée par les équipes de docker et kubernetes. Cette méthode a pour avantage d’être supportée par des systèmes d’exploitation autres que linux.
Bind-mount
et tmpfs
sont généralement utilisés pour des tâches spécifiques dans le conteneur.
Le premier est généralement utilisé pour la population du contenu des fichiers hosts de chaque conteneur, tandis que le second peut servir à stocker temporairements des données sensibles, qui seront détruites au redémarrage du conteneur. Les programmes df -h
et findmnt
peuvent vous fournir un liste de fichiers montés par ces conteneurs.
Pour information, kubelet s’occupe de gérer la création des fichiers /etc/{resolv.conf,hostname,hosts}
sur chacun des conteneurs, pour éviter les problèmes de type écriture directe sur la machine hôte[1], dans les fichiers correspondants.
III. Stockage de données
3.1 Système de fichier
Depuis le début de cette série d’articles, je vous ai présenté des conteneurs utilisant un système de fichiers pour présenter les espaces de disque aux conteneurs (voir chap 4 concernant l’exemple ci-dessous).
apiVersion: v1
kind: Pod
metadata:
name: pingtest01
spec:
containers:
- name: pod1
image: docker.io/centos/tools:latest
command:
- /sbin/init
Le problème avec ce type de stockage est que, les modifications y apportées (ajout ou suppression de données) seraient perdues au redémarrage du conteneur. Et c’est là qu’entre en jeu le système de Volume pour y remédier.
3.2 Volumes
Dans le Chap 8, je vous ai présenté des Pods multi-conteneurs utilisant un Volume de type emptyDir, qui peut être partagé entre plusieurs conteneurs du même pod.
apiVersion: v1
kind: Pod
metadata:
name: pod-with-sidecar
labels:
app: pod-with-sidecar
spec:
containers:
# Log service
- name: sidecar-container
image: alpine:latest
command: ["/bin/sh"]
args: ["-c", "while true; do date >> /var/log/index.html; sleep 5;done"]
volumeMounts:
- name: shared-logs
mountPath: /var/log
# Web server
- name: app-container
image: nginx:latest
ports:
- containerPort: 80
volumeMounts:
- name: shared-logs
mountPath: /usr/share/nginx/html
# Shared volume
volumes:
- name: shared-logs
emptyDir: {}
L’utilisation d’un système stockage partagé de type « Volumes » est précisé dans le fichier yaml avec justement l’ajout du mot clé volumes
. Pour y accéder, chaque conteneur doit préciser le chemin d’accès avec volumeMounts
.
Pour que le même volume soit accessible à tous les conteneurs, ces derniers doivent utiliser comme nom du volume à monter, celui du volume partagé. Ensuite, ajouter le chemin où monter ce volume avec l’option mountPath
dans le conteneur.
3.3 Les différents types de volumes
Voici une liste non exhaustive des différents types de volumes supportés par kubernetes. Connectez-vous sur la page officielle, pour avoir la liste complète à jour.
- Local storage
Un volumelocal
représente un périphérique de stockage local monté tel un disque, une partition ou un dossier. - hostPath
Un volumehostPath
monte un fichier ou un dossier à l’intérieur d’un Pod, depuis le système de fichiers de l’hôte. - nfs
Un volumenfs
permet un partage NFS (Network File System) pour être monté dans un Pod. - persistentVolumeClaim
Un volumepersistentVolumeClaim
est utilisé pour monter un PersistentVolume dans un Pod. - emptyDir
Un volumeemptyDir
est le type de volume créé lorsqu’un Pod est assigné pour la première fois à un Node (nœud), et existe aussi longtemps que le Pod s’exécute sur ce nœud. Comme le nom l’indique, le volume est initialement vide. - configMap
La ressourceconfigMap
fournit un moyen d’injecter des données de configuration dans les Pods. - secrets
Un volumesecret
est utilisé pour fournir des informations sensibles, comme des mots de passe, aux Pods. - Cloud storage
AWS, , etc. - etc.
Une petite note concernant les fichiers et dossiers, sous linux/unix tout est fichiers.
3.4 Exercices
Sur la page de kubernetes, il vous est proposé un exercice pour vérifier la consistance de données ajoutées ou modifiées dans un volume type emptyDir.
Noter que le programme ps
n’est disponible qu’après avoir installé procps
dans ces conteneurs de cet exercice.
$ kubectl exec -it <nom-du-conteneur> -- apt update $ kubectl exec -it <nom-du-conteneur> -- apt install procps
Ci-dessous le fichier yaml utilisé,
$ cat << EOF >> volumes.yaml
kind: Pod
metadata:
name: redis
spec:
containers:
- name: redis
image: redis
volumeMounts:
- name: redis-storage
mountPath: /data/redis
volumes:
- name: redis-storage
emptyDir: {}
EOF
Au redémarrage du conteneur ( la valeur de RESTARTS pour le pod concerné doit avoir été incrémentée), vérifier que le fichier /data/redis/test-file existe toujours.
Afin de pouvoir faire une comparaison avec un conteneur utilisant un système de fichier, je vous propose de refaire le même exercice, après avoir supprimé la partie « volumes » du fichier yaml. Vous pouvez aussi utiliser le fichier yaml ci-dessous.
$ cat << EOF >> file-system.yaml
apiVersion: v1
kind: Pod
metadata:
name: redisfs
spec:
containers:
- name: redisfs
image: redis
EOF
Pour pouvoir effectuer exactement les mêmes étapes que dans l’exercice précédant, créer un dossier /data/redis dans le conteneur redisfs.
Après avoir tué le processus Redis pour redémarrer le conteneur, le dossier ainsi que son contenu ne devrait plus exister.
3.5 Conclusion
Avec un système de fichiers, les modifications apportées au niveau des fichiers et données ne sont pas persistantes, et seront détruites au redémarrage du conteneur.
L’utilisation des Volumes permet d’éviter ce désagrément.
Ce qu’il faut savoir en ce qui concerne les volumes,
- Les modifications apportées au sein de chaque conteneur persistent jusqu’au redémarrage ou à la destruction du Pod dans lequel ces conteneurs sont associés
- Les Volumes peuvent être mis en commun entre plusieurs conteneurs du même pod
Ces deux limitations peuvent être outrepassées en passant par un serveur de stockage (local ou dans le Cloud) pour présenter les volumes, afin de garantir une sauvegarde de données indépendemment de l’état du Pod, de façon plus permanente.
Après il faut voir comment vous gérez votre cluster de stockage de donnée.
Sources
Manage data in Docker
Kubernetes: Documentation / Concepts / Stockage
docker container does not need an OS, but each container has one. Why?
What is the meaning of mounting /dev/sda1 to /etc/hosts in Docker container
Quelle est la différence entre un conteneur et une machine virtuelle?
Kubernetes Mount Propagation
Kubernetes – Volumes
Configurer un pod en utilisant un volume pour le stockage